Turn any PDF into a world-class study deck. Let science handle what you review and when.
| URL | |
|---|---|
| Frontend (Vercel) | recallio-designed-for-perfect-recal-seven.vercel.app |
| Backend (Render) | recallio-backend.onrender.com |
| Health Check | /api/health |
| API Docs | /docs |
β οΈ Render free tier sleeps after 15 min of inactivity. Before opening the app, wake the backend first:
- Open
https://recallio-backend.onrender.com/api/health- Wait for
{"status":"ok","version":"1.0.0"}- Then open the frontend
β οΈ Groq free tier limit: 100,000 tokens/day per account. If card generation fails with"LLM returned empty", wait ~24 hours for the limit to reset.
Recallio converts any PDF β a textbook chapter, lecture notes, research paper β into a rich set of high-quality flashcards, then uses the scientifically-proven SM-2 spaced repetition algorithm to schedule exactly what you should study and when. Cards you know well fade away. Cards you're struggling with keep surfacing. Over time, you build genuine long-term retention β not the illusion of it.
The LLM (Groq) doesn't just scrape surface-level facts. It generates cards across multiple cognitive levels: definitions, relationships, edge cases, worked examples, and conceptual "why" questions β the kind a great teacher would write.
This isn't a utility. It's a complete, polished learning experience β from a premium animated landing page down to a smooth, keyboard-driven review session.
Recallio is designed to feel like a real product, not a side project.
Landing Page (/) β A fully animated hero with parallax scrolling, an interactive 3D flashcard demo you can flip right on the page, feature cards with hover glow, student testimonials, and a clear CTA flow. Built to impress at first glance.
Onboarding (/onboarding) β A focused, minimal name-input screen. No account. No friction. Just a name, stored locally via Zustand, and you're in.
User Flow:
/ (Landing)
β "Start Learning Free"
β if returning user β /dashboard
β if new user β /onboarding β enter name β /dashboard
Inside the app: Every page lives inside a dark, space-themed UI with floating orb animations, smooth page transitions via Framer Motion, and a persistent sidebar that greets you by name. The review session is keyboard-first, distraction-free, and satisfying to use.
| Area | What It Does |
|---|---|
| Landing Page | Animated hero, interactive flashcard demo, testimonials, CTA β a full product landing |
| Onboarding | Name input with quick-select chips; stored locally, no account required |
| PDF Ingestion | Upload any PDF; smart chunking + Groq extracts high-quality cards (15β40 per doc) |
| Card Types | Basic Q&A, Cloze deletion, Definition, Worked Example, Conceptual, Edge Case |
| SM-2 SRS | Cards scheduled by ease factor + interval; you never manually decide what to study |
| Review Session | 3D flip animation, self-rating (Again / Hard / Good / Easy), keyboard shortcuts |
| Dashboard | Cards due today, streak, mastery %, upcoming reviews β personalized by name |
| Analytics | Heatmap, retention curve, cards-per-day chart, per-deck mastery breakdown |
| History | Every session logged β date, deck, duration, accuracy, cards covered |
| Deck Manager | Browse, search, tag, rename, delete decks |
| About | How the app works, algorithm explainer, Groq attribution |

The first impression of Recallio β a visually immersive hero section that highlights the core idea of AI-powered spaced repetition learning, with strong call-to-action buttons to start learning instantly.

Your personal command center β shows cards due, streaks, study time, accuracy, and recent decks, helping users track progress and stay consistent.

A distraction-free flashcard experience powered by SM-2 spaced repetition, where users rate difficulty (Again, Hard, Good, Easy) to optimize memory retention.

Upload any study material (PDFs) and instantly convert it into AI-generated flashcards, including key concepts and worked examples.

Organized view of all study decks β users can review, browse, and track mastery levels for each subject or topic.

Deep insights into learning behavior β includes study streaks, activity heatmaps, accuracy trends, and deck mastery breakdowns.
Live demo: Recallio--Designed_for_perfect_recall
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β BROWSER (localhost:5173) β
β β
β React 18 + TypeScript + Vite + TailwindCSS β
β Framer Motion β Zustand β TanStack Query β Rechartsβ
ββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββ
β HTTP (REST)
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FastAPI (localhost:8000) β
β β
β /api/upload β PDF Parser (PyMuPDF) β
β ββ Groq API βββββββββββββββββββββββΊβ
β (llama-3.3-70b-versatile) β
β /api/review β SRS Engine (SM-2) β
β /api/analyticsβ Analytics Service β
ββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββ
β SQLAlchemy ORM
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SQLite (local file) β
β flashmind.db β zero infrastructure β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Key design decision β SQLite: Single-user, local app. SQLite gives zero-setup persistence, full SQL power, and no Docker/Postgres dependency. The entire state of the app lives in one portable .db file.
| Package | Version | Purpose |
|---|---|---|
fastapi |
0.111 | API framework |
uvicorn |
0.30 | ASGI server |
sqlalchemy |
2.0 | ORM |
alembic |
1.13 | DB migrations |
pydantic |
2.7.4 | Request/response validation |
pymupdf (fitz) |
1.24.3 | PDF text + structure extraction |
groq |
latest | LLM client (card generation) |
python-multipart |
β | File uploads |
python-dotenv |
β | Env var loading |
| Package | Version | Purpose |
|---|---|---|
react |
18 | UI framework |
typescript |
5 | Type safety |
vite |
5 | Build tool |
tailwindcss |
3 | Styling |
framer-motion |
11 | Card flip + page animations |
zustand |
4 | Global state (user identity, session, deck) |
@tanstack/react-query |
5 | Server state, caching, refetch |
recharts |
2 | Analytics charts |
react-router-dom |
6 | Client-side routing |
react-dropzone |
β | PDF drag-and-drop upload |
axios |
β | HTTP client |
lucide-react |
β | Icon set |
recallio/
βββ backend/
β βββ alembic/ # DB migration scripts
β βββ app/
β β βββ routers/
β β β βββ upload.py # POST /upload β PDF ingestion pipeline
β β β βββ decks.py # CRUD for decks
β β β βββ cards.py # Card CRUD + bulk ops
β β β βββ review.py # Session start/answer/end
β β β βββ analytics.py # Charts data endpoints
β β β βββ history.py # Study session history
β β βββ services/
β β β βββ pdf_parser.py # PyMuPDF β structured text chunks
β β β βββ card_generator.py # Groq API β prompt + parse + validate
β β β βββ srs_engine.py # SM-2 algorithm + scheduling
β β βββ config.py # App config + env var loading
β β βββ database.py # SQLAlchemy engine + session
β β βββ main.py # FastAPI app + CORS + routers
β β βββ models.py # ORM models (Deck, Card, SRS, Session)
β β βββ schemas.py # Pydantic request/response schemas
β βββ .env.example
β βββ alembic.ini
β βββ flashmind.db # Auto-created on first run
β βββ requirements.txt
β
βββ frontend/
β βββ public/
β β βββ favicon.svg
β β βββ icons.svg
β βββ src/
β β βββ api/
β β β βββ client.ts # Axios instance + typed API calls
β β βββ assets/
β β β βββ hero.png
β β βββ components/
β β β βββ cards/
β β β β βββ FlashCard.tsx # 3D flip card component
β β β β βββ RatingBar.tsx # Again/Hard/Good/Easy buttons
β β β βββ layout/
β β β β βββ FloatingBackground.tsx # Animated orb/particle background
β β β β βββ Layout.tsx # Page wrapper
β β β β βββ Sidebar.tsx # Navigation + user greeting
β β β βββ ui/
β β β βββ Badge.tsx
β β β βββ Spinner.tsx
β β β βββ StatCard.tsx # Dashboard stat tiles
β β β βββ TiltCard.tsx # Mouse-tilt interactive card
β β βββ hooks/
β β β βββ useCardTilt.ts # Mouse parallax tilt hook
β β βββ pages/
β β β βββ About.tsx # App info + algorithm explainer
β β β βββ Analytics.tsx # Full analytics dashboard
β β β βββ Dashboard.tsx # Home β stats + due cards + streak
β β β βββ DeckDetail.tsx # Single deck β all cards + edit
β β β βββ Decks.tsx # All decks grid view
β β β βββ History.tsx # Past sessions timeline
β β β βββ Landing.tsx # Animated landing page
β β β βββ Onboarding.tsx # Name input + entry flow
β β β βββ Review.tsx # Active study session
β β β βββ Upload.tsx # Drag-and-drop PDF β card generation
β β βββ store/
β β β βββ reviewStore.ts # Active session state
β β β βββ userStore.ts # Zustand store β user name, persistence
β β βββ utils/
β β β βββ getGreeting.ts # Time-based greeting helper
β β βββ App.css
β β βββ App.tsx # Router setup (Landing β Onboarding β App)
β β βββ index.css
β β βββ main.tsx
β βββ index.html
β βββ vite.config.ts
β βββ package.json
β
βββ package.json # Root β single `npm run dev` starts everything
βββ start.sh # Shell bootstrap script
βββ README.md
βββ CLAUDE.md
-- A study deck (one PDF = one deck)
CREATE TABLE decks (
id TEXT PRIMARY KEY, -- UUID
title TEXT NOT NULL,
description TEXT,
source_file TEXT NOT NULL, -- original PDF filename
tags TEXT, -- comma-separated
card_count INTEGER DEFAULT 0,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL
);
-- Individual flashcards
CREATE TABLE cards (
id TEXT PRIMARY KEY,
deck_id TEXT NOT NULL REFERENCES decks(id) ON DELETE CASCADE,
front TEXT NOT NULL, -- question / prompt
back TEXT NOT NULL, -- answer / explanation
card_type TEXT NOT NULL, -- basic | cloze | definition | example | conceptual
hint TEXT, -- optional hint shown before reveal
tags TEXT,
created_at DATETIME NOT NULL
);
-- SM-2 state per card (one row per card, updated after every review)
CREATE TABLE card_srs (
card_id TEXT PRIMARY KEY REFERENCES cards(id) ON DELETE CASCADE,
ease_factor REAL DEFAULT 2.5,
interval INTEGER DEFAULT 0, -- days until next review
repetitions INTEGER DEFAULT 0, -- consecutive correct reviews
due_date DATETIME NOT NULL, -- next scheduled review
state TEXT DEFAULT 'new' -- new | learning | review | mastered
);
-- One row per study session
CREATE TABLE study_sessions (
id TEXT PRIMARY KEY,
deck_id TEXT REFERENCES decks(id) ON DELETE SET NULL,
deck_title TEXT, -- snapshot in case deck is deleted
started_at DATETIME NOT NULL,
ended_at DATETIME,
cards_reviewed INTEGER DEFAULT 0,
correct_count INTEGER DEFAULT 0, -- quality >= 3
duration_secs INTEGER DEFAULT 0
);
-- One row per card answer within a session
CREATE TABLE card_reviews (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL REFERENCES study_sessions(id),
card_id TEXT NOT NULL REFERENCES cards(id) ON DELETE CASCADE,
quality INTEGER NOT NULL, -- 0-5 (SM-2 scale)
time_taken_ms INTEGER,
reviewed_at DATETIME NOT NULL,
ease_before REAL,
interval_before INTEGER
);POST /api/upload Multipart PDF upload β triggers generation pipeline
GET /api/upload/{job_id}/status Poll generation progress (SSE or polling)
GET /api/decks List all decks (with stats)
GET /api/decks/{id} Single deck + all its cards
PATCH /api/decks/{id} Update title, description, tags
DELETE /api/decks/{id} Delete deck + all cards
GET /api/cards/due Cards due for review today (all decks)
GET /api/decks/{id}/cards All cards in a deck
PATCH /api/cards/{id} Edit front/back/hint
DELETE /api/cards/{id} Delete single card
POST /api/review/start Start session β { session_id, first_card }
POST /api/review/answer Submit answer quality (0β5) β { next_card, srs_update }
POST /api/review/end End session early β final stats
GET /api/review/session/{id} Session summary
GET /api/analytics/overview Total cards, mastered, retention rate, streak
GET /api/analytics/heatmap Daily study counts (last 365 days)
GET /api/analytics/retention Retention curve data per deck
GET /api/analytics/decks Per-deck mastery breakdown
GET /api/analytics/daily-cards Cards reviewed per day (last 30 days)
GET /api/history All sessions (paginated, filterable by deck/date)
GET /api/history/{id} Single session detail + card-by-card breakdown
Every card carries three values: ease_factor (EF), interval (days), repetitions.
After each review, user rates quality q β {0, 1, 2, 3, 4, 5}
0 = Complete blackout
1 = Wrong, but felt familiar
2 = Wrong, easy recall
3 = Correct, significant effort β threshold
4 = Correct, some hesitation
5 = Perfect recall, instant
If q < 3 (failed):
repetitions = 0
interval = 1
state = 'learning'
If q >= 3 (passed):
if repetitions == 0: interval = 1
if repetitions == 1: interval = 6
else: interval = round(interval * ease_factor)
repetitions += 1
state = 'review' if interval < 21 else 'mastered'
EF update (always):
EF = EF + (0.1 - (5 - q) * (0.08 + (5 - q) * 0.02))
EF = max(1.3, EF) # floor at 1.3
due_date = today + interval days
Cards in state new are interleaved with learning cards so new material is always being introduced alongside review.
The quality of generated cards is the hardest problem. The pipeline:
- Extract text preserving heading hierarchy (H1 β H2 β paragraph)
- Detect and skip headers, footers, page numbers
- Split into semantic chunks of ~800β1200 tokens with overlap
- Each chunk carries its section title as context
Cards are generated in a structured JSON format via a carefully engineered system prompt:
System: You are an expert educator creating flashcards for deep learning.
Generate cards at multiple cognitive levels:
- DEFINITION: precise definitions of key terms
- CONCEPT: "why" and "how" questions about mechanisms
- RELATIONSHIP: how concepts connect or contrast
- EXAMPLE: worked examples or applications
- EDGE_CASE: common mistakes, boundary conditions
Rules:
- Front must be specific and unambiguous
- Back must be complete but concise (< 80 words)
- No trivial yes/no questions
- Vary difficulty: 40% recall, 40% understanding, 20% application
- Output valid JSON array only
User: [section title + chunk text]
- Parse and validate JSON output
- Deduplicate cards by semantic similarity (simple token overlap check)
- Filter cards where front or back is too short/long
- Assign
card_typefrom the LLM's category tag - Bulk insert with initial SRS state (
due_date = today)
Target: 15β40 high-quality cards per PDF, not 100 shallow ones.
- Animated hero with cycling text (Smarter / Faster / Deeper / Longer)
- Parallax scroll effects and floating particle background
- Interactive 3D flashcard demo β click to flip, right on the page
- Feature cards with hover glow effects
- Student testimonials section
- Dual CTA: "Start Learning Free" β onboarding / dashboard
- Centered name-input card β clean, minimal, focused
- Quick-select name chips for fast entry
- Name persisted via Zustand + localStorage β no account required
- "Stored locally. No account required." β trust signal on screen
- Personalized greeting using stored user name
- Today's due cards count with a "Start Review" CTA
- Current study streak (days)
- Total mastered / total cards ratio
- Mini upcoming review calendar (next 7 days)
- Recently added decks
- Full-screen drag-and-drop zone
- Real-time progress: "Parsing PDF β Analyzing content β Generating cards β Done"
- Preview of generated cards before saving
- Option to regenerate or delete individual cards before saving
- One card at a time, centered on screen
- Front shown first; spacebar / click to flip (3D flip animation via Framer Motion)
- Rating buttons: Again Β· Hard Β· Good Β· Easy (with estimated next review time shown)
- Keyboard shortcuts: Space = flip, 1/2/3/4 = rate
- Session progress bar + cards remaining
- "End Session" available at any point
- Card grid with deck thumbnail (auto-generated gradient based on title hash)
- Shows: card count, mastery %, last studied date
- Search + tag filter
- Sort by: newest, most due, mastery %, alphabetical
- Vertical timeline of all study sessions
- Each entry: deck name, date, duration, accuracy %, cards reviewed
- Click to expand β full card-by-card breakdown of that session
- Filter by deck or date range
- Study Heatmap β GitHub contribution-style grid (last 52 weeks)
- Daily Cards Chart β bar chart of cards reviewed per day (last 30 days)
- Mastery Breakdown β stacked bar per deck: New / Learning / Review / Mastered
- Retention Curve β estimated forgetting curve overlay
- Top Stats β total study time, longest streak, best day, average accuracy
- Python 3.11+
- Node.js 20+
- A Groq API key β get one free at console.groq.com
git clone https://github.com/SamridhiiiGupta/Recallio--Designed_for_perfect_recall.git
cd Recallio--Designed_for_perfect_recallcd backend
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env
# Open .env and add your GROQ_API_KEY
alembic upgrade head # Creates flashmind.db with schemacd ../frontend
npm installFrom the project root:
npm run devThis starts both the FastAPI backend and the Vite frontend in one terminal. Visit http://localhost:5173 β upload a PDF and start studying.
# backend/.env
GROQ_API_KEY=gsk_... # Required β Groq API key
GROQ_MODEL=llama-3.3-70b-versatile # Model to use for card generation
DATABASE_URL=sqlite:///./flashmind.db
CORS_ORIGIN=http://localhost:5173
MAX_PDF_SIZE_MB=50
CARDS_PER_CHUNK=5 # Cards to generate per text chunk
# frontend/.env (not committed)
VITE_API_URL=http://localhost:8000Render (backend)
| Key | Value |
|---|---|
GROQ_API_KEY |
Your Groq API key |
GROQ_MODEL |
llama-3.3-70b-versatile |
DATABASE_URL |
sqlite:///./flashmind.db |
CORS_ORIGIN |
Your Vercel frontend URL |
MAX_PDF_SIZE_MB |
50 |
CARDS_PER_CHUNK |
5 |
PYTHON_VERSION |
3.11.9 |
Vercel (frontend)
| Key | Value |
|---|---|
VITE_API_URL |
https://recallio-backend.onrender.com |
# Backend (if running separately)
uvicorn app.main:app --reload --port 8000
alembic revision --autogenerate -m "description"
alembic upgrade head
# Frontend (if running separately)
npm run dev # Dev server
npm run build # Production build
npm run lint # ESLint check
npm run type-check # TypeScript check (tsc --noEmit)
# Reset database (fresh start)
rm flashmind.db && alembic upgrade head- Project architecture + README
- Backend: DB models + migrations
- Backend: PDF parsing service
- Backend: Groq card generation service
- Backend: SM-2 SRS engine
- Backend: All API routes
- Frontend: Layout + routing + dark theme
- Frontend: Upload page + progress flow
- Frontend: Review session (flip card + rating)
- Frontend: Dashboard
- Frontend: Analytics dashboard
- Frontend: History timeline
- Frontend: About page
- Keyboard shortcuts + accessibility
- Animated landing page + onboarding flow
- Zustand-persisted user identity (no auth required)
- Single-command dev setup (
npm run dev) - Deployed: Vercel (frontend) + Render (backend)
- Dynamic API URL via
VITE_API_URLenv var - Card editing UI
- Export deck as Anki-compatible
.apkg
- Sound effects on card flip / session complete
- Confetti on streak milestones
- "Daily goal" system with push notifications (Electron wrapper)
- Offline support (service worker)
- Multiple card themes / fonts
Groq's LPU inference hardware delivers sub-second latency on large models. For a card generation pipeline that processes 10+ text chunks per PDF, this means a 50-page document generates its full card deck in under 30 seconds rather than minutes. The llama-3.3-70b-versatile model used here rivals GPT-4 in instruction-following quality while being free-tier accessible.
Long-term retention beats short-term cramming. Every time.