A terminal-styled pinyin workbench for learning Mandarin.
Type pinyin → discover hanzi → build phrases → hear them spoken.
learn-chinese is a minimal, keyboard-first web app that helps you study Mandarin the way a CLI tool would teach it. You type pinyin, the app surfaces matching hanzi with meanings and audio, and you assemble selections into phrases you can play back character-by-character.
It is not a gamified streak app. It is a vocabulary workbench — fast, forgiving, and focused.
- Forgiving pinyin search — type with tone marks (
nǐ hǎo), tone numbers (ni3 hao3), or plain letters (ni hao). All three work. - Active vocabulary registry — selected cards persist to
localStorageand survive reloads. - Phrase workbench — bundle cards into sentences, toggle hanzi ↔ pinyin view, play audio for the full phrase.
- Web Speech audio — native browser TTS with automatic detection of quality Mandarin voices (Tingting, Xiaoxiao, etc.).
- Bilingual UI — full localization in English and Brazilian Portuguese, persisted via cookie.
- Keyboard-native UX — arrow keys navigate suggestions, Enter selects, Escape clears. No mouse required.
- Terminal aesthetic — JetBrains Mono, dark
#0a0d0abackground, lime-green accents, Silkscreen display type.
Seeded from HSK 1 and selected HSK 2 entries, cross-referenced against CC-CEDICT and Pleco. Each entry carries:
{
id: "你好",
hanzi: "你好",
pinyin: "nǐ hǎo",
english: "hello",
portuguese: "olá",
}Entries live in app/data/vocabulary.ts and are ordered so the most common sense of any ambiguous pinyin variant comes first.
| Layer | Choice |
|---|---|
| Framework | Remix (SSR) |
| Bundler | Vite |
| Language | TypeScript |
| Styling | Tailwind CSS |
| Runtime / PM | Bun (or Node ≥ 20) |
| Audio | Web Speech API |
| Persistence | localStorage + cookie (locale) |
# install
bun install
# dev server (http://localhost:5173)
bun run dev
# production build
bun run build
bun run start
# type-check
bun run typechecknpm / pnpm / yarn work just as well — replace
bun runwith your package manager of choice.
app/
├── data/
│ └── vocabulary.ts # HSK 1/2 corpus
├── lib/
│ ├── i18n.ts # en + pt-BR dictionaries
│ ├── lang-cookie.{ts,server.ts}
│ ├── pinyin.ts # tone-mark & numeric normalization
│ ├── speech.ts # Web Speech API wrapper
│ └── storage.ts # localStorage helpers
├── routes/
│ └── _index.tsx # the entire workbench UI
├── root.tsx
└── tailwind.css
public/
└── favicon.svg # 汉 glyph on terminal-dark tile
remotion/
├── Demo.tsx # animated README demo
├── Root.tsx
└── index.ts
scripts/
└── find-hanzi-variants.ts # CC-CEDICT candidate discovery
The repo ships with a Bun script that scans CC-CEDICT for hanzi candidates matching pinyin keys you already have, filters out entries already in the corpus, and writes a TypeScript snippet ready for manual review.
bun run find-variants
# → scripts/output/variant-candidates.tsCherry-pick the candidates you want, translate them, and paste into app/data/vocabulary.ts.
| Key | Action |
|---|---|
↑ / ↓ |
Navigate pinyin suggestions |
Enter |
Select highlighted suggestion |
Esc |
Clear the input / dismiss dropdown |
The animated demo above is generated with Remotion — no screen recorder, just React. The composition lives in remotion/ and mirrors the real app's terminal styling.
bun run demo:studio # open the Remotion studio to iterate
bun run demo:gif # re-render public/demo.gif
bun run demo:render # re-render public/demo.mp4 (h264)Released under the MIT License.
Vocabulary definitions are derived from CC-CEDICT and are distributed under the CC BY-SA 4.0 terms of the source dictionary.
祝你学习愉快 · happy studying · bons estudos
