Learn and practice typing Bangla on a PC keyboard — structured lessons, endless speed tests and honest progress tracking, free, no sign-up, no ads, and no data leaves your device.
structured lessons · endless stream · 12 lessons · 261 themes · 21 badges · custom text · weak-key drills · a typing game · generated keyboard guide — instantly, in the browser, in English or বাংলা
Live app · Report a bug · Feature idea · Security policy · Contributing
A static website. The content pages are prerendered HTML; the typing area is a
small interactive island. There is no backend, no database, no account, and no
third-party tracker. Progress lives in localStorage.
Two input modes:
- System keyboard mode — you already have a Bangla keyboard (Avro Keyboard, an OS layout, …). The app compares the Unicode your keyboard produces against the target text. Any layout works, and the app scores what you actually typed.
- Built-in mode (preview) — the app converts Roman keystrokes into Bangla
itself, so nothing needs to be installed. The rules are backed by a real Bangla
word list: the first time the mode is used, the page fetches a correction index
of 11,221 spellings and the engine consults it whenever the rules alone would
spell a non-word (
Da^Talois ডাঁটালো instead of ডাঁটাল). Native speakers have not signed off the rules yet, so it stays an opt-in preview and the system keyboard remains the default.
A word counts as correct when its final Unicode text matches the target after normalization, no matter which keystrokes produced it.
Finished runs, the error map, lesson results and the settings all live in
localStorage. The progress page summarises them and can export, import or reset
them as one JSON file.
| Endless stream | Untimed runs never run out — a fresh line of words is generated whenever the caret gets near the end, keeping up with 100+ WPM typists without a single visual jump. |
| Time / words / zen | 15/30/60/120-second runs, 10/25/50/100-word goals that end exactly at the goal, or the endless zen stream (Tab ends it). |
| 12 lessons | A path from the vowels to conjuncts, numbers and real-world text — fixed drills, untimed, passed at 90% accuracy. |
| Your own text | A small named library of your own Bangla passages (12–1200 characters, ASCII or Bengali numerals — the other set can be repaired in with one click). Stored on your device, never uploaded. |
| Typing game | /game: words fall, you type them before they land. Three speeds, one point per cluster, three lives. Same vocabulary as the endless stream. |
| Share a result | A finished run becomes a 1200x630 PNG card, painted in the browser. No upload, no service — the file is yours. |
| Shareable links | Time, words, funbox, difficulty, layout and a custom text all fit in the query string, so one link opens one exact exercise. |
| Keyboard guide | /keyboard documents both input modes, and its tables are generated from the phonetic grammar — the tool and its documentation cannot disagree. |
| Funboxes | Twist the stream: Bengali numerals, punctuation, reversed words, or a memory mode that hides the words ahead. |
| 261 themes | Built-ins, community classics, and one palette for every country flag — every one contrast checked. Star them, export them. |
| Command bar | Ctrl+K palette and Ctrl+/ command line share one grammar: theme dracula · time 60 · words 25 · funbox numbers · goto progress. |
| Honest progress | Personal bests per test type, streaks, 21 badges, a miss-rate heat grid and the speed trend. |
| Weak-key drills | One focused drill over the clusters you mistype most. |
| Offline PWA | Install it and it works with no network at all. Nothing is fetched from a third-party server at runtime. |
/lessons is a path of twelve short lessons, from the vowels to conjuncts, numbers
and real-world text. Each lesson is a fixed drill set with no timer, passed at 90%
accuracy. The curriculum and its copy are in src/content/lessons.ts, the drill
texts in content/lessons/drills.json, and every drill carries the same
reviewed flag as a practice text.
On the practice page, Your own text opens a paste box: paste an exam question or a paragraph from a book and, once it passes the checks (Bangla only, 12–1200 characters in 3–200 words), it becomes the target of one run. Paste as many as you like — they are kept as a small named library rather than overwriting each other.
Punctuation and numerals are allowed in either numeral system, and a passage
whose digits are ASCII while your keyboard produces Bengali ones can be repaired
in one click (25 নম্বর → ২৫ নম্বর) rather than rejected. Everything is kept in
localStorage (never uploaded), it travels with the export/import file, and
"reset all data" on the progress page removes it too.
The practice test streams words endlessly, like monkeytype: untimed runs on the
built-in library never run out, because the island appends a fresh line whenever
the caret gets near the end. Tab ends the run and shows the results.
Ctrl+K (or the terminal icon in the header) opens the command palette, and
Ctrl+/ opens the command line — the same grammar either way:
theme dracula time 60 words 25 funbox numbers
conf max typos below blind on goto progress
time counts bare numbers in seconds (time 90 is a minute and a half);
an explicit suffix says otherwise (time 5m, time 45s). words counts words,
and a bare words or time alone starts an endless run.
The toolbar above the words is monkeytype's config bar: @ punctuation and
# numbers toggles, a time / words / zen / custom mode row, and duration
chips — 15/30/60/120 seconds in time mode, 10/25/50/100 words in words mode.
zen is the endless stream, custom opens Your own text.
Settings go deep: difficulty, quick restart key, confidence mode, minimum speed and accuracy, indicate typos, hide extra letters, words history, focus mode, sound volume, and further funbox modes that twist the stream (Bengali numerals, punctuation, reversed words, or words you have to remember). A difficulty or funbox change restarts the run on screen, so the choice takes effect right away — a pasted text, a lesson drill and a weak-key drill are exempt, since they are fixed targets. A small palette icon in the header opens the theme picker.
The theme gallery ships 261 palettes: the built-in ones, community classics, and one for every country flag (search "Bangladesh", or filter by flags). A flag theme is built out of that flag's own colours — the page keeps the field colour, the accent is the flag's most vivid colour (Argentina's sun, Vietnam's star), the text is the flag's white or its darkest ink — and every palette is contrast checked, so none of them can be unreadable. Themes can be starred and exported as JSON.
The progress page keeps personal bests per test type, streaks, 21 badges, a miss-rate heat grid and the speed trend. Any run in the history table opens a detail view with its own stats, the consistency score recomputed from that run's per-second speed samples, its per-cluster breakdown, and — when the test type has one — a link that repeats exactly that test.
Two more pages serve typing rather than practice:
/gameis the arcade mode: words fall, you type them before they land. Points are one per cluster, so a long word is worth more; three speeds, three lives, and a pause button. It draws from the same curated vocabulary the endless stream does, so it drills the words the site actually teaches./keyboarddocuments both input modes — the system keyboard and the built-in phonetic preview — including the conjunct and hasanta rules the engine follows. Its cheat sheet is generated fromphonetic-rules.jsonat build time, so a corrected rule shows up in the guide without anyone editing prose.
Content pages: /guides collects three guides — how to type Bangla on a computer,
an Avro phonetic cheat sheet, and preparing for a job typing test — each with its
own page; /faq answers the questions a new learner asks; /about says who
makes it and why. The FAQ answers are also the page's FAQPage structured data, so the
screen and the search result cannot disagree.
- Bun ≥ 1.4 for development and scripts.
- Node ≥ 22 for the
scripts/helpers that run outside Bun.
Astro (static output) + TypeScript, Preact for the interactive islands, Tailwind
CSS v4 with the CSS-variable tokens in src/styles/tokens.css, Vitest for unit
tests. Content pages are prerendered HTML; only the typing area and the settings
drawer ship JavaScript. There is no backend.
Nothing is fetched from a third-party server at runtime: the fonts are
self-hosted and there is no analytics or advertising script. Astro's build-time
telemetry is disabled in CI with ASTRO_TELEMETRY_DISABLED=1, and can be disabled
locally the same way (or with bunx astro telemetry disable).
bun install
bun run devThe dev server binds to 0.0.0.0 and reads PORT from the environment
(falling back to 4321), so the hosted preview keeps working.
Other scripts:
| Command | What it does |
|---|---|
bun run dev |
Dev server |
bun run build |
Production build to dist/ |
bun run preview |
Serve the built output |
bun run typecheck |
tsc -b --noEmit |
bun run test |
Unit tests (Vitest) |
bun run test:scripts |
Unit tests for the scripts/ helpers |
bun run test:a11y |
axe over every page in dist/ (run it after bun run build) |
bun run check:attribution |
Authorship guard: tracked files + commit messages |
node scripts/generate-og.mjs |
Regenerate the per-page social cards in dist/ (the build runs it for you) |
bun run validate:text |
Content validator: characters, encodings, review flags |
bun run build:dictionary |
Rebuild the word list built-in mode consults (public/dictionary/bn.txt) |
bun run check:dictionary |
Fail when that file is out of date against the grammar (CI runs it) |
Pages: / (practice), /lessons (the twelve-lesson path, one page per lesson),
/game (the arcade mode), /progress (history and data), /keyboard (input
modes and the cheat sheet), /guides and /guide/<slug>, /faq, /about,
/privacy. Every page has an English mirror under /en/, and every built page
gets its own 1200x630 social card with its title on it.
bun run test # engine, metrics, storage, the app's own logic
bun run test:scripts # the attribution guard, the OG generator, the service worker
bun run typecheck
bun run build && bun run test:a11y # axe over every built pagePure logic (the typing engine, metrics, cluster splitting, storage, the game
rules, preset links, the share card) is unit tested. Tests are written together
with the code, not afterwards. Accessibility is not a promise here but a gate:
bun run test:a11y reads the built HTML and fails on an axe violation, and CI
runs it after the build.
The repository enforces authorship rules locally. Enable the hook once per clone:
git config core.hooksPath .githooks.githooks/commit-msg rejects a commit message that contains attribution
patterns, and CI runs the same check (scripts/check-attribution.mjs) over the
changed range and over every tracked file. docs/MASTERPLAN.md and the guard
script itself are the only files excluded from the file scan.
docs/MASTERPLAN.md— the plan. Read this before changing anything.docs/PROGRESS.md— the roadmap checklist, ticked phase by phase.docs/DECISIONS.md— every deviation from the plan and every non-obvious choice.docs/VERIFY.md— open questions that need a native Bangla speaker.
Contributions of reviewed practice texts, translations and test cases for the typing engine are welcome. Every text needs a native-speaker review before it ships, and every rule of pure logic needs a test. Start with CONTRIBUTING.md — it walks through the setup, the gates and the house rules. Bug reports and feature ideas go through the issue templates.
By participating you agree to the Code of Conduct. Security issues go through SECURITY.md's private channel, never a public issue.
src/engine/input/phonetic-rules.json is this project's own grammar for the
well-known Avro phonetic conventions. It is not copied from an existing
implementation: the reference implementations are GPL-3.0, MPL, or state no
licence at all, so none of them can be relicensed under MIT. Every row records
where it came from in the file's own meta.sources, and a row is only marked
nativeReviewed: true once a human has checked it against a real keyboard.
Built-in mode therefore ships as an opt-in preview, not the default. The full
licence analysis is in docs/DECISIONS.md.
A rule table can spell Bangla but cannot know which spellings are words — the one
thing the reference implementation's own ~150,000-word dictionary does better. So
built-in mode has a word list too, and it is not copied from anyone's:
content/dictionary/bn_BD.dic is the LibreOffice Bengali spell-check dictionary,
vendored verbatim at a pinned revision with its licence, and
bun run build:dictionary derives the index the engine reads. Only corrections
ship, which is why the index is 11,221 spellings rather than 90,000: a spelling
whose rule output is already a real word is left alone, because preferring the
other word would be a guess with no frequency data behind it. The app's own lesson
and practice words are folded in as words at build time, so a correction can never
make a target impossible to type.
The list is fetched on demand and cached by the service worker, so built-in mode
works offline after one visit and system-keyboard users never download it.
content/dictionary/NOTICE.md records its provenance, its GPL-2.0-only
licence (the rest of the project is MIT), and how to remove it — the engine falls
back to its rules.
One row exists for a different reason: the period key types the danda (।).
Nothing in the published guide documents that, but a Roman keyboard cannot
produce the character any other way, and it appears in half the practice texts,
the punctuation funbox and the numbers lesson — without the row those runs could
not be finished in built-in mode. It is marked unsourced and listed in
docs/VERIFY.md like every other rule a native speaker has still to confirm.
- Code: MIT — see
LICENSE. - Lesson and practice text: original content of this project, released under CC0
(
content/), unless a file states otherwise. - The phonetic grammar: original to this project, MIT, like the rest of the code.
- The word list (
content/dictionary/,public/dictionary/bn.txt): the LibreOfficebn_BDBengali spell-check dictionary and the index derived from it, GPL-2.0-only. It is vendored data rather than code;content/dictionary/NOTICE.mdrecords the exact revision, the provenance and how to remove it.
Built with care by Afterclass Studio — © 2026 Afterclass Studio
