Skip to content

gagan-53/kortex

Repository files navigation

Kortex 🥷

Flashcards that slap. Drop a PDF, get teacher-tier cards, learn with spaced repetition.

Next.js TypeScript Tailwind CSS Gemini License

Full docs · Report a bug


✦ What it does

  1. Drop a PDF — textbook chapter, lecture notes, anything with a text layer.
  2. Kortex chunks it — paragraph-aware splitter, ~6000 chars per chunk.
  3. An LLM generates cards — Gemini 2.5 Flash Lite with schema-constrained JSON returns Q/A, cloze, concept, and example cards.
  4. SM-2 schedules reviews — the same spaced-repetition algorithm Anki uses.
  5. Learn → Practice → Browse → Feed — four surfaces for intro, review, discovery, and social context.

✦ Features

📚 PDF → Cards pipeline Paragraph chunker + Gemini 2.5 Flash Lite with Zod-validated JSON schema
🧠 SM-2 spaced repetition Full Anki-style algorithm with easeFactor, intervalDays, lapses, and custom mastery scoring
🎓 Intro pass /learn surface separates "meet the card" from "test the card" via a learnedAt gate
🎬 Browse reel TikTok-style vertical swipe across all decks; ratings write through to SM-2
📡 Activity feed Append-only event log: signup, deck created, card learned, card mastered
↩️ Undo reviews 5-second window after every rating — one mis-click shouldn't cost a week
🔐 Stateless auth HMAC-signed session cookies, bcrypt password hashing, no session store
🌓 Light + dark mode Hand-tuned brutalist palette. Violet highlighter in dark mode, acid in light
📱 Mobile-first Bottom tab bar, safe-area insets, 56px touch targets, responsive across phone/tablet/desktop
⌨️ Keyboard shortcuts Space flip, 1–4 rate, ↑↓/jk navigate, U undo, ? for the cheat sheet
🎭 Kort the mascot Brain-blob SVG with six moods (wave, think, cheer, sleep, study, flex)

✦ Tech stack

Framework   Next.js 14 (App Router)  +  TypeScript 5.6
UI          React 18  +  Tailwind CSS  +  Framer Motion
Data        better-sqlite3 (WAL mode)  +  migrations baked in
Auth        HMAC session cookies  +  bcryptjs
LLM         Google Gemini 2.5 Flash Lite  +  Zod schemas
PDF         pdf-parse

Full reasoning behind every choice is in DOCS.md (also available as DOCS.docx).


✦ Quickstart

git clone https://github.com/gagan-53/kortex.git
cd kortex
npm install
cp .env.example .env.local       # add GEMINI_API_KEY and AUTH_SECRET
npm run dev

Open http://localhost:3000, sign up, drop a PDF, and you're cooking.

Grab a free Gemini key at aistudio.google.com.

Environment

Var Required Default Notes
GEMINI_API_KEY Get one from Google AI Studio
AUTH_SECRET ✅ in prod dev-only-insecure-secret-change-me 32+ random chars for HMAC signing
GEMINI_MODEL gemini-2.5-flash-lite Override to use Flash / Pro

✦ Scripts

npm run dev        # Next dev server (HMR)
npm run build      # production build
npm start          # serve the production build
npm test           # node --test on lib/**/*.test.ts
npm run lint       # next lint

✦ Project structure

kortex/
├── app/                    # Next App Router
│   ├── api/                # Route handlers (auth, upload, review, feed, …)
│   ├── browse/             # TikTok-style reel
│   ├── decks/              # Library
│   ├── deck/[id]/          # Per-deck stats
│   ├── feed/               # Activity timeline
│   ├── learn/[id]/         # Intro pass
│   ├── practice/[id]/      # SM-2 review loop
│   ├── upload/             # PDF picker
│   ├── login/, signup/     # Auth forms
│   ├── layout.tsx          # Root layout (logo, nav, mobile tab bar)
│   ├── page.tsx            # Home (streak + deck grid)
│   └── globals.css         # Design system (brutalist utilities)
├── components/
│   ├── Mascot.tsx          # Kort, six moods, SVG
│   ├── MobileNav.tsx       # Bottom tab bar
│   ├── DeckBrowser.tsx     # Search + sort + deck cards
│   ├── Flashcard.tsx       # CSS-grid flip card
│   ├── RatingBar.tsx       # again/hard/good/easy
│   ├── Confetti.tsx        # done-state burst
│   └── …
├── lib/
│   ├── db.ts               # better-sqlite3 + migrations
│   ├── auth.ts             # HMAC sessions + bcrypt
│   ├── sm2.ts              # SM-2 + mastery + struggleScore
│   ├── chunker.ts          # Paragraph-first text splitter
│   ├── llm.ts              # Gemini client + Zod schemas
│   └── prompts/            # Generation prompts
├── middleware.ts           # Auth presence-check for protected routes
├── DOCS.md / DOCS.docx     # Full technical documentation
└── tailwind.config.ts      # Brutalist color + shadow tokens

✦ Design system

Editorial brutalism. Thick borders, hard offset shadows, rotated stickers, serif headlines paired with mono labels.

Token Hex Role
ink #0B0B0F near-black, primary text
bone #F4EFE6 warm cream, light-mode base
charcoal #14131A dark-mode base
slab #1E1D26 dark-mode surface
acid #D4FF3B electric lime, primary accent
lava #FF4D26 hot orange, warnings, "slap"
violet #5B2BFF deep violet, dark-mode highlight

Type stack: Fraunces (display serif) · Inter (body) · JetBrains Mono (tags / kbd).


✦ Deployment

⚠️ Netlify / Vercel caveat: this app uses better-sqlite3 with a local DB file. Serverless hosts don't have persistent filesystems. To deploy to Netlify/Vercel you'll need to migrate the data layer to Turso, Supabase, or Neon. See DOCS.md for trade-offs.

Hosts that work out of the box (persistent disk):


✦ Roadmap

  • Export deck as Anki .apkg
  • PWA with offline review queue
  • Multi-modal cards (diagrams extracted from PDFs)
  • Per-deck difficulty calibration via IRT
  • Shared decks with fork semantics

✦ License

MIT © gagan-53


Developed by G🥷

Releases

No releases published

Packages

 
 
 

Contributors