It all started with a simple yet profound frustration - the struggle to effectively study and retain information from dense academic materials. As a student myself, I knew the pain of reading through hundreds of pages only to realize I couldn't recall the key concepts during exams. The traditional methods of highlighting and re-reading were inefficient, and existing study tools felt either too simplistic or overly complex.
StudyWise AI was born from this need - a smart study companion that could transform any document into interactive, personalized practice tests. The vision was clear: create an application that feels like having a personal tutor who understands your study materials and creates targeted practice questions to reinforce learning.
- Frontend: React 18 + TypeScript + Vite
- Backend: Node.js + Express + TypeScript
- Styling: Tailwind CSS with shadcn/ui components
- State Management: Zustand with localStorage persistence
- Routing: Wouter for lightweight client-side routing
- Database: Supabase (PostgreSQL) with Row-Level Security
- Authentication: Supabase Auth with OAuth support
- Build Tool: Vite for fast development and optimized builds
- Deployment: Render (backend) + Netlify/Vercel (frontend)
studywise-ai/
├── client/ # React frontend application
│ ├── src/
│ │ ├── components/ # Reusable UI components
│ │ ├── pages/ # Page components
│ │ ├── stores/ # Zustand state management
│ │ ├── contexts/ # React contexts
│ │ ├── hooks/ # Custom React hooks
│ │ ├── lib/ # Utilities and configurations
│ │ ├── types/ # TypeScript type definitions
│ │ ├── utils/ # Helper functions
│ │ └── services/ # API service functions
│ ├── public/
│ └── index.html
├── server/ # Node.js/Express backend
│ ├── controllers/ # Route handlers
│ ├── services/ # Business logic (AI, database)
│ ├── lib/ # Database and utility functions
│ ├── routes.ts # API route definitions
│ ├── index.ts # Server entry point
│ ├── config.ts # Server configuration
│ └── storage.ts # Legacy storage (deprecated)
├── shared/ # Shared types and utilities
├── config/ # Configuration files
│ ├── vite.config.ts # Frontend build configuration
│ ├── tsconfig.json # TypeScript configuration
│ └── tailwind.config.ts # Styling configuration
├── scripts/ # Build and deployment scripts
├── docs/ # Documentation
├── supabase/ # Database migrations and config
└── src/ # Legacy source directory (deprecated)
The heart of StudyWise AI is its ability to process various document formats:
// Supported formats: PDF, TXT, Markdown, DOCX
const processDocument = async (file: File) => {
const text = await extractText(file);
return generateQuestions(text);
};Technical Challenge: PDF parsing proved particularly tricky due to PDF.js worker configuration issues. The initial implementation struggled with MIME type errors and fake worker fallbacks.
Solution: Implemented a hybrid strategy:
- Development: Uses local worker file for consistency
- Production: Leverages CDN for performance and caching
- Fallback: Comprehensive error handling with debug logging
The application creates realistic practice questions with:
- Multiple choice questions
- True/false questions
- Fill-in-the-blank questions
- Source text linking for context
interface Question {
id: string;
type: 'multiple_choice' | 'true_false' | 'fill_blank';
question: string;
options: string[];
correctAnswer: string;
sourceText: string;
}Built a robust state management system using Zustand:
// Core stores for different application states
const useTestStore = create<TestState>()(...);
const useLibraryStore = create<LibraryState>()(...);
const useTestSessionStore = create<TestSessionState>()(...);
const useResultsStore = create<ResultsState>()(...);Key Insight: Zustand's simplicity combined with localStorage persistence created a seamless user experience where tests and progress are preserved across sessions.
Leveraged Tailwind CSS and Radix UI to create:
- Mobile-first responsive design
- Accessible components with proper ARIA labels
- Smooth animations with Framer Motion
- Consistent design system with custom color palette
The marketing page showcases:
- Hero section with clear value proposition
- Feature explanations with visual examples
- Pricing structure (though currently free)
- FAQ section addressing common concerns
The main workspace features:
- File upload area with drag-and-drop support
- Real-time document processing status
- Quick access to recent tests and results
A full-screen, immersive test environment:
- Clean, distraction-free interface
- Real-time timer with auto-submission
- Visual progress indicators
- Smooth question navigation
<TestTaking
questions={questions}
onAnswer={handleAnswer}
timeLimit={timeLimit}
/>Comprehensive performance tracking:
- Score calculation with percentage breakdown
- Time spent analysis
- Question-by-question review
- Source text linking for learning reinforcement
The Problem: PDF parsing failed with cryptic MIME type errors and fake worker fallbacks, preventing document processing.
The Journey:
- Initially tried using the default PDF.js configuration
- Encountered version compatibility issues between core and worker
- Experimented with different CDN versions and local file serving
- Discovered the need for explicit worker configuration
The Solution:
// Hybrid worker configuration strategy
const workerConfig = {
workerSrc: import.meta.env.PROD
? `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js`
: `/pdf.worker.min.mjs`
};The Problem: Users expected their test progress and library to persist between browser sessions.
The Solution: Implemented Zustand persist middleware with localStorage:
create<TestSessionState>()(
persist(
(set, get) => ({
// state definitions
}),
{
name: 'test-session-storage',
}
)
);The Problem: Creating a reliable countdown timer that works across component re-renders and persists state.
The Solution: Used Zustand for timer state management with useEffect cleanup:
useEffect(() => {
const interval = setInterval(() => {
if (timeRemaining > 0) {
set({ timeRemaining: timeRemaining - 1 });
} else {
handleTestCompletion();
}
}, 1000);
return () => clearInterval(interval);
}, [timeRemaining]);The Problem: Creating a test interface that works seamlessly on mobile, tablet, and desktop.
The Solution: Tailwind CSS responsive utilities with mobile-first approach:
<div className="flex flex-col md:flex-row h-screen">
<div className="w-full md:w-3/4 p-4">
{/* Question content */}
</div>
<div className="w-full md:w-1/4 border-t md:border-t-0 md:border-l">
{/* Navigation sidebar */}
</div>
</div>Since this is a demonstration project, the AI question generation is implemented as a mock service that creates realistic-looking questions based on document content patterns:
const generateMockQuestions = (text: string): Question[] => {
// Analyze text structure and create relevant questions
// Uses patterns like definitions, lists, and key concepts
// Returns array of questions with plausible options
};This approach allows showcasing the full user experience without requiring actual AI API integration.
npm install
npm run devnpm run buildThe backend is deployed on Render with:
- Web service configuration using
render.yaml - Automatic builds from GitHub
- Environment variable management
- Health check endpoints
- Automatic scaling
The frontend can be deployed to:
- Netlify: Build command
npm run build:client, publishdist/public - Vercel: Automatic deployment with zero configuration
- Environment variables for API endpoints and Supabase configuration
- PDF.js is powerful but requires careful configuration - Worker files must be properly served and version-matched
- Zustand is excellent for medium-complexity state - Simpler than Redux but more powerful than Context API
- Tailwind CSS accelerates UI development - Especially when combined with component libraries like Radix UI
- TypeScript pays dividends in larger projects - Catch errors early and provide better developer experience
- Users value immediate feedback - The real-time test generation and results were well-received
- Persistence is crucial - Users expect their work to be saved between sessions
- Mobile responsiveness is non-negotiable - Many users study on mobile devices
- Clear visual feedback reduces anxiety - Progress indicators and timers help users feel in control
- Real AI integration with LLM APIs
- Spaced repetition scheduling
- Export test results as PDF
- Social features for sharing tests
- Mobile app versions (iOS/Android)
- Voice-based question answering
- Integration with learning management systems
- Advanced analytics and learning recommendations
// Group related components in feature folders
components/
test/
TestWizard.tsx # Multi-step configuration
TestTaking.tsx # Full-screen test interface
TestResults.tsx # Results display
// ... other test-related components// Use descriptive store names and clear state boundaries
const useTestStore = create<TestState>()(...); // Test configuration
const useTestSessionStore = create<TestSessionState>()(...); // Active test
const useLibraryStore = create<LibraryState>()(...); // Saved tests// Comprehensive type definitions for all data structures
interface TestConfig {
questionCount: number;
questionTypes: QuestionType[];
timeLimit?: number;
sourceText: string;
}// Graceful error handling throughout the application
try {
await processDocument(file);
} catch (error) {
console.error('Document processing failed:', error);
toast.error('Failed to process document. Please try again.');
}Building StudyWise AI was a journey of solving real problems that students face every day. From the initial frustration with traditional study methods to the technical challenges of document processing and state management, each step taught valuable lessons about both software development and user experience design.
The application successfully demonstrates how modern web technologies can create powerful, responsive educational tools that work across devices. While the current implementation uses mock AI, the architecture is designed to easily integrate with real AI services when available.
This project stands as a testament to the power of identifying a genuine user need and systematically building a solution that addresses it through thoughtful design and robust engineering practices.