The number that should stop you mid-scroll
535,496 lines of Zig. Ported to over 1 million lines of Rust. In 11 days. For $165,000 in API spend. Zero tests skipped, zero tests deleted, 100% pass rate across 6 platforms before merge.
That's Bun — the JavaScript runtime Anthropic acquired in December 2025 and now leans on to run Claude Code — getting fully re-platformed from Zig to Rust by a fleet of Claude agents while Jarred Sumner mostly watched dashboards.
If your first reaction is "no way that's safe to ship," you're not wrong. If your second reaction is "this is what software engineering looks like now," you're also not wrong. Sit with both.
What actually happened
Bun's core has been Zig since day one. Zig gave Sumner control and speed. It also gave Bun a nasty, recurring bug class: use-after-free, double-free, and forgot-to-free-on-an-error-path — the classic manual-memory-management tax, made worse because Bun's runtime mixes a JS garbage collector with Zig's manual allocation. Two memory models, one codebase, constant friction.
In March, a bundler bug that generated sourcemaps when explicitly told not to leaked 512,000 lines of Bun's source. That was the wake-up call. Sumner's diagnosis: Zig wasn't built for this job, and it never will be. Rust's borrow checker turns most of that bug class into compile errors instead of 2am incidents.
So instead of a gradual migration, they did this:
- Wrote
PORTING.mdmapping every Zig idiom to its Rust equivalent - Wrote
LIFETIMES.tsvpre-annotating struct field lifetimes so agents wouldn't fight the borrow checker blind - Ran a 3-file trial to validate the approach before committing
- Spun up 50 dynamic workflows, peaking at 64 parallel Claude agents across 4 git worktrees
- Every implementation got adversarially reviewed by 2 separate Claude instances whose only job was to find bugs in it
- Converted 1,448
.zigfiles to.rs, generating 6,778 commits over 11 days, peaking at 1,300 lines of code per minute and 695 commits in a single hour
Token bill: 5.9B uncached input tokens, 690M output tokens, 72B cached input reads. That's the $165K.
The results are genuinely good
This isn't a "technically it compiles" story:
HTTP throughput (Bun.serve): 169.6k → 177.7k req/s (+4.8%)
fastify: 91.5k → 95.9k req/s (+4.8%)
express: 64.5k → 66.6k req/s (+3.2%)
next build: 13.62s → 13.03s (+4.5%)
Linux binary size: 88MB → 70MB (-20%)
Memory (2,000x Bun.build loop): 6,745MB → 609MB (leak eliminated)
Claude Code Linux startup: 517ms → 464ms (~10% faster)
128 known bugs from v1.3.14 — fixed, reproducibly, in v1.4.0. 19 new regressions surfaced during the port, all from real semantic gaps between the languages (Zig's assert always runs; Rust's debug_assert! is compiled out in release builds — that kind of thing), and all were caught and fixed before merge.
This is not vibe coding. This is closer to a compiler-assisted formal migration with a very expensive compiler.
Then Zig's creator torched it
Andrew Kelley didn't attack Rust. He attacked the process:
"We became increasingly horrified at the programming practices we saw in Bun's codebase... It's not sufficient to catch bugs in Zig code but it is sufficient to catch bugs in a million lines of unreviewed slop?"
His point, stripped of the heat: a test suite is only as trustworthy as your confidence that it actually exercises the code paths that matter. If that same suite failed to prevent the memory bugs that motivated this whole rewrite in the first place, why does passing it now prove the new million-line Rust codebase is sound? You can't use a test suite as both the reason you needed to rewrite and the sole proof the rewrite is safe.
Zig's project has a standing policy against AI-generated contributions to the compiler itself, for exactly this reason. Kelley's not a Luddite here — he's applying a consistent standard and Bun is failing it by his own metric.
Sumner's counter is fair too: no human ever read a million lines of Zig line-by-line either. Nobody does full manual review at that scale, AI-authored or not. The real safety net was always the test suite plus production traffic plus time. Bun shipped this behind a canary, not straight to stable.
Who's actually right
Both of them. That's the uncomfortable part.
Kelley is right that "100% test pass" is a much weaker safety claim for a wholesale rewrite than it sounds — passing tests means the new code does what the old tests expected, not that the new code is correct, and definitely not that a reviewer would sign off on the design decisions an agent made mid-port.
Sumner is right that gatekeeping this on "did a human read every line" was never realistic and isn't how large codebases have been validated for a decade. The actual bar was always: better test coverage, staged rollout, fast rollback, and production monitoring. Bun met that bar. Whether it's the right bar for a runtime that Claude Code itself depends on is a legitimate, open question — not a settled one, no matter which side is currently louder on Hacker News.
What this means if you write code for a living
Ignore the "AI replaces engineers" headline version of this story — that's not what happened. What happened is one engineer with a fleet of agents did an 11-day, six-figure infrastructure migration that would've been a multi-quarter, multi-team project two years ago. The scarce resource shifted from "typing speed" to "can you design a verification harness good enough to trust the output."
If you're building anything with AI-assisted large-scale changes, the takeaways from this specific rewrite are concrete:
-
Write the porting spec before you write the code.
PORTING.mdandLIFETIMES.tsvweren't busywork — they're what kept 64 parallel agents from making 64 different design decisions about the same lifetime problem. - Adversarial review beats self-review. Separate agents whose only job is finding bugs in someone else's (or something else's) output catches things a single pass misses — same as with humans.
- Your test suite is your actual spec, whether you admit it or not. If you wouldn't trust it to catch a rewrite's bugs, that's not an AI problem, that's a coverage problem you already had.
- Canary everything, always. The fact that this shipped to a canary channel, not stable, is the whole reason this is a case study and not an incident report.
The number worth remembering isn't 1 million lines or $165K. It's 11 days for a migration most teams would've scoped at 6-12 months. That gap is going to define how a lot of infrastructure work gets planned from here.
Go read the source and the drama yourself — Bun's own writeup has the full methodology, and The Register's coverage has the fight in full. Simon Willison's breakdown is the best neutral summary of what shipped in Claude Code as a result.
Top comments (0)