Children’s software became one of the most surveilled categories of software ever sold, and it happened quietly enough that most parents never noticed the trade, because the free typing game on the school portal and the free phonics app on the tablet are not free at all, they are telemetry endpoints with a cartoon mascot on the front, collecting session lengths, device identifiers, and behavioral profiles on an audience that cannot legally consent to any of it, and the occasional COPPA fine that makes the news is just the cost of doing business for the ones who got caught. We grew up in a different regime, where Mavis Beacon came in a cardboard box and the only things she knew about you were your words per minute and which lessons you had finished, all of it stored on the same disk as the program, and the interesting question for us was not how to build a typing game but whether that older deal, software that works and knows nothing, was still possible to ship in 2026 without it reading as nostalgia bait.

The answer turned out to be yes, and the reason is boring in the best way: a typing tutor for kids does not need a backend, it never did, and every architectural decision that would require one, accounts, cloud sync, leaderboards, parent dashboards, analytics, is a product decision wearing a technical costume. Strip those away and what remains is a lesson path, a scene, some sound, and a place to remember progress, and none of that needs anything more than a static file host and the browser’s own storage.

The game itself

SpiderTypes teaches home row the way the old tutors did, starting with the F and J bumps, working out through the rest of the home row, then spaces, punctuation, and full sentences, across a hundred levels that end in multi-paragraph kid-friendly stories rather than drill text. The on-screen keyboard is a deliberate nod to Mavis Beacon, highlighting the home row, the F/J bumps, and the current target key, because the visual anchor of “where do my fingers live” is the entire pedagogy at this age and nothing since has improved on it.

What we changed is the motivation layer, because a child will not grind through a hundred levels for a WPM number, so the lesson is wrapped in the Itsy Bitsy Spider story that every kid already knows: a Three.js baby spider climbs a slanted water spout as you type, correct keys carry her upward, mistakes make her slip, and most levels end the way the song says they end, with the rain washing her back down so she can climb again. Every twentieth level breaks the pattern with roof friends and fireworks, a small celebration beat to mark real progress, and a Tone.js music box rendition of the song starts on the first typed key and stops when the level ends, so the audio feedback loop is the melody itself rather than a generic ding.

None of this is technically exotic, and that is the point; the renderer is Three.js, the audio is Tone.js, the bundler is Vite, and the code is vanilla JavaScript with ES modules, no framework, no TypeScript, no codegen. The spider model is a GLB file bundled into the repo at public/models/spider.glb, not fetched from a CDN at runtime, which means the whole scene renders from files the server already sent.

localStorage as the entire data layer

The complete persistence story of this product fits in one line of the README, because progress lives in the browser under a single localStorage key, itsy-bitsy-spider-home-row:v1, holding unlocked levels and per-level best times, and the in-game level selection screen has a “Clear Saved Scores” button that wipes it. There is no migration path, no schema version negotiation beyond that :v1 suffix, no sync conflict resolution, and no account recovery flow, because there is no account to recover.

The runtime privacy table in the README reads almost like a parody of a modern privacy policy, and we keep it because every row is a thing the industry has normalized that we simply do not do: no runtime network requests of any kind, no analytics, no cookies, no accounts, no API calls, no remote assets, and not even a service worker, so the tab never keeps a background process around that could pick up a network habit in a later version. A parent can open the dev tools network tab, let the kid play for an hour, and watch it stay empty, which is a stronger guarantee than any policy document, because it is verifiable by inspection rather than by trust, and it holds from both directions, the network tab proving what the running game actually does while the source proves why, since the bundle simply contains no code path that builds a request. The old deal was “the box cannot phone home because there is no phone”; the modern equivalent is a bundle that never phones home by construction, and the second one is checkable in five minutes.

Deployment follows the same logic, since npm run build emits a plain dist/ directory that runs on any static host, including the family NAS or a Raspberry Pi in the closet, and the shipped game needs nothing at runtime except the files themselves. Self-hosting a kids’ game sounds absurd until you realize it is the only hosting model where the operator’s incentives are the parent’s incentives.

Honest scope and what it costs

The development notes say things most projects would be embarrassed to publish: no test suite, no linter, no typechecker, no CI, verification is manual, you run npm run dev, open the browser, and play the affected level. That is a real tradeoff and we are not going to dress it up, because a regression in level 40’s text goes unnoticed until a child finds it, and the correctness bar for a typing game is genuinely low enough that a human playthrough catches what a test would, but the discipline holds only because the surface area is tiny, four source files plus a hundred levels of data. The day this codebase grows a second contributor who does not have the whole game in their head, that policy gets revisited.

The harder limits are the ones we chose on purpose and will not revisit. Progress does not follow the child between devices, because sync means accounts and accounts mean identity data about minors, and no feature is worth that trade in this category. There is no teacher dashboard showing a classroom’s accuracy curves, because dashboards are analytics with a friendly name. There is no difficulty adaptation driven by a server-side model, because the model would need the keystrokes. Each of those is a product someone would pay for, and each of them converts the game from software into a service, and services want data the way water wants downhill.

The spaghetti-PHP era taught us something the industry keeps relearning the expensive way, which is that scope is the cheapest architecture there is: a thing that does one honest job, in files you can inspect, with state you can delete from a settings screen, is not a lesser version of the cloud product, it is the version you can actually verify. Mavis Beacon in her cardboard box worked exactly like that, and the kid at the keyboard in 2026 deserves the same deal, so that is the deal we shipped, GPL-3.0-only, source and all. And that’s it.