TypeLearn


Dictation-based language learning — Django, Strawberry GraphQL and Vue

Idea

Most language apps test recognition: pick the right word out of four, flip a flashcard. That trains you to recognise a word when you see it. Dictation trains something else — writing down what you hear: you listen to a sentence and type it yourself, with nothing to choose from.

The raw material already exists. Common Voice is a free, crowd-sourced collection of recorded sentences in more than a hundred languages, each clip paired with its text and checked by other listeners. TypeLearn turns those recordings into dictation exercises, keeping only short sentences with verified audio.

Features

(for now)

  • The clip plays as soon as the sentence appears, so you listen first instead of copying
  • An on-screen Thai (Kedmanee) keyboard highlights the next key and switches to the Shift layer by itself when that key lives there; after a mistake it highlights Backspace instead
  • Keys are coloured by the finger that presses them, with the index fingers' resting keys marked — touch-typing guidance for a script most learners have never typed
  • The answer is checked the moment it reaches the sentence's length — no button to press
  • After a correct answer: today's and the last 7 days' totals (symbols, key presses, sentences) and one more listen to the sentence you just typed
  • Thai is rendered in a looped typeface, because beginners tell Thai letters apart by their loops
  • Works on a phone: the system keyboard stays down instead of covering the app's own
  • Interface in English, French, German, Thai, Russian and Hungarian
  • No account: the practice counters stay in your browser

Tech stack

Backend is Django with a Strawberry GraphQL API on PostgreSQL. Frontend is Vue 3 with Pinia and Tailwind. Deployed on Kubernetes as a single Helm chart; CI/CD runs on GitHub Actions.

Keyboard layouts are plain data files, so supporting another keyboard means adding a layout, not rewriting the keyboard.

How I build it

Local development runs the same Helm chart as production on a kind cluster driven by Tilt. Every git worktree — mine or an LLM coding agent's — gets its own namespace, database and ports, and every feature starts as an openspec proposal before any code.

All of it is public: the repository carries every completed proposal with its design notes and task list, and a decision log recording why each choice was made — including the ones that were later reversed.

CI on GitHub Actions builds each image once and tests inside it — pytest, Vitest, and Playwright in a real browser — renders the Helm chart in every configuration it supports, checks that a secret can never land in a ConfigMap, brings the whole stack up in a kind cluster for a smoke test, and only then promotes the exact images that passed. Nothing is rebuilt between being tested and being shipped.

Try it

Open typelearn.app — no sign-up. The source is on GitHub under AGPL-3.0.