Master languages one sentence at a time — with spaced repetition and offline speech recognition.
- Spaced repetition (SM-2 algorithm) — review sentences at optimal intervals
- Pronunciation scoring — speak and get instant feedback (0–100%)
- Offline speech recognition — Vosk WASM, no API keys, no data uploaded
- Zipf progression — unlock harder vocabulary as you improve
- Multi-language — Spanish, Chinese, Swedish (easily extendable)
- Zero backend — everything runs in the browser, progress saved locally
See the sentence, reveal the pronunciation guide, or tap "I don't understand" for the translation.
Hold the microphone button, speak the sentence, release — get an instant 0–100% score.
A level bar shows how many correct answers until the next Zipf level unlocks.
| Step | Action | What happens |
|---|---|---|
| 1 | App opens | Loads sentences from JSON, restores your progress from IndexedDB |
| 2 | Card shown | SM-2 picks the sentence due for review today |
| 3 | Listen | Tap the speaker icon to hear eSpeak-NG audio |
| 4 | Speak | Hold mic button → Web Speech API / Vosk transcribes live |
| 5 | Score | Word-overlap score (0–100%) updates ease factor |
| 6 | Next | SM-2 schedules the next review; Zipf level unlocks at milestones |
| Layer | Technology | Why |
|---|---|---|
| UI | React 18 | Functional components, fast |
| Styling | Tailwind CSS | Utility-first, no custom CSS |
| Speech recognition | Vosk WASM | Free, offline, private |
| Speech fallback | Web Speech API | Zero setup, Chrome/Edge |
| Storage | IndexedDB (Dexie) | Local-first, no backend needed |
| Hosting | Firebase Hosting | Free CDN, COOP/COEP headers |
| Algorithm | SM-2 | Battle-tested spaced repetition |
npm install
npm run dev
# → http://localhost:5173See docs/SETUP.md for Vosk model download and Firebase deployment instructions.
src/
├── components/ # React UI components (≤ 50 lines each)
├── hooks/ # Custom React hooks (business logic)
├── services/ # Data & storage abstraction layer
├── utils/ # Pure functions (SM-2, Zipf)
└── config/ # Constants, no magic numbers
public/data/ # JSON content — edit to add sentences
screenshots/ # UI screenshots for README
docs/ # Architecture, setup, API reference
Add sentences: edit public/data/sentences_<language>.json
Add a language: add to public/data/config.json + create a sentences file + add to LANG_CODES in src/config/constants.js
Add audio: drop MP3s into public/audio/ matching audioUrl values in the JSON
- Architecture Decisions — why each technology was chosen
- Setup & Deployment — installation, Vosk models, Firebase deploy
- API & Data Flow — service interfaces and data schemas
To replace the placeholders above with real screenshots:
- Open the app:
npm run dev→http://localhost:5173 - Take screenshots of each view (browser DevTools → device toolbar for mobile sizing)
- Save to the
screenshots/folder with these exact names:
| File | What to capture |
|---|---|
screenshots/main-ui.png |
Full app — card + recording panel visible |
screenshots/card-display.png |
Card with pronunciation guide expanded |
screenshots/recording.png |
Recording panel after speaking (score shown) |
screenshots/progress.png |
Progress bar area, level label visible |
- Recommended size: 800px wide for the hero, 400px wide for feature shots
- Commit:
git add screenshots/*.png && git commit -m "Add UI screenshots"
MIT



