Local-first is not a luxury
The applications behind RingScript run in a bank in Niger, a high school, a restaurant in France. What building for places where the connection is a guest — not a given — teaches about how software should be made.
Writing from the work itself — no filler. Three kinds of posts: where this project is going and why, how to build things with it today, and the decisions underneath, with links into the real source and the design documents they came from. Two of them run live Ring inside the page you are reading.
Looking for the release notes? Dated entries for everything that has landed — the runtime, the performance work, the applications, the fixes sent upstream — live on What’s new.
Vision & direction
Why this software exists, and for whom.
The applications behind RingScript run in a bank in Niger, a high school, a restaurant in France. What building for places where the connection is a guest — not a given — teaches about how software should be made.
For app programmers
Practical, tested, copy-paste-able. The fastest path to building well with Ring in the browser.
During a real field trial in France, a faulty refrigerator kept tripping the breaker — and hours of work vanished behind a changed network address, because browsers bind storage to the origin. The whole journey: the evening, seven laws paid for in the field, the library that carries them, the harness that severs real sockets, and a 70-line tutorial app you can break on purpose.
field notes · a failure is only expensive once if you capture itThree libraries, one registry, and every piece consumed by a shipped sample before its tag settled. The outbox learned partition tolerance from a real restaurant outage; money learned that doubles are not an accounting policy — 19% of 137 750 F is now 26 173 F by a rule, not 26 172.4999… by luck.
pwa 2.0 · table · money — publish, consume, then let the tag restA working field-sales application with every business rule — price tiers, discounts, tax, stock, the credit limit — running in Ring on the device, and the server used exactly twice. Includes the two HTTP endpoints it needs, in whatever language your back end already uses.
with a working application you can cut the connection onTwo samples had written the same outbox from scratch, so we built a registry, a package manager and a first library — separate from Ring’s, because a RingScript user has no Ring installed. The plumbing took a day. Then installing it into a second application found a duplicate send the first had hidden, and a third forced the API to change shape.
a registry is a file; the second user is the ecosystemLocal-first says the rules live on the device — but if the app is a web page, the device does not really have it. A PWA closes that hole: a manifest, a service worker that caches the 397 KB Ring runtime itself, and Background Sync that pushes finished work even when the app is closed. Under half a megabyte, cached once.
stop the server, reload, and it still opensEach rule was learned by getting it wrong first, and each has a measurement behind it. Together they took a 20,000-record page from sluggish to instant.
with a live example you can edit and runFiles, directories, processes: the practical map of what a Ring program loses inside a page, exactly how each loss behaves, the two traps worth knowing before they bite, and how to ship your own Ring library into the browser unchanged.
with a live example you can edit and runDeep technical
How the runtime actually works, and how it is held correct. For readers who want the source, not the summary.
The same scenarios through two other C interpreters compiled to WebAssembly. Robustness parity is the headline; Ring wins four rows of nine, including JSON encode ahead of QuickJS's native codec. Every loss is published with its cause — and those causes became the work list that produced the wins.
There was already a working Emscripten build. Replacing it was decided in half a day, from five greps over the vendored C rather than from taste — and the evidence was not unanimous. What replaced each Emscripten convenience, the fallback that was never needed, and what the choice cost.
A real app, driven like a user, found two O(n²) behaviours in the Ring VM's list machinery within minutes — invisible to every benchmark we had. The diagnosis, the fixes, and the safety net that made touching the VM's most-used code path safe.