You can now rewrite Svelte in 54 hours. I checked.
54 hours of agents running, up to sixteen at once. 72,000 lines. 8,846 of Svelte's own tests passing. Not a single line written by me.
That's what it takes today to rewrite Svelte from scratch — a framework a strong team spent years building. It's not a fork and not a wrapper: brand-new TypeScript with no Svelte code in it, passing the tests written by the authors of Svelte, SvelteKit and the Vite plugin. Svelte's source was the reference. Its tests were the referee.
There's no secret prompt. No genius model either. Just agents that don't get tired, and a judge they didn't write.
Code is no longer the most valuable part of a project. Its tests are. Publish good tests, and you publish the recipe for your own clone.
And you still can't take an agent's word for it. Opus, who led the work, first estimated it at several weeks. Then, over those 54 hours, the agents told me "everything's green" more than once, with total confidence.
Sometimes it was true.
Midnight, just for fun
My product, Tagma, runs on Svelte. For a while I'd been carrying my own patch to Svelte's scheduler — the heart of the framework that decides what re-renders and when. Two hundred lines of patches, each one fixing a single case and never the cause. A little after midnight on October 29, Tagma's UI went down, and the patch didn't cover it.
At some point the question changed from "how do I fix this?" to "why am I living on someone else's scheduler at all?"
I handed the fix to one agent. With Claude Opus 5.5, which runs the big jobs for me, I started talking about something else. The idea was just for fun: fork Svelte, bring it back to TypeScript, throw out the legacy, and finally fix the bugs that have been sitting open for months.
Opus was against it, and didn't sugarcoat it:
Rewriting in TypeScript gives you the least and costs you the most.
It suggested forking one scheduler file and leaving everything else alone. I said we would never merge back from upstream. We're not chasing Svelte, we're going our own way. Opus thought about it and changed its mind: no merges means no permanent tax on porting someone else's fixes. The price is different: all the code is mine now, and Svelte's fixes won't flow in on their own anymore.
I wanted TypeScript because of the agents. Agents live by the type checker: a type error is the first check an agent gets for free, before any test runs.
To be fair, if the goal was a stable Svelte for my product, a fork would have been the smarter move. Opus said so: "For Tagma it's an illogical decision. As an experiment, it's fine." I wanted to know whether agents could carry a mature system all the way, and a fork doesn't answer that.
Then I asked how long it would take. "Several weeks of agent work. That's an estimate, I haven't measured it." The size didn't scare me. Opus was worried about something else, and rightly so:
The main risk of a rewrite is losing behavior. That behavior lives in upstream's tests.
That sentence became the plan.
We called the framework Vigla. In the Byzantine army, that was the name of a tagma — the guard. Tagma comes from the same place.
Svelte is just the front door
Rewriting Svelte one-to-one would have been boring. Vigla is built differently.
Vigla's core doesn't know the word "Svelte." Its package has zero imports of svelte, and an automated check keeps it that way. Svelte compatibility is a separate adapter on top of the core: swap the dependency, and your runes code works. But that's the entrance, not the point.
The point is a core built for whole applications, not just components. In Svelte, context only lives inside a component. In Vigla, owners, context, async resources and the scheduler work anywhere: in services, in server requests, in several apps on one page.
On the first day I asked Opus what paradigm the core was being built on. Its answer: "Half the problem is solved. The other half is repeating Svelte's path right now. The agents don't know, because that's what the specs say — and I wrote them." It wrote a rule on the spot and sent it to the three agents already working. Later I demanded proof that the core could carry any architecture on top of it. Opus read its own core from start to finish — more than four thousand lines — and came back with: "No, the core's design doesn't fully meet the goal yet." Plus five real gaps. All five got fixed, and now a ten-layer service graph runs on the public API, with no hacks.
And there's one scheduler. Async is always on, there's no other mode, and the scheduler's guarantees are written down as a contract. The class of bug that took Tagma down that night is now a test that has to pass.
The next entrance is TSX: the same core, runes right in TypeScript, no separate language. Svelte will stay as one way in.
A judge you can't bribe
Agents write code faster than you can read it: Tagma, my main product, is over a million lines written by agents. Writing a lot isn't the problem. The problem is knowing whether the code is right. "The agent says everything's green" doesn't count as an answer.
The judge was the Svelte team's own test suite — years of edge cases, old bugs and decisions nobody remembers anymore. Compiler and runtime samples, SvelteKit's test apps, the Vite plugin's specs, frozen at Svelte 5.57.3, SvelteKit 3.1.0 and vite-plugin-svelte 7.3.1. With fixtures, that's 177,000 lines of tests — more than twice the code the agents ended up writing. The agents read Svelte's source as a reference, but whether they got it right was up to the tests.
There were three rules.
Check the judge first. Before the first line of new code, we ran our test runner against real Svelte. It had to agree with the authors' own runner — and it did: on the runtime-runes suite, both passed the same 2,346 tests. The Svelte team wrote the expectations, but the runner was ours, and we checked it as hard as we checked the agents.
Every test is accounted for. Every test has a status and a reason: passes as is, rewritten against the public API with the same expectations, replaced by our own test of the same behavior, intentionally changed, or dropped along with the old syntax. A test without a status fails the run. Each variant — dom, hydrate, ssr — counts as a separate test, the same way Svelte counts them. Of SvelteKit's 1,108 unit tests, 1,025 poke at internals, so we replaced them with our own, and every replacement has a reason in the manifest. The apps are the real judge: of the 869 SvelteKit app tests in scope, 866 are green, and the other three, per the record, aren't supposed to pass anywhere.
No going back. Once a test passes, it gets recorded and has to pass forever. An agent can say everything's fine as confidently as it likes — the ratchet won't let it slip back. And you can't quietly delete a line from the list: it shows up in the diff.
Here's how Svelte's tests break down. The manifest counts tests; each test runs in one or more variants — dom, hydrate and ssr in Svelte, dev and build in SvelteKit — and those variants add up to the 8,846.
| Svelte | SvelteKit | Vite plugin | |
|---|---|---|---|
| Run as is | 1,969 | 976 | 68 |
| Rewritten against the public API | 380 | 55 | 55 |
| Replaced by our own test | 88 | 1,153 | 27 |
| Changed on purpose | 11 | 37 | 1 |
| Dropped with the old syntax | 166 | 0 | 2 |
Don't take my word for it — here's the CI run: 9,076 tests green on Linux, 8,846 of them Svelte's and 230 ours.
After that, the agents did what they do best: kept working until the judge said yes.
The first day
Around 6 a.m., the first two agents started — and neither of them was writing the framework. One was building the judge, the other was going through Svelte's open bugs. By midday, four more had joined.
At 2:25 p.m. I looked at the numbers — 35,000 lines, thousands of Svelte tests passing — and couldn't believe it: "So we wrote our own framework in a day?"
Opus corrected me: "Partly. In a day we rewrote almost all of Svelte's compiler and most of the runtime, but not the whole framework. The first commit in the repo was today at 3:38 a.m."
Pedantic, but right. SvelteKit was still ahead, and it turned out to be the biggest part of the job.
That part was my call. When Opus suggested starting with the client and putting off server rendering, I said Svelte without SvelteKit is useless to everyone, us included. It agreed: "You're right." SvelteKit turned out to be 869 app tests run in about four thousand variants, plus most of the known bugs. Put it off, and the quick win of day one would have hidden half the job.
Twice as much fixing as writing
On the first day, the agents made 58 commits with new features and 19 fixes. On November 2: seven new and ninety fixes. On the morning of November 3, a second full SvelteKit run added more than three thousand passing tests to the record at once, and by evening the set reached 9,076.
Writing a lot of code fast turned out to be just the start. The real work came after: making the code agree with someone else's tests, one edge case at a time.
As a separate job, the agents went through 172 open bugs in Svelte, SvelteKit and the Vite plugin. 51 are fixed — each with a test that fails on the original and passes on ours. 30 were dropped with evidence, the rest are waiting. Those 51 failing tests are ready-made bug reports, and I'll send them to the Svelte team.
An agent is a machine that converges on a judge. No judge, nothing to converge on.
Speed
Medians of ten runs on one machine, M2 Max, Node 26:
| Benchmark | Svelte | Vigla | Faster |
|---|---|---|---|
| Parser: markup | 75.6 ms | 26.5 ms | 2.9× |
| Parser: script and style | 144.7 ms | 66.5 ms | 2.2× |
| Compile: script and style | 569.6 ms | 328.8 ms | 1.7× |
| Compile: TypeScript | 320.8 ms | 214.4 ms | 1.5× |
| Effect cleanup | 5.6 ms | 1.6 ms | 3.4× |
| Writes to 1,000 effects | 22.5 ms | 11.4 ms | 2.0× |
| Repeated dependencies | 264.0 ms | 185.0 ms | 1.4× |
| kairo graph: diamond | 655.5 ms | 522.3 ms | 1.3× |
| kairo graph: repeated | 110.9 ms | 72.4 ms | 1.5× |
| Unmount 10,000 readers | 5.6 ms | 0.8 ms | 7.1× |
| Unmount 100,000 readers | 508.4 ms | 15.7 ms | 32× |
| Server rendering | 61.0 ms | 62.5 ms | even |
12 of the 51 benchmarks in the run. The harness is in the repo; the numbers are from commit d5220448.
Where you couldn't trust the agents
"Everything's green." An agent fixed a known SvelteKit bug — and broke eight of SvelteKit's own tests. What the issue tracker called a bug, the authors' tests treated as intended behavior. The "everything's green" I heard was about a run that about fifteen more commits had landed on top of. A full run on the new code caught it, and the fix was rolled back. An hour and a half. "Green" without a commit hash is a rumor.
"What's actually left is small." That's what Opus said. Six minutes later, an auditor agent counted: of the 172 selected bugs, 30 were proven fixed, and nobody had touched 139 of the SvelteKit ones. Another time, Opus claimed a whole group of SvelteKit tests had never been recorded. 866 of 869 had been. It explained this itself, better than I could: "I passed off an assumption as the state of things and didn't check it, even though checking would have taken one command."
Someone else's instruction as permission. One agent told another to "record what passes." The other one launched nine hundred browser tests for fifty minutes, on every core of my laptop: it read another agent's instruction as permission. A rule against this was written ten seconds later. It didn't hold. What held was moving heavy runs to CI on ten machines.
A ratchet only works if it's fast. A change to error handling in the runtime broke a test that was already recorded. The ratchet caught the regression, and a few minutes later both tests were passing again. The runtime ran in seconds, SvelteKit in half an hour. The slower the check, the more new code piled on top of a mistake: in the runtime we caught regressions in minutes, in SvelteKit in hours.
A bug the original never had. The blog you're reading is built on Vigla. While I was building it, the dev server stopped picking up new styles in the root layout: the markup updated, but the CSS stayed stale until a restart. Real SvelteKit handles this case fine. The ported tests didn't cover it. An agent fixed the bug along with a new test that fails before the fix. A human found it, on a live site.
For the people building models, here are three habits I saw in the agents. They pass off assumptions as verified facts. They read another agent's instruction as permission. They estimate in weeks where the work takes hours.
How one person runs 228 agents
This was a side project. It got the leftovers: spare quota and the minutes between my real work.
The agents worked in Tagma, the tool I build for exactly this kind of work. I talked to one Opus. It launched the others, and they launched their own reviewers. 228 agents, up to sixteen at a time, Claude Opus 5.5 and GPT-6.1 Sol side by side. And one person to talk to.
About 137 of the 228 agents were reviewers. Half the team did nothing but distrust the other half.
All the agents worked in a single working copy of the repo. Each one owned its own directories, Tagma tracked whose lines were whose and committed each agent's own changes. Overlaps still happened: once, someone else's lines ended up in a core commit. But the history has 1,653 commits and not a single merge commit.
My job was the scope, the calls, and figuring out what each new "done" actually proved.
Why 8 billion tokens is cheap
I burned 8.25 billion input tokens to find out what agents can actually do. Sounds like the budget of a small country — until you look at what it's made of.
98.2% of it is cache reads: at every step, the agent re-reads what it already knows. At API list prices this would have come to about $2,000, most of it Opus re-reading its own memory. I paid with subscriptions I already have: this work used less than half of their weekly limit.
The tokens aren't the expensive part. The expensive part is the attention it takes to check the agents' work.
What this means
Code got cheap to rewrite. Knowing it's right is what's expensive. The Svelte team spent years deciding what Svelte should be. I got the finished answer, written down in their tests. For open source, that's both a threat and a compliment: your tests are now worth more than your code.
Svelte is the perfect target: open source, thousands of tests, a deterministic compiler. Look for others like it — there are more than you'd think.
The judge matters more than the model. You can't take an agent's word for it. You need expectations that the author of the new implementation didn't make up, and a test runner checked against the original. And you still have to look for yourself: a human found the styles bug, not the tests.
Start with tests. If you want agents to do big work, don't start with prompts or picking a model. A good test suite turns an agent from a generator of plausible code into an engineer converging on the right answer. A bad one turns a team of agents into a very fast way to write a lot of wrong code.
If you want to try this yourself:
- Judge first, agents second. Find a judge the agents didn't write, and check it against the original before you build anything.
- Account for every test. A rewrite loses behavior silently.
- Put a commit hash on every "green." Green without a commit is a rumor.
- Don't let checks fight the agents for the machine. Heavy runs go to CI.
- Ask agents to measure. They estimate like people. They don't work like people.
What's next
When I asked Opus to compare us to Svelte honestly, under "where we're worse" it wrote, on its own: "No production use. Not a single real app runs on Vigla."
This blog is built on Vigla, but it's static pages, and that's hardly a serious test. The serious test is Tagma. The same UI that went down that night is moving to Vigla: a hundred and fifty thousand lines, live reactivity, and agents working inside it around the clock. Then TSX, the second way into the same core. That's when we'll find out what those 54 hours were really worth.
That's the next post.
Code, test manifest and green CI run. You can try it by swapping dependencies:
"svelte": "npm:@vigla/svelte@^5.57.3",
"@sveltejs/kit": "npm:@vigla/sveltekit@^3.1.1",
"@sveltejs/vite-plugin-svelte": "npm:@vigla/vite-plugin-svelte@^7.3.2"Runes code only. Adapters: node, bun and static; no Cloudflare, Vercel or Netlify yet. Don't put this in production. Try it on a side project and send us a failing test.