Demo GIF and screenshots coming soon — open an issue if you'd like to contribute one.
- Overview
- Key Features
- Why AI Study Quiz Generator
- Tech Stack
- Project Layout
- Auth & Login Flow
- Application State — AppContext
- Pages
- Components
- NLP & AI Routing
- Getting Started
- Known Limitations
- Contributing
- Author
Students preparing for high-stakes exams waste 1–2 hours daily on a broken study loop — manually deciding which chapter to review, re-reading slides passively, and never actually testing recall until the night before the exam.
AI Study Quiz Generator eliminates that friction end-to-end. Upload your lecture PDFs once, configure your difficulty and quiz style, and Gemini synthesizes your entire syllabus into a structured 20-question session — mixing MCQ and MSQ formats, graded with per-option AI explanations — in under 10 seconds. Progress persists across sessions via Firebase so you can track improvement over weeks, not just guesses.
Built originally for the BITSOM AI PM Course, the app was adopted organically across the cohort:
| Metric | Result |
|---|---|
| Quizzes generated | 100+ |
| Course mates reached | 150+ |
| Adoption rate | ~50% (75 of 150 tried it) |
| Monthly active power users | 70 students (10+ quizzes/month) |
| Avg. satisfaction score | ~8 / 10 |
- Synthesizes any PDF syllabus into personalized quizzes — Uploads multiple lecture PDFs, chunks them into ~500-word segments, and randomly draws from the full course library to generate 20-question sessions that span the entire syllabus, not just one chapter.
- Enforces true active recall with a two-phase question format — Each question prompts you to write a free-text answer before the MCQ/MSQ options are revealed. Gemini then evaluates your open-ended response and explains every option — so you're retrieving from memory first, not recognizing from a list.
- Tracks learning velocity with a persistent progress dashboard — Recharts-powered analytics surface score trends, difficulty progression, and quiz frequency so you can see exactly where you're improving week over week.
- Configures quiz depth and style to match your exam format — Choose from 4 difficulty levels (Easy → Expert) and 5 themes (Conceptual, Scenario-based, Application, Analytical, Mix) to simulate the exact exam conditions you're preparing for.
- Enforces timed sessions to simulate real exam pressure — A 20-minute countdown timer (1 min per question) replicates time-constrained test conditions, training both recall speed and composure under pressure.
- Enables real-time study Q&A via a persistent AI chatbot — A Gemini-backed chatbot floats across all pages so you can ask clarifying questions about your study material without leaving the quiz flow.
- Scales across an entire course library with multi-PDF management — Upload, search, and soft-delete PDFs across all modules; Firestore scopes all data to
user.uidso your library stays private.
Who is this for?
| User | Use Case |
|---|---|
| 📚 Students with dense syllabi | Convert lecture slides and notes into exam-ready quizzes without manually writing questions |
| 🎓 MBA / professional course cohorts | Share a single deployment with classmates — everyone uploads their own PDFs and generates personalized quizzes |
| 🧑💻 AI PM learners | Study AI/ML/PM frameworks from PDFs and immediately test retention — the exact use case this app was built for |
| 📝 Certification candidates | Upload study guides for PMP, AWS, GCP, CAPM, etc. and auto-generate adaptive practice tests |
Why not just use ChatGPT? ChatGPT doesn't store your study library, track your scores over time, or adapt quiz style to your preferences. This app is a product — with persistent state, auth, analytics, and a UI purpose-built for the study workflow.
Click to expand file tree
AI-Study-Quiz-Generator/
├── src/
│ ├── components/
│ │ └── Chatbot.tsx # Global AI chatbot floating widget (Gemini-backed)
│ ├── pages/
│ │ ├── Dashboard.tsx # PDF library + quiz generation hub
│ │ ├── History.tsx # Past quiz results, scores & replay
│ │ ├── Login.tsx # Firebase Auth login / sign-up page
│ │ ├── Progress.tsx # Recharts analytics: score trends & difficulty breakdown
│ │ └── Quiz.tsx # Active quiz session: timer, MCQ/MSQ, AI recall evaluation
│ ├── App.tsx # Root component: AuthContext provider + React Router
│ ├── firebase.ts # Firebase SDK init, auth helpers (login / logout)
│ ├── index.css # Global Tailwind base styles
│ └── main.tsx # Vite entry point
├── server.ts # Express server: /api/upload-pdf + Vite SPA middleware
├── .env.example # Environment variable template
├── firebase-applet-config.json # Firebase project config for AI Studio deployment
├── firebase-blueprint.json # Firestore collection schema blueprint
├── firestore.rules # User-scoped Firestore security rules
├── index.html # SPA shell / Vite entry HTML
├── metadata.json # AI Studio app metadata
├── package.json # Dependencies & npm scripts
├── tsconfig.json # TypeScript compiler config
└── vite.config.ts # Vite + React + Tailwind plugin config
Firebase Auth manages session state. AuthContext propagates the current user throughout the React tree, and all Firestore reads/writes are scoped to user.uid — enforced at both the app layer and Firestore security rules.
sequenceDiagram
actor User
participant LoginPage
participant FirebaseAuth
participant AuthContext
participant Firestore
User->>LoginPage: Enter credentials (email / Google OAuth)
LoginPage->>FirebaseAuth: signIn (email or popup)
FirebaseAuth-->>AuthContext: onAuthStateChanged → setUser(currentUser)
AuthContext-->>App: user state propagated via React Context
App->>Dashboard: Navigate to "/" (protected route)
Dashboard->>Firestore: query(pdfs, where userId == user.uid)
Firestore-->>Dashboard: Real-time snapshot via onSnapshot()
Note over User,Firestore: All Firestore queries are scoped to user.uid.<br/>Firestore security rules enforce server-side isolation.
AuthContext is the single global provider, defined in App.tsx and consumed via the useAuth() hook throughout all pages.
| Property | Type | Description |
|---|---|---|
user |
User | null |
Firebase Auth user object; null when unauthenticated |
loading |
boolean |
true during initial auth state resolution; prevents flash of unauthenticated content |
All pages import useAuth() to access the current user. Quiz generation, PDF uploads, and Firestore queries all derive userId from user.uid — no separate user store needed.
| Route | Page | Purpose | Key Interactions |
|---|---|---|---|
/login |
Login.tsx |
Authentication gate | Firebase Auth sign-in / sign-up |
/ |
Dashboard.tsx |
Main hub | Multi-PDF upload, difficulty/theme selectors, quiz generation trigger, PDF library with search & delete |
/quiz/:quizId |
Quiz.tsx |
Active quiz session | Two-phase recall flow: free-text answer → MCQ/MSQ reveal; 20-minute countdown timer; Gemini-graded per-option explanations; score saved to Firestore |
/history |
History.tsx |
Past sessions | Quiz history list, scores, timestamps, replay navigation |
/progress |
Progress.tsx |
Learning analytics | Recharts graphs: score over time, difficulty distribution, quiz frequency |
| Component | Location | Description |
|---|---|---|
Chatbot |
src/components/Chatbot.tsx |
Persistent floating AI assistant powered by Gemini; available on all authenticated pages for real-time study Q&A without leaving the current workflow |
Gemini's schema-constrained output (responseMimeType: "application/json" + responseSchema) ensures deterministic, type-safe quiz generation — no fragile regex parsing, no hallucinated JSON structure.
flowchart TD
A[User clicks Generate Quiz] --> B[Fetch all chunks from Firestore\nwhere userId == user.uid]
B --> C[Shuffle all chunks\nSelect up to 10 at random\n~500 words each ≈ 5K token context]
C --> D[Build prompt:\n• Difficulty level\n• Theme / style\n• Anti-memorization rules\n• 20-question target\n• MCQ + MSQ mix]
D --> E[Gemini Flash Preview\ngemini-3-flash-preview]
E --> F[Schema-constrained JSON\nArray of Question objects]
F --> G{Parse response.text}
G -->|Success| H[Save Quiz → Questions → Options\nto Firestore sequentially]
G -->|Error| I[Alert user\nReset generating state]
H --> J[navigate to /quiz/:quizId]
The quiz generation prompt enforces three guardrails to prevent shallow, memorization-based questions:
- Anti-copying rule — explicitly instructs Gemini not to reproduce sentences from source content directly
- Understanding gate — requires questions to test conceptual comprehension, not surface-level fact recall
- Structural constraint — mandates a MCQ/MSQ mix with shuffled answer positions to prevent pattern recognition
The quiz page implements genuine active recall, not just multiple choice:
sequenceDiagram
participant User
participant QuizPage
participant Gemini
QuizPage->>User: Display question text only (no options visible)
User->>QuizPage: Type free-text answer from memory
QuizPage->>Gemini: Evaluate recallEvaluation (open-ended answer vs. correct answer)
Gemini-->>QuizPage: Recall score + qualitative feedback
QuizPage->>User: Reveal MCQ/MSQ options
User->>QuizPage: Select answer(s)
QuizPage->>User: Show per-option AI explanations
This two-phase design forces retrieval before recognition — the mechanism behind active recall's learning advantage over passive review.
Each quiz question conforms to this schema, enforced at the API level — not at parse time:
{
questionText: string,
type: "MCQ" | "MSQ", // Single or multiple correct answers
explanation: string, // Overall question rationale
theme: string, // Topic tag (e.g. "Analytical", "Conceptual")
options: [{
optionText: string,
isCorrect: boolean,
explanation: string // Per-option explanation: why right or wrong
}]
}pdfs/ { userId, title, createdAt }
chunks/ { pdfId, userId, content, createdAt }
quizzes/ { userId, score, totalQuestions, difficulty, theme, sourceContent, createdAt }
questions/ { quizId, userId, questionText, type, explanation, theme }
options/ { questionId, quizId, userId, optionText, isCorrect, explanation }
Prerequisites
- Node.js ≥ 18
- A Google AI Studio Gemini API key
- A Firebase project with Firestore + Authentication enabled
Install & run
# 1. Clone the repo
git clone https://github.com/yatinbhalla/AI-Study-Quiz-Generator.git
cd AI-Study-Quiz-Generator
# 2. Install dependencies
npm install
# 3. Configure environment variables
cp .env.example .env.local
# Edit .env.local and set: GEMINI_API_KEY=your_key_here
# 4. Start the dev server (Express API + Vite HMR)
npm run devEnvironment Variables
| Variable | Required | Description |
|---|---|---|
GEMINI_API_KEY |
✅ Yes | Google AI Studio API key — powers quiz generation and the persistent chatbot |
Firebase config is loaded from firebase-applet-config.json via src/firebase.ts. The file contains standard public Firebase config keys (API key, project ID, etc.) — these are safe to commit. To connect your own Firebase project, replace the values in firebase-applet-config.json with your own project's credentials from the Firebase Console.
Build for Production
# Build Vite frontend + bundle Express server via esbuild
npm run build
# Start production server
npm startThe build step compiles the React SPA with Vite and bundles server.ts into dist/server.cjs — a single-file Node.js server that serves the static frontend and handles the /api/upload-pdf endpoint.
- Chunk randomness — Quizzes draw from up to 10 randomly selected chunks; with a large PDF library, some lectures may be underrepresented in a given session. A weighted selection by recency or low-score topics is a planned v2 improvement.
- No spaced repetition — Questions from past quizzes aren't surfaced more frequently based on incorrect answers. Integrating an SM-2 algorithm would significantly improve long-term retention outcomes.
- Shared API rate limit — A single
GEMINI_API_KEYis used server-side, meaning all users in a shared deployment share the same quota. Per-user key injection or a quota management layer is needed for scaled multi-user use. - No OCR support — Scanned (image-based) PDFs don't yield usable text via
pdf-parse. Google Document AI integration is the natural next step for broader PDF compatibility. - No quiz curation — Once generated, questions can't be manually reviewed or removed before starting. A review-before-start flow would reduce friction on poorly extracted chunks.
- Desktop-first layout — The current UI is not optimized for mobile. A responsive redesign for on-the-go study sessions is on the roadmap.
This started as a personal tool for one course and ended up with 70 students relying on it weekly — which means there's plenty of room to build on top. I'd genuinely love collaborators.
If you're a student, PM, or AI builder who wants to add features, fix edge cases, or just poke the architecture — you're welcome here.
Ways to contribute:
- 🐛 Open an Issue for bugs, edge cases, or UX friction points you hit
- 💡 Propose features (spaced repetition, OCR support, quiz sharing, topic tagging, mobile layout) via GitHub Issues or Discussions
- 🔧 Submit a PR — all levels welcome; product feedback is as valuable as code
No contribution is too small. If you used this to study for something and have thoughts on what would make it better, open an issue. That's product research I actually want.
Yatin Bhalla · Product Manager & AI Product Builder