mara-pt
I wanted a better way to review my Portuguese lessons, so I built one with my teacher, Mara: an Anki-style spaced-repetition app for her classes. She unlocks each lesson as a class covers it; her students review the cards on their phones. It's been live with real classes since early July 2026.

For the teacher
Lessons are decks of cards, grouped into lesson plans. The real course is one plan, A1 to A2: 50 lessons and about 2,600 cards so far, every one of them from my own notes on her classes. I transcribe them (there's a new lesson every week, so this never ends), then ChatGPT and Gemini each review the cards for accuracy, as separate judges. When they flag something local or specific to European Portuguese, I take it to Mara before it goes into the app.
She creates a class, adds students by name and email, and the app sends each an invite. Then she turns the plan on for that class and unlocks lessons one at a time as they get through them. Locking a lesson again just hides it; nobody's progress is lost.

I needed more verb practice, so verbs got their own drills. Verb tenses unlock the same way lessons do. Turn on, say, the pretérito perfeito for a class and it becomes drillable for every verb in that class's unlocked lessons, including ones unlocked later. There's also an optional English-to-Portuguese drill ("I walk" becomes "eu ando"), a preview-as-student mode that saves nothing, and a dashboard showing how many days each week a class studied.

For students
Students get a phone-first app that installs to the home screen. Home shows what's due. Each lesson has its own deck, and a global deck pulls in new cards from the newest lesson while keeping everything older in review.


Cards come in a few kinds, each labeled: words, phrases (something useful in a restaurant), concepts (grammar or culture questions, like whether the couvert is free), verbs, nouns and adjectives. Most get studied both ways, Portuguese to English to recognize and English to Portuguese to produce, and the two are scheduled separately. A verb card also feeds the conjugation drills, which are scheduled per verb and tense across the whole course rather than per lesson; a conjugation belongs to the verb, not the lesson. Nouns and adjectives feed drills on gender, plurals, feminine forms and agreement. Numbers, dates and times are generated from rules, so you get a fresh example every time.
Classic flashcard flow: show the answer, grade yourself Outra vez, Difícil, Bom or Fácil, and the scheduler decides when the card comes back. Plus "practice anyway" rounds for cramming the night before class, and a verb reference. Menus are in Portuguese or English; the content is European Portuguese, often with the English alongside.
How I built it
With Claude Code, starting in July 2026. First a spec and a build plan, then a clickable demo in Storybook, so Mara and I could agree on how it should work before anything was real. Then the real app: Next.js, React and TypeScript on Vercel, Supabase for the database and logins, and the same scheduling algorithm modern Anki uses (FSRS, via ts-fsrs). I'm about 330 commits and 65 database migrations in.
The bit worth explaining is the data model. There's no card list per deck; a deck is a query. Whether a student can study a card is worked out from their class and which lessons and tenses are unlocked for it. Why does that matter? Unlocking a lesson for a whole class writes one row, and a student who joins late needs nothing backfilled. Verbs are data too (verb × tense × person); nobody hand-writes a card per conjugation. Conjugations stay hidden from students until a person has verified them.
Two things broke. A new join table quietly took out five live database reads, and for a while the links Mara emailed only worked in her own browser. Both fixed, and I wrote a rule into the project for each so it doesn't happen twice.
Still moving: the newest lessons and irregular-verb drills shipped on November 1. She also teaches English to Portuguese speakers, so the plan is an English version that runs the other way.
This post was written using Claude. I am working through a backlog of posts and topics, and I don't want to keep delaying. I hope to revise this post myself and remove this comment in the near future.