Study
Flashcards with real spaced repetition and quizzes built from them, running entirely in the browser — no account, no server, no subscription.
- Section
- productivity
- Year
- 2026
- Role
- Solo project
- Stack
- Next.js, React, TypeScript, Dexie, IndexedDB
Summary
Flashcards with real SM-2 spaced repetition, plus quizzes built from the same cards. Everything runs client-only — decks, due dates and review logs live in IndexedDB through Dexie, with a JSON backup as a first-class feature. No account, no server, no subscription.
Story
lib/ is pure logic and it’s where the thinking goes: every module takes data
and returns data and has a test file beside it, and exactly one module is
allowed to import the database. The scheduler never reads the clock — today is
an argument — so a session crossing midnight stays consistent and the algorithm
is testable without faking time. The rating buttons show the interval each one
will cost before you press it, because a scheduler you can’t see is a scheduler
you don’t trust. The rest was invariants that never fail loudly: a day is a
YYYY-MM-DD string and an instant is epoch milliseconds; review intervals are
clamped to whole days so the button label can’t promise something the schedule
won’t deliver; and a card’s new state and its review log are written in one
transaction, since a card without its log breaks the streak and a log without
its card replays the same question forever.
Lessons
- The invariants worth the most are the ones whose violation is invisible for weeks. They need tests, not review.
- Validate restored data rather than casting it — half-shaped records crash a screen three clicks later, with the good data already overwritten.
- A colour defined only inside a media query or
[data-theme]block doesn’t apply in the default “system” state. That produced a 1.06:1 failure here once.