Personal projects Case study

Free JLPT practice, in the real format

A study site for Japanese learners living in Japan — 207 timed, automatically marked papers from N5 to N1, laid out the way the exam is, 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.

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 audio 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 — 199 of the 207 can be sat end to end, sound and all. There is no account and no backend: progress and answers in progress stay in the reader's own browser.

Architecture

There is no server, so the build is the backend. Python tools turn three kinds of source — archived papers, item banks of original questions, and open dictionary data — into a fully static site: more than 3,000 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. The only things fetched at runtime are the listening recordings and a few exam diagrams.

Archived sittings 89 papers · parsed from source Item banks 118 original papers · 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 Vercel 3,000+ static pages · no backend Browser exam player · 12-language interface progress kept in localStorage web.archive.org exam diagrams Google Drive listening audio

Dashed lines are the only runtime requests; everything else is a file written at build time.

Decisions that shaped it

  • Never invent inside a real paper. Seven archived sittings lost their listening booklets. Writing questions to fill them would put invented material inside a paper labelled as a real exam, so the gaps stay — each of those papers names the sitting that has the booklet it is missing — and 118 original papers were written instead, where every listening question has a script the device can speak.
  • Papers are dealt, not typed. Original 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.
  • The papers are not for search engines. The archived questions are not the site's to republish, so papers are kept out of search results and anyone holding rights can have material removed within 72 hours. What search engines read is written separately: a page per level and nine guides that answer what learners actually type.
  • 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, which have listening, which have meanings — are generated from the data at build time rather than written by hand.

Outcome

207

Timed papers, N5 to N1

20,346

Questions, auto-marked

12

Interface languages

0

Sign-ups or backend

The site is live and free, with nothing to sign up for. Alongside the papers it carries 9,638 vocabulary entries, 2,211 kanji with stroke order and 280 grammar points, all levelled from N5 to N1 — and 1,753 words with meanings in Nepali.

Stack

Front end

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

Build

Python — static generator, exam parser, item-bank assembler, JMdict glossary

Hosting

Vercel · IndexNow

Data

JSON exam files · localStorage for progress