Personal projects Case study

Free JLPT practice, in the real format

A study site for Japanese learners living in Japan — 118 timed, automatically marked papers from N5 to N1, every one written for the site, with an interface in twelve languages.

Role
Solo — design, engineering, content tooling
Type
Personal product
Surface
Exam player · study lists · guides
Status
Live at nihongomock.com

The problem

The JLPT is not a set of loose questions. It is a timed paper with a fixed shape — 問題 groups in a set order, reading passages that several questions share, and listening sections played once. Practice that doesn't look like that paper trains the knowledge but not the sitting.

The site is written for learners who are already living in Japan, many of them from Nepal, Vietnam and China. A study tool that only speaks English or Japanese reaches few of them, so the interface had to be in their languages from the start. And official past papers are not free to republish, so every paper had to be written.

What it does

Each paper opens as one continuous page, like the printed booklet: questions grouped under their 問題 instruction, reading passages pinned beside the questions that use them, one player per listening section, and a question map for moving around. Submitting marks the same page in place and gives an estimated scaled score with a section breakdown.

Every paper carries furigana on a toggle, a meaning for every word in it, and a script for every listening question. All 118 can be sat end to end, sound and all: the listening is read aloud by the reader's own device, so a paper works with the connection off. There is no account and no backend — progress stays in the reader's own browser.

Architecture

There is no server, so the build is the backend. Python tools turn two kinds of source — item banks of hand-written questions, and open dictionary data — into a fully static site: more than 1,700 pages across twelve language trees, each tied to the others with hreflang, plus the JSON the exam player reads. Vercel serves the result as files, and nothing on a page is fetched from anywhere else.

Item banks hand-written questions · dealt by rule JMdict + JLPT lists word meanings · readings Build · Python · runs locally, no server Static generator papers · glossaries · furigana 12 language trees · hreflang · sitemap deploy · answer banks stay behind Vercel 1,700+ static pages · no backend Browser exam player · 12-language interface listening read by the device · progress kept locally

Every file is written at build time; a page makes no request to anyone but the site itself.

Decisions that shaped it

  • Papers are dealt, not typed. Questions live in item banks, and an assembler deals them into papers of the published shape — 67 questions at N5 up to 107 at N1. It shuffles the choices (the first hand-written paper had all 21 answers in position one), refuses to repeat a question anywhere in the library, and records the deal so that adding to a bank never disturbs a paper that already exists.
  • A paper is never missing its audio. Every listening question carries its own script, and the device reads it aloud. No recording to host, nothing to lose, and the whole site keeps working offline once it is installed.
  • The answer key stays off the server. The banks store the right answer first, on purpose, so they can be checked by eye — which makes every bank an answer key. They are kept out of the deployment entirely, and only the shuffled, built papers are served.
  • Twelve languages, without pretending. The interface switches language in place with no reload, and every language has its own URL tree. Where a guide has no translation the build skips that language rather than serving English under a Nepali address, and the level pages stay English-only on purpose — a machine translation would not be the better answer they exist to be.
  • Numbers that cannot drift. The counts on the home page — papers per level, questions, words — are generated from the data at build time rather than written by hand.

Outcome

118

Timed papers, N5 to N1

11,433

Questions, auto-marked

12

Interface languages

0

Sign-ups or backend

The site is live and free, with nothing to sign up for. Every paper has a glossary — 18,201 different words with their reading, level and meaning — and alongside the papers sit 9,638 vocabulary entries, 2,211 kanji with stroke order and 280 grammar points, levelled from N5 to N1, with 1,753 entries in Nepali.

Stack

Front end

HTML · CSS · vanilla JavaScript · Web Speech · service worker — no framework

Build

Python — static generator, item-bank assembler, JMdict glossary, furigana

Hosting

Vercel · IndexNow

Data

JSON exam files · localStorage for progress