AI News HubLIVE
In-site rewrite6 min read

Merged at the Speed of AI

Bun's AI-driven rewrite of its core from Zig to Rust sparked a debate on AI-generated code, memory safety, and test reliability. The article examines three opposing perspectives and underscores that passing tests is not verification, advocating for stronger behavioral equivalence standards.

SourceHacker News AIAuthor: taubek

Luka Kladarić

Jul 13, 2026

In May, Bun, the JavaScript runtime that ships inside Claude Code, replaced its entire core. About a million lines of Zig became a million lines of Rust: +1,009,272 lines, 6,502 commits, on a branch named claude/phase-a-port, merged May 14. Bun’s founder Jarred Sumner didn’t pretend a human typed it: “we haven’t been typing code ourselves for many months now.” The press ran with merged at the speed of AI and moved on.

After two months of silence, Bun published their promised follow up article last Wednesday. Zig’s creator Andrew Kelley published a response the following day, blunt enough that people called it a meltdown. Finally, legacy code veteran Ray Myers published his takedown of the whole spectacle on Sunday.

Seemingly opposed, but if you strip the venom... all three are making the same argument.

Three stories, one merge

Bun’s story is memory safety. The post opens with a bugfix list that reads like a confession: use-after-free in node:zlib, double-free in the CSS parser, a leaked SSL_SESSION per call. Mixing a garbage-collected JavaScript engine with manually-managed Zig memory meant every allocation was a small bet, and the team kept losing a few bets per week. Rust’s compiler turns that class of bug into a compile error. That’s the whole stated rationale. The Zig politics appear nowhere in it: not the ban on AI contributions, not the compiler fork Bun couldn’t upstream.

Kelley’s story is that it was never the language. The Zig team read Bun’s code for years and was, in his words, horrified: “Hacks on top of hacks.” Slop, he says, well before vibe coding was a thing. The relationship was already dead. The $60k/year donation to the Zig Software Foundation silently stopped after the Anthropic acquisition, scheduled meetings went ignored, and when the rewrite was announced, “we were ecstatic.” What the press pegged as a one sided escape turns out to be a divorce both sides wanted.

Myers’s story is that the decision was marketing. Real memory bugs, several viable fixes. Management picked the one that doubles as a showcase for the new model, with a trillion-dollar valuation to feed. His sharpest line: the marketing had to focus on how the AI was powerful enough to do the rewrite, “even though it was not powerful enough to catch a use-after-free.” He also lists what the rationale post doesn’t have: a pros-and-cons section, any mention of compilation speed, and a “Bun is better in Rust” section padded with wins unrelated to the rewrite.

One contradiction sits unresolved between them. Bun’s post says they fuzz runtime APIs 24/7 with Fuzzilli. Kelley says that on calls, the Bun team told ZSF they weren’t fuzzing anything. His first version called that an “outright fabrication,” a charge he deleted within a day.

And a detail I can’t resist, because this is an essay about verification: of the three posts, the angriest one is the only one with a public edit history. Kelley rewrote his conclusion in an open git repo, admitting his resentment “was obvious to the reader, but not to myself,” and apologizing to Zig users caught in the blast. He invites you to diff him.

The part they agree on

Bun’s defense of merging a million unreviewed-by-humans lines is that the test suite passed. All of it: ~60,000 tests, 1.38 million assertions, zero skipped, green on six platforms. Kelley’s counterattack is a single question: if that suite is good enough to certify a million lines of machine-written Rust, “Then why are you saying you have so many annoying bugs in the Zig code?” The same suite let those bugs through for years. Myers makes the same point from the outside. The model that wrote the port couldn’t catch a use-after-free.

Attacker and defender are standing on the same fact. A green test suite is not verification. Bun’s own postmortem proves it with a number, and the number is 19.

What $165,000 of verification bought

Let’s be fair first, because the lazy version of this essay (the one I almost published in June) said Bun merged on faith. They didn’t.

How do you review a pull request with a million added lines? Bun’s honest answer: you don’t. You review the process that writes the code, and you fix the process when it fails. Before any code, they wrote a PORTING.md mapping Zig patterns to Rust patterns and a LIFETIMES.tsv tracing the ownership of every struct field, both adversarially reviewed before use. Then the harness: one Claude implements, two separate Claudes review, each in its own context window, given only the diff, told to assume the code is wrong. At peak, 64 Claudes ran in parallel for 11 days. Total bill: 5.9 billion uncached input tokens, around $165,000 at API pricing.

And the adversarial reviewers earned their tokens. They caught a use-after-free in an async uv_close handoff, a negative-timestamp bug where trunc produced an invalid timespec, and an eagerly-evaluated unwrap_or that would panic on valid CSS. All three compiled clean and looked plausible. A second Claude with no stake in shipping the code found them anyway.

This is, plainly, the most verification anyone has ever purchased for a software rewrite. Job well done. Not really.

What it still missed

The port shipped 19 known regressions. Not one of them was sloppy code. Every single one was a faithful, line-for-line translation that meant something different in the new language:

Zig’s assert is a function; its argument runs in every build. Rust’s debug_assert! is a macro; release builds erase the whole expression, including the side effect inside it. Hot module reloading silently broke, in production builds only.

Zig’s reinterpretSlice quietly ignored a trailing odd byte. Rust’s cast_slice panics on it. Blob.text() went from returning a string to killing the process.

Zig’s comptime format strings are resolved before arguments arrive. Rust has no equivalent, so the color-marker parser started eating escape sequences out of user data.

A test suite with 1.38 million assertions saw none of this. Users did. That isn’t an indictment of Bun’s tests; it’s the definition of the ceiling. Tests verify the behaviors you thought to assert. Rewrite bugs live precisely in the behaviors you didn’t, because if you’d thought of them, you wouldn’t have translated them wrong.

The stronger standard

Enter Andreas Kling, whose Ladybird browser ported its JavaScript engine’s frontend from C++ to Rust back in February. Same class of tools: Claude Code and Codex, hundreds of small human-directed prompts, adversarial review passes. About 25,000 lines in two weeks.

The difference isn’t discipline; Bun had discipline. The difference is the standard. Kling’s requirement, set before the port began, was byte-for-byte identical output from both pipelines: every AST identical, every byte of generated bytecode identical, 52,898 test262 tests and 12,461 regression tests at zero deltas, and then lockstep browsing of the live web, with the C++ and Rust pipelines running simultaneously and diffing output on every piece of JavaScript that flowed through.

That’s a different claim than “our tests pass.” It says the old system and the new system are not allowed to disagree, and someone is watching. Assertion coverage tells you the new code does what you remembered to check. Output equivalence tells you it does what the old code did, including the behaviors nobody remembered were load-bearing. Yes, 25,000 lines is not a million; the standard scales worse than the codebase. But the 19 regressions are exactly the bugs the stronger standard catches and the weaker one structurally cannot.

What to take from this

If you’re running a platform, this episode is worth more than the drama around it, because one thing is now settled: the cost of attempting a rewrite has collapsed, and it’s not coming back up. Language choice is becoming reversible. Even Myers, no friend of the hype, calls the migration method the real contribution. Sooner or later someone in your org will propose letting agents rewrite something you depend on. Fine. The reusable parts of Bun’s playbook are worth stealing: porting guides as executable style guides, adversarial reviewers with no stake in shipping, fixing the generator instead of hand-patching its output.

But the merge criterion is where the whole thing is decided, and it needs to be stronger than a green suite:

Define “identical behavior” before the port starts, and make it executable. Output diffing, not vibes.

Run old and new in lockstep against real traffic, and diff what comes out.

Treat your test suite as a floor, not a proof: it already missed the old system’s bugs.

Keep a human on the hook for the merge. Bun did; Jarred pressed the button himself. That part didn’t get cheaper.

“Merged at the speed of AI” turned out to be true and beside the point. Bun spent eleven days and $165,000 closing the gap between generated and verified, got further than anyone before them, and the gap still let 19 bugs through.

Generation is now approximately free.

The gap is now approximately the whole job.

References

Rewriting Bun in Rust — Jarred Sumner, Jul 8, 2026. The official rationale and process writeup; source of all workflow, cost, and regression figures.

My Thoughts on the Bun Rust Rewrite — Andrew Kelley, Jul 9, 2026. The Zig creator’s response; test-suite contradiction, relationship history.

Kelley’s conclusion rewrite commit — Jul 10, 2026. Public self-edit: resentment admission, apology to Zig users.

Kelley’s “double down” commit — Jul 9, 2026. Retracts the “outright fabrication” charge on fuzzing; sharpens other criticism.

Zig Creator Calls Spade a Spade, Anthropic Blows Smoke — Ray Myers, Jul 12, 2026. The marketing/meta-narrative critique; missing pros/cons, compilation speed omission.

Ladybird adopts Rust, with help from AI — Andreas Kling, Feb 23, 2026. The byte-for-byte standard: test262/regression tables, lockstep browsing.

Bun Rust port PR #30412 — the merged pull request; +1,009,272 lines, 6,502 commits.

Ladybird LibJS Rust port PR #8104 — the 25,000-line frontend port.

Bun unsafe audit — Bun’s own accounting of unsafe usage (~4% of code, 78% single-line FFI).

Jarred Sumner on AI-written code — “we haven’t been typing code ourselves for many months now.”

Anthropic’s Bun Rust rewrite merged at speed of AI — The Register, May 14, 2026. The headline that carried the story for two months.