Turn a folder of JSON into an installable, offline-first practice app. The mill that grinds questions into knowledge.
quizmill
以下摘录自该仓库的 README(片段) · 在 GitHub 读完整 README →
**The mill that grinds questions into knowledge.**
Quizmill is an open-source practice-app engine. You bring (or have your
AI agent write) a **learning pack** — a small directory of JSON
describing a question bank — and quizmill turns it into a fast,
installable, offline-first practice app for that topic: practice
sessions biased toward unseen questions, a mistakes queue that re-asks
what you got wrong until you get it right, per-question feedback, and
optional cross-device sync.
Like a mill, it works by going around: answer, review, retry. The
engine is the wheel; packs are the grist.
Quick start
You don't clone this repo to use quizmill — you run it with npx. The
CLI keeps the engine in ~/.quizmill/engine for you and shells out to
it, so a pack is all you ever edit. Requires Node ≥ 26, git and npm.
| Command | What |
|---|---|
| new [dir] | scaffold a learning pack with an agent-ready README |
| validate | schema + cross-reference checks (agents loop on this) |
| run [dir\|owner/repo] | activate a pack and start the app |
| build [dir\|owner/repo] | emit a deployable static app in -app/ |
| bundle [--out file] | validate + write one .bundle.json to hand over (see Share a pack as one file) |
| list | published packs you can install |
| upgrade | re-align the cached engine (see Upgrading) |
Install a published pack
Packs can live in their own GitHub repos. run and build accept a
repo reference and install it straight from there — public repos
anonymously, private repos through your own git clone credentials:
| Pack | What | |
|---|---|---|
| pack-claude-cert | Unofficial Claude Certified Architect (Foundations) practice — 635 questions across the five exam domains, curated from MIT-licensed community banks with per-question attribution | public |
| your-name/your-pack | Private repos install exactly the same way (family packs, exam prep, team material) — anyone whose git clone works can run it | private |
owner/repo, owner/repo#branch, full GitHub URLs and SSH remotes all
work.
Build a pack about anything
The intended authoring path is your local AI agent. With
Claude Code, the bundled
create-learning-pack skill means you can just say:
> "Make me a learning pack about Kubernetes networking"
and the agent will scope it with you, write the pack, loop on the
validator until it's clean, activate it, and start the app.
Manual authoring works the same way — scaffold, edit, validate, run:
Packs are **private by default** — they live wherever you put them and
never enter this repo. Only the demo pack ships with the engine.
Publish a pack
A pack repo is just the pack directory pushed to GitHub — pack.json,
questions.json, optional scenarios.json / concepts.json / assets/,
plus a README (see pack-claude-cert
for the shape). Once pushed, anyone can install it:
Keep it private and it still works for everyone with repo access. If
the pack is public and you want it listed in npx quizmill list, PR an
entry into tools/pack/registry.json.
If your questions build on someone else's bank, keep the upstream
license, record provenance in each question's sourceRef (the app
links to it in the answer panel), and reproduce upstream notices —
again, pack-claude-cert is the worked example.
Share a pack as one file
Not every pack wants to be a git repo. bundle validates a pack and
writes it as a single .json — the pack files verbatim, plus every
image from assets/ embedded as a data URL, plus schemaVersion, the
pack id, a bundledAt stamp and (in a git checkout) the pack's
revision:
Any quizmill app inserts the file at /packs (pick it, or paste a URL
it's hosted at) — no CLI needed on the receiving end, and the pack
works offline there because its images travel inside the file. Browsers
keep an inserted pack in about 5 MiB of storage, so the bundler warns
when the images push a bundle past 4 MiB.