A single-learner web app that teaches Python from "what is a variable?" to advanced practical Python. Real CPython runs in your browser (Pyodide in a Web Worker), including a genuinely blocking input().
It is not a quiz app, not a coding-interview site and not an AI tutor. The app decides the order; every lesson teaches one idea, then lets you use it: see it, type it, understand it, modify it, predict it, complete it, create it, reuse it.
- 18 units, 266 lessons, about 1,970 steps, 247 concepts, 202 named pitfalls
- Guided progression plus a free Playground, Review (spaced practice), Mastery map, achievements, XP, levels and streaks
- Friendly error explanations first, the raw traceback always one click away; your code is never erased by a failure
- Everything is stored in your browser (
localStorage); there is no account and no server state
You need Node.js 20 or newer (24 is what it was built with) and Python 3 (only for npm run content:verify; the app itself runs Python in your browser).
git clone https://github.com/staraepp/hatch-python.git
cd hatch-python
npm install
npm run dev # syncs Pyodide, compiles the curriculum, serves http://localhost:2034The curriculum build is strict: it fails while any unit is unfinished. While authoring use HATCH_PREVIEW=1 npm run content && npx next dev -p 2034, which leaves out units whose lessons are not all written.
Python code runs through SharedArrayBuffer, so the app is served with cross-origin isolation headers (set in next.config.ts). Use a current Chromium, Firefox or Safari. asyncio.run in the live editor needs JSPI (Chromium); without it Hatch rewrites the usual top-level asyncio.run(main()) into an await so lessons still run, but hidden checks that call asyncio.run themselves are not supported there.
| Command | What it does |
|---|---|
npm run content |
Compile content/ into public/curriculum/ and src/generated/outline.json |
npm run content:check |
Validate schema, concept graph, prerequisite leaks, terminology, feature ownership, XP |
npm run content:verify |
Run every reference solution (must pass) and every invalid/starter sample (must fail) through the real checker |
npm run typecheck / npm run lint |
tsc --noEmit and ESLint |
npm test |
Vitest: engine, persistence, feedback, error explanations, secondary pages |
npm run test:e2e |
Playwright flows against the real UI |
HATCH_E2E_UNITS=u01,u02 npx playwright test walkthrough |
Plays whole lessons through the UI with their reference solutions |
Add HATCH_PARTIAL=1 ... --only u11 to the content scripts to work on one unit.
- Next.js 16 (App Router), React 19, strict TypeScript, Tailwind v4, zustand, zod, CodeMirror 6, Motion.
- One Python implementation.
python/hatch/runs, checks and analyses code. The browser loads it into Pyodide (public/hatch-worker.js); Node uses it throughpython3 -m hatch.clifor content verification. Nothing is re-implemented in TypeScript. - Behavioural validation, never source matching. A check runs the learner's program with scripted stdin, files, mocks and fixtures, then compares stdout/stderr/values, and applies AST rules (feature, call, function, class, import) to the entry file. Hidden fixtures can probe multi-file projects and run the learner's own tests against deliberately broken implementations.
- Content is data.
content/units/<unit>/unit.yamldeclares the concept graph, features, terms and pitfalls; each lesson is one YAML file. Seecontent/AUTHORING.md. - Mastery is evidence-based. Reading never raises mastery; passing exercises, predictions and reviews does. XP is idempotent per source.
- Details for contributors and other coding agents:
AGENTS.md(conventions) andHANDOFF.md(current state, known limits, next steps).
Python in the browser cannot open real network connections, spawn processes or threads, or read your files. Lessons about those topics (threads, processes, real downloads, virtual environments) say so plainly and use simulated or explained examples instead of faking them.