Everything bundled
Lessons, exercises, quizzes, cheatsheets, a glossary, the embedded book chapters and a small library of PDFs all ship inside the app.
Seventy-eight lessons and ninety-one deliberately broken programs. The learner predicts what the compiler will say, runs it, reads the real error, and fixes it. There is no account, no cloud and no assistant; it works with the network off.
Install on Android
A beginner who is handed the fix learns that the fix existed. A beginner who reads the compiler's own words and works out what they mean learns to read compiler errors, which is most of what learning this language is. So the help is built as a ladder that deliberately stops short: one rung per attempt, climbing from the concept, to the error code to expect, to the chapter of the book that teaches it.
It never reaches the fix, and this is not enforced by good intentions in the interface. The server does not send the solution to the browser at all, and a browser test exists whose entire job is to assert that the answer never leaks to the client. If someone later wires the solution into a response, that test goes red.
Every exercise declares the exact compiler error it is built to teach. A change that makes a broken program compile has destroyed the lesson while leaving a perfectly green build — unless the curriculum is a test suite.
This is the part I would show another engineer. Each exercise carries a declaration of the diagnostic it teaches — a specific error code, or a runtime panic — and a script compiles all ninety-one of them with the actual Rust compiler, running (not merely building) the ones that are supposed to panic, and asserts the declared outcome really appears.
There is no test framework for the assertion "this program must fail, in this specific way". It has to be built, and it is worth building, because two things rot a curriculum silently: a well-meaning edit that fixes a program which was supposed to stay broken, and a new compiler release that renames or merges an error code, which can invalidate a lesson without anyone touching it.
$ scripts/verify-exercises.sh
EXERCISES OK (91 verified)
# # every declared error code still appears, on this compiler version
The lessons, the exercise state, the hint ladder and the spaced-repetition queue live in one Rust core, and everything else is a surface over it: a local web app, a terminal app, a command-line tool, and an Android build. They share one progress file, kept in plain text under the learner's home directory, so a learner can put their own progress under version control if they want to.
The Android app is the same engine rather than a reimplementation of it. A thin native shell hosts the same interface, and a small Rust library — cross-compiled for all four phone architectures from the very same crates as the desktop — answers fourteen calls that stand in for what the desktop's web server would do. That is why the hints and the recall queue behave identically on a phone instead of drifting apart over a year of separate bug fixes.
Lessons, exercises, quizzes, cheatsheets, a glossary, the embedded book chapters and a small library of PDFs all ship inside the app.
With a companion terminal app installed, the phone compiles and runs the learner's Rust on its own processor. Without it, the app says so and stays fully usable as a read-and-predict course rather than appearing broken.
Only one crate is permitted to mention the Rust toolchain at all; a build gate fails if a compiler-specific name leaks out of it, which is what would let a second language be added without unpicking the engine.
The Android app is published and installable today — sideloaded, not from a store, and debug-signed. The desktop version is source you build yourself: it runs, its one hundred and eighty-two tests pass with no compiler warnings, and it has never been packaged for download. Calling that finished would be a stretch; calling it real is fair.