An EPUB reader for people learning Japanese.
YomuKey turns a plain EPUB into something you can study from. Click any word and you get its reading, meaning, and how often it appears. Words are colored by difficulty. Furigana and vertical (縦書き) writing work out of the box. An AI assistant explains grammar. Your progress saves itself.
🔗 https://yomu-key.vercel.app/
Everything runs in your browser. Your books and reading data never leave your machine.
Live app: https://yomu-key.vercel.app/
- Click any word: get the reading, meaning, examples, and frequency.
- Difficulty colors: five levels color words: normal, green (to study), red (rare).
- Japanese-first reading: furigana (with a hide option), vertical writing, and 11 Japanese fonts.
- Progress that saves: chapters and scroll position are saved and restored.
- Word panels: an outline with chapter stats and a list of words worth studying.
- AI grammar help: get a word-by-word explanation of any phrase.
- Flexible layouts: continuous scroll, page-by-page, or a visual-novel view.
- No servers: no accounts, no uploads. Books are stored in your browser.
npm install
npm run devOpen http://localhost:3000, then:
- Import an EPUB: drop a
.epubfile (up to 100 MB) on the Library page. - Open a book: click a book. You start where you left off.
- Click any word: you get the reading, meaning, and frequency.
- Adjust difficulty & formatting: use the
Aatoolbar, Focus mode, and Settings. - Track progress: your speed, time, and progress save automatically.
Want a full tour of every page? Open the in-app manual at
/docs(Docs button on the Library and Reader pages).
| Page | Route | What it does |
|---|---|---|
| Library | / |
Import EPUBs and open your books |
| Reader | /reader/[id] |
The reading screen |
| Settings | /settings |
All reader options, auto-saved |
| Text Analyser | /text-analyser |
Analyze text you paste |
| Manual | /docs |
User guide + developer reference |
| Area | Technology |
|---|---|
| Framework | Next.js 15 (App Router) |
| UI | React 19, Tailwind CSS v4, Flowbite React, shadcn/ui |
| Fonts | Inter, Geist, Noto Sans JP, Noto Serif JP, and more |
| Unzipping | JSZip (in-browser) |
| Japanese tokenization | TinySegmenter (Web Worker) |
| Persistence | IndexedDB, localStorage, sessionStorage |
| AI grammar | OpenRouter LLM via /api/grammar |
| Testing | Vitest + jsdom |
UI Library │ Reader │ Settings │ Text Analyser
Contexts Dictionary │ Level │ Reader Settings
Services EPUB Parser │ Tokenizer │ Dictionary │ AI Grammar
Storage IndexedDB │ localStorage │ sessionStorage
Import: the EPUB is unzipped with JSZip. The parser reads container.xml and the OPF manifest to pull out text, stylesheets, images, and the table of contents. The HTML is cleaned, image paths are swapped for placeholders, and the result is tokenized and saved to IndexedDB.
Reading: the Reader loads the saved content, builds the active chapter, wraps every word in a span with a frequency color, and renders it with EpubRenderer. The book's own CSS stays intact.
YomuKey needs no server for reading:
- Books live in IndexedDB in your browser (
yomukey-epubsfor library/content,yomukey-coversfor covers). - Settings live in
localStorage, scroll positions insessionStorage. - The only network calls are the bundled frequency dictionary and the optional AI grammar endpoint (below).
| Variable | Required | Purpose |
|---|---|---|
OPENROUTER_API_KEY |
Optional | Turns on Grammar Check / Ask YomuKey AI |
Copy .env.example to .env.local and add your key to enable AI grammar explanations.
src/
app/ Routes: dashboard, reader, settings, text-analyser, docs
components/ UI: EpubRenderer, UploadEpub, Library, panels, tools...
lib/ DictionaryContext, LevelContext, SettingsContext, tokenizers
actions/ handleEpubUpload, dictionaryLoader
app/api/ /api/dictionary, /api/grammar
services/ IndexedDB storage layer (epubs, covers)
public/ Patterns, fonts, tokenizer workers, dictionary data
src/__tests__/ Vitest suites
npm run dev # start the dev server
npm test # run Vitest test suites
npm run test:watch # watch mode
npm run build # production build
npm run start # run the production buildTests live in src/__tests__/ and cover the reader's core logic:
- domTokenizer: splitting words, colors, ruby
- epub-parser: importing a book
- imageResolver: image paths
- sanitizer: cleaning bad HTML
- styleProcessor: book CSS
YomuKey is open source. Fork it and make it yours. The code is easy to follow:
- Difficulty & colors: the five levels and their thresholds live in
src/lib/LevelContext.jsx. Tune them to your level. - Reader defaults: fonts, size, spacing, and view modes are in
src/lib/SettingsContext.jsx. - Visual theme: colors and design tokens are in
src/app/globals.css. The UI is all Tailwind classes. - Dictionary: swap
public/simplified_dictionary.jsonfor your own frequency data. - Fonts: add font families in the settings page to match how you like to read.
A fork runs locally with npm install && npm run dev. No backend, no accounts.
Contributions, ideas, and forks are welcome. Build something useful and share it.
- The Text Analyser is the older plain-text tool. The Reader is the main way to study.
AppSidebaris unused legacy code.
Made with care for Japanese learners.