The first commit was on 14 September 2026. Version 0.46.0 came on the 17th. Sixty-four releases in four days, for a kernel of about four thousand lines with exactly one runtime dependency — an icon set, which the kernel itself doesn't import.
That pace is worth explaining, because it isn't about typing quickly. It's what happens when the substrate does the boring parts and the argument is the work.
eta is one process and one file. Bun makes that unremarkable rather than clever.
The database is bun:sqlite, built into the runtime — no driver, no pool, no container to start. The server is Bun.serve, which takes the routes, the static files and the WebSocket upgrade in one place, so there is no framework between a request and the code that answers it. HTML is imported directly, so there is no bundler and no build step; the page is a file the server knows how to serve. Tests are bun test, with a config that fails the run below 100% coverage.
Put together, the things that normally have to be assembled before any real work begins — a database, a server, a bundler, a test runner, a coverage gate — are the runtime. The first day got a server, sessions in SQLite and a working chat, because none of that day was spent on setup.
It matters more than it sounds. The reason eta can claim no queue, no cache and no build step isn't restraint; it's that Bun made those the easy option rather than the austere one.
Every feature starts as a story: a person's intent, in a sentence a customer could call true or false. Not "the drawer opens" — Ada adds a course to the menu, and the couple see it. The rule in the repo is blunt about why: a story describing what the interface does, rather than what a person wants, is the sign that a feature was invented first and justified afterwards.
Each one names who acts and who then sees it — and the last kind matters as much as the first. A story that must fail is how a refusal gets tested, rather than assumed.
The other half is a file of things not to break — Bun only, never node; the server is the only renderer; a write names a document and a path, never a function; the kernel never imports an example. That file is the contract I hand to Claude at the start of every session, and it is the reason a model can move at that speed without quietly inventing an architecture of its own.
So the loop is: tell the story, watch it fail, build the least that passes, cut a release. Sixty-four times.
This is the part I'd rather people knew about than the pace.
Working with Claude is not dictation, and it is at its most useful when it isn't agreeable. On 17 September I asked for a deep review from first principles — no code, just two questions: does eta deliver what its README promises, and is it using Bun well?
It came back with grades. DRY: code C+, docs F. KISS: C−. YAGNI: D, measured against the project's own stated rule. Bun: B+, with the note that the platform being under-used wasn't the server but the browser.
It was right, and it was specific in the way that leaves nowhere to hide:
The next three releases were almost entirely deletions. The stories now check what each person was sent. Six implementations of "write" became one, and four hand-written ways of announcing a change became one. Seventeen of the wedding's sixty-three stories went, and eight of the ticker's, because they only described the interface moving and could not fail. The reference document went from 4,700 words to 1,700.
One of the deleted stories is my favourite thing in the repository. Grace claims the kettle from its drawer; the couple see it claimed. It was false — and it passed.
That is what the squabbling is for. Not a second pair of hands: a reader who has no investment in yesterday's decision, will grade the work against the standard I set rather than the one I'd drifted to, and doesn't mind saying D.
I don't take every finding. Some proposals in that review are still open, and one or two I think are wrong. But the argument is where the design happens, and the record of it — the requests, the reviews, what was asked of the kernel and by which example — is kept in the repository beside the code, because in a year the reasoning will be worth more than the diff.
eta runs three examples: a chat room, a wedding site with a figure builder and a live photograph of everyone coming, and a price board with a Swiss railway clock. They exist to ask things of the kernel; the kernel knows nothing about any of them.
It is for small teams and solo builders making live apps where reversibility and legibility matter more than scale. A wedding. A booking board. A classroom. An ops console.
It is four days old.