kanabr is a typing tutor focused on Japanese kana (hiragana + katakana), powered by an adaptive lesson engine: it tracks per-kana statistics, generates practice text that targets your weakest kana, and visualizes long-term progress.
This repo is designed to run as a static SPA: no server required, no
cloud database required. You can deploy it to Vercel / GitHub Pages / any
static hosting, as long as the host can serve index.html (or the generated
404.html) as the fallback for client-side routes.
In static mode, user progress is stored locally in the browser (IndexedDB / localStorage). That means:
- Switching browsers/devices (or clearing site data) loses progress unless you export it
- Server-backed features are unavailable (accounts/login, public profiles, high scores, multiplayer)
If you need server features, you can still run server mode (see below).
npm installBuild the static output (written to vercel-dist/):
npm run build-staticPreview locally (pick one):
npx serve -s vercel-dist
# or
python3 -m http.server 3000 -d vercel-distThen open the URL shown in your terminal.
npm run build-static writes index.html, a 404.html SPA fallback, and
directory entrypoints for each page and supported locale. Direct links and
refreshes work on static hosts without rewrite rules.
The GitHub Pages site is built and
deployed by .github/workflows/pages.yml on pushes to master. The workflow
can also be run manually from the Actions tab. In repository Settings →
Pages, select GitHub Actions as the publishing source.
The workflow obtains the site's base URL from GitHub Pages and uses it for
assets, client-side routes, and language switching. Repository subpaths such
as /kanabr/ and custom domains at / are supported.
To build the same output locally:
KEYBR_BASE_URL=https://l-m-sherlock.github.io/kanabr/ npm run build-staticPublish only vercel-dist/. For a local preview of this subpath build, serve
that directory at /kanabr/. Vercel Analytics is enabled only when building
in Vercel (VERCEL=1).
Recommended Vercel settings:
- Build Command:
npm run build-vercel - Output Directory:
vercel-dist
Optional build-time env vars:
KEYBR_BASE_URL(default:http://localhost:3000/)KEYBR_LOCALE(default:en)KEYBR_COLOR(default:system)KEYBR_FONT(default:open-sans)
In static mode, go to Profile:
- Export data: exports local data (history + settings + preferences + theme) to
kanabr-local-data.json - Import data: imports a JSON file and overwrites current local data (supports
kanabr-local-data.json, legacykeybr-local-data.json, and legacytyping-data.json) - Reset local data: clears all local data and resets to defaults
- Open the Practice page and click the settings button (gear icon).
- Go to Keyboard:
Language→ JapaneseLayout→ Japanese Romaji (layout id:ja-romaji)
- Go to Lessons (Guided lesson):
- Optional: enable Balance kana frequency
- Hiragana is unlocked first; katakana is unlocked later as a separate practice block.
- (Optional) In Keyboard, toggle Show romaji helper if you want to see suggested romaji spellings for the next kana.
Development build (webpack, NODE_ENV=development):
npm run build-devWatch mode:
npm run watchIf you want accounts/login, public profiles, high scores, or multiplayer, you need to run the server.
The easiest setup uses sqlite (no MySQL required):
cp .env.example .env
./packages/devenv/lib/initdb.ts
npm start
.env.exampledefaults toDATABASE_CLIENT=sqliteand usesDATABASE_FILENAME.
Server-only integrations such as OAuth, email, ads, Paddle checkout, and custom analytics must be enabled explicitly through environment variables.
npm run test- Bugs / features: issues and PRs are welcome
- Translations: see
docs/translations.md
kanabr is based on the original keybr.com project by aradzie:
https://github.com/aradzie/keybr.com.
Released under the GNU Affero General Public License v3.0.

