Bun just rewrote its entire runtime from Zig to Rust in 11 days. 535,496 lines of code. 6,778 commits. Every test passing on every platform.
Not one line was written by a person.
If you build software for a living, that sentence should stop you. Not because it failed. Because it worked, and "it worked" is being treated as the end of the argument when it's actually the start of one.
I want to walk through what Bun actually did, because the engineering is genuinely impressive, and then tell you why I'd still be nervous putting it under a production system. This is a builder's read, not a hot take.
What Bun actually pulled off
Bun is the fast all-in-one JavaScript toolkit: runtime, bundler, package manager, test runner, one binary. Jarred Sumner started it in Zig in 2021, in a cramped Oakland apartment, pre-LLM, over about a year. Zig gave a tiny team low-level memory control and let Bun punch way above its weight on speed. Today the CLI does over 22 million downloads a month, and tools like Claude Code and OpenCode run on it.
So why leave Zig? Sumner was straight about it. The bug list was full of use-after-free, double-free, and "forgot to free on the error path" mistakes. Zig makes you write cleanup by hand with defer, and mixing that with JavaScript's garbage collector is a combination almost no language designs for. He doesn't blame Zig, and neither do I. In safe Rust, a whole category of those bugs becomes a compiler error instead of a 3am page.
Here's the method, because the method is the interesting part. Rewrites are usually a terrible idea. A year of frozen features and no bug fixes kills projects. So Sumner didn't do a normal rewrite. He pointed a pre-release model, Claude Fable 5, at the codebase and ran roughly 50 automated Claude Code workflows for 11 days straight.
The setup was disciplined, and that matters:
- A 3-hour session first, mapping Zig patterns to Rust patterns into a
PORTING.mdguide, then aLIFETIMES.tsvtracing the lifetime of every struct field. - A trial on 3 files before touching all 1,448. One agent writes the Rust, two adversarial agents check it matches the Zig behavior, one fixer applies the notes.
- Adversarial review as a hard rule: a second Claude, in its own context window, gets the diff and nothing else, and is told to find how it's wrong. The Claude that writes wants the code accepted. The Claude that reviews wants to break it. Different incentives, on purpose.
- When something went wrong, he fixed the workflow that generated the code, not the code by hand.
At peak, 64 Claudes ran at once across four worktrees, writing about 1,300 lines a minute. The whole test suite is written in TypeScript, so it doesn't care what language the runtime is built in. That test suite, with its million-plus assertions, was the gate. Two days after the first CI run, failures dropped from 972 test files to 23. A day and a half later, Linux went fully green. Zero tests skipped or deleted.
Since merging, they've run 11 rounds of automated security review and stood up 24/7 fuzzing that has executed Bun's parsers 100 billion times. That's a serious safety net. I'm not here to pretend it isn't.
The gap between "tests pass" and "we understand this"
Now the part I can't get past.
A green test suite tells you the known paths behave correctly. It does not tell you the code is understood. Those are different claims, and Bun's own writeup quietly proves the difference. The rewrite shipped 19 known regressions, all caught and fixed, but every one is a lesson in what tests miss.
One example. In Zig, assert is a function, so its argument runs in every build. In Rust, debug_assert! is a macro, so in release builds the whole expression is erased. A line that looked like a faithful translation silently stopped running a real side effect in production. Another: a slice cast that used to ignore a trailing odd byte instead started panicking the whole process on a UTF-16 byte order mark. Another: a placeholder value lowered a module resolver's ceiling from 8.4 million interned filenames to 270,272, a limit real projects hit, and woke up an off-by-one that had been dormant for years.
None of these were caught by the tests before release. They were found after. That's the tell. The tests encoded known behavior on known inputs. The regressions lived in the boundary conditions, the release-vs-debug differences, the invariants that were never written down because the original author just knew them.
That last point is the one I'd underline for any tech lead. Every mature codebase has a layer of design rules that exist only in the heads of the people who built it. Why this buffer is sized like that. Why this cleanup has to happen before that callback. Why this looks wrong but is load-bearing. AI translation gets you local correctness, function by function. It does not reliably carry the global rules that span the whole system, because those rules aren't in the source, and they aren't in the tests.
Bun's merged pull request makes this concrete. It was approved by coderabbitai[bot] and claude[bot]. The human reviewer was still marked "awaiting requested review" when it landed. Code written by Claude, reviewed by Claude. That loop isn't impossible to trust, but it means no single human has read this codebase end to end. We covered a version of this in why testing in production costs you: a check that runs is not the same as a system you understand.
The risk quietly changed owners
There's a business angle underneath the engineering one.
When Bun was a solo bet in 2021, taking on tech debt and moving fast was Sumner's risk to carry. Fair enough. But Bun was acquired by Anthropic in December 2025, and Claude Code ships as a Bun executable to millions of users. If Bun breaks, Claude Code breaks. Sumner even notes the memory issues around re-entering across JavaScript boundaries are something the Rust compiler can't fully catch, and still lean on human oversight. The parts that need a human are exactly the parts a human didn't fully review.
So the risk moved. It's no longer carried by one founder betting on himself. It's carried by every team running Bun in production and every user they serve. That's the number that should sit with you longer than the 11 days.
What I'd take back to my own team
I'm not telling you to avoid Bun. The stable release you install today still ships from the battle-tested Zig codebase, and the Rust version is experimental until it clears a public beta. I run Bun. I'll keep running it.
What I'm taking from this is a way to think about AI-generated code in our own work at dsrpt, because this method is coming to normal teams fast, not just runtime authors:
- A strong, language-independent test suite is the single biggest thing that makes large AI rewrites even thinkable. If your tests are thin, you have no gate. Invest there first.
- Adversarial review by a separate agent, given only the diff and told to break it, is a genuinely good pattern. Steal it. But it finds bugs in the change, not violations of invariants nobody wrote down.
- "All tests pass" is a starting line for a production decision, not a finish line. Ask the harder question: if this breaks in six months, who on the team can open this file and know why it's shaped the way it is?
- The maintainability bet is the real bet here. Not Zig versus Rust. Whether AI-built, largely unreviewed code can be maintained over years is still an open question, and Bun is the biggest live experiment we have.
Sumner made the honest call himself: merging into main isn't a release, and he wasn't confident enough to ship it yet. That restraint is the most reassuring thing in the whole story. The people closest to it are treating it as unproven. So should the rest of us.
The demo was breathtaking. The bet is real. Watch what happens the first time something breaks at 3am and nobody can say why.