# Bun's Rust Rewrite Killed the One-Way Door

> Source: <https://sourcefeed.dev/a/buns-rust-rewrite-killed-the-one-way-door>
> Published: 2026-07-09 06:04:59+00:00

[Dev Tools](https://sourcefeed.dev/c/dev-tools)Article

# Bun's Rust Rewrite Killed the One-Way Door

An LLM ported a million lines from Zig to Rust in under two weeks. The conformance suite mattered more than the model.

[Rachel Goldstein](https://sourcefeed.dev/u/rachel_goldstein)

For most of software's history, the language you started a project in was a life sentence. Joel Spolsky's "Things You Should Never Do" put the ground-up rewrite at the top of the list of ways to kill your company, and he wrote that in 2000. The advice held because rewrites meant humans re-deriving years of accumulated edge-case knowledge by hand, slowly, while the old thing rotted.

[Bun](https://bun.com) just demonstrated that this constraint has quietly loosened. Jarred Sumner ported the runtime from [Zig](https://ziglang.org) to [Rust](https://www.rust-lang.org) in roughly eleven days, with a coding agent authoring the overwhelming majority of the one-million-plus lines in the pull request. The internet's reaction split into two camps: "this is terrifying" and "this is the future." Both are missing the actual story. The interesting thing here isn't that an LLM wrote a lot of Rust. It's *why* it worked, and the answer is boring in the best possible way.

## The test suite did the heavy lifting, not the model

Strip away the token counts and the real enabling factor is something Bun built years ago for unrelated reasons: a test suite written in TypeScript. Because the tests exercise behavior through JavaScript APIs rather than internal Zig calls, they're language-independent. They don't care whether `fs.watch`

is implemented in Zig, Rust, or hand-carved runes. That makes them a conformance suite, and a conformance suite is exactly what turns a rewrite from an act of faith into a measurable engineering loop.

That's the mechanism. The agent harness ported code, ran the suite, and iterated against a million assertions. When something regressed, the fix wasn't to hand-patch the generated Rust, it was to fix the *process* that generated it. The reported result: 99.8% test compatibility on Linux x64 glibc, with the remaining 0.2% being platform quirks and edge cases rather than structural breakage.

This is the part worth internalizing. The LLM is interchangeable and will get cheaper. The oracle that tells you the translation is correct is the expensive, irreplaceable asset, and most teams don't have one. If your "tests" are a handful of unit checks wired to internal function signatures, no model on earth is going to safely rewrite your codebase, because nothing can tell it when it broke something. Bun could do this because Bun had already done the unglamorous work of specifying its own behavior from the outside.

## What actually changed under the hood

The motivation was memory, not performance. Bun's bug reports read like a greatest-hits album of manual memory management gone wrong: use-after-free in `node:zlib`

when a callback re-enters during an async write, double-free in the CSS parser, leaked `SSL_SESSION`

handles at ~6.5 KB a pop, watchers pinned forever by a reference-count underflow. The root cause is structural. Bun stitches a garbage-collected world (JavaScriptCore) to manually managed native memory, and Zig, by design, gives you `defer`

and expects you to get every cleanup path right by hand. No destructors, no hidden control flow. That's a fine trade for many systems, and Sumner goes out of his way to credit Zig for making Bun possible at all. But mixing a GC with manual allocation is a niche that no language really designs for, and it bit them constantly.

A large share of those bugs are, in safe Rust, simply compiler errors. Use-after-free and double-free don't survive the borrow checker, and `Drop`

handles the "forgot to free on the error path" class automatically via RAII. That's the whole thesis: move an entire category of runtime crashes to compile time.

What's telling is what *didn't* change. Per the pull request, it's the same architecture, the same data structures, still very few third-party dependencies, and notably no async Rust. They kept their own event loop rather than pulling in Tokio. This wasn't a re-imagining, it was a faithful port that preserves the engineering while swapping the memory model underneath. Which is precisely why the conformance suite could validate it.

## What it means if you ship on Bun

Short term, almost nothing, and that's the point. The Rust implementation has shipped inside Claude Code since v2.1.181 on June 17, and the observed effect was startup about 10% faster on Linux and otherwise nobody noticing. Rust and Zig both compile to native code, neither has a GC, and a well-written program in either lands within a few percent of the other. Don't expect a speed revolution. Bun's existing benchmark lead (its published Express hello-world numbers put it at roughly 59,000 req/s against Deno's 25,000 and Node's 19,000) comes from architecture, not language choice, and the architecture came along for the ride.

The payoff you should actually care about is a slower drip of the crash-and-leak bugs that make people nervous about betting production on Bun. If the memory-safety class of issue genuinely shrinks, that's a reliability win that compounds over years.

There are real caveats:

**Platform coverage is narrow at first.** The rewrite nailed Linux x64 glibc; macOS, Windows, and ARM come later. If you develop on a Mac or deploy to ARM, the mature Zig build is still your reality for now, and stable Bun continued shipping from Zig through the transition.**Contributor accessibility genuinely improves.** Finding engineers fluent in Zig is hard. The Rust hiring pool is enormous, and Rust is now the default language for systems rewrites across the industry. More eyes means faster fixes.**The 0.2% gap is where your weird edge case lives.** If you depend on some obscure`node:http2`

re-entrancy behavior, test it explicitly rather than assuming parity.

The broader lesson for maintainers of any large codebase: the value of an external, implementation-agnostic conformance suite just went up dramatically. It's no longer only a regression guard. It's the thing that makes a language migration, a dependency swap, or an aggressive refactor *reversible and verifiable*. That's a reason to invest in one now.

## The skeptics are right about the wrong thing

The "this should terrify you" take leans on real anxieties (a million lines nobody wrote by hand, near-zero institutional knowledge, "tech debt laundering" where old quirks get dressed up in a clean git history) but mostly aims at the wrong target. The fear assumes the code was merged on vibes. It wasn't. It was gated by a million assertions, adversarial review, and a month of live production use inside Anthropic's own flagship product before the blog post went up. "Boring is good" is a defensible standard for merging, and it was met.

The genuinely sharp critique came from a systems engineer in the comments, not the headline: the scariest part isn't correctness, it's *intent the type system never encoded*. An arena lifetime that the original Zig author tracked by convention doesn't automatically become a Rust lifetime. It can become an `unsafe`

block that happens to work today. The conformance suite proves behavioral equivalence on the paths it covers, but it can't prove that an invariant held in someone's head survived the translation. That's the seam to watch, and it's exactly the kind of thing a green Rust contributor, drawn in by the friendlier language, might trip over later.

One more thing worth flagging honestly: the numbers vary by teller. Sumner's own account describes monitoring the workflows across eleven days; louder secondhand versions rounded it to nine. The estimated pre-merge cost was around $165,000 at API pricing (5.9 billion uncached input tokens, 690 million output, 72 billion cached reads), which Anthropic absorbed because it owns both the model and, since December 2025, Bun itself. That vertical integration is the unspoken asterisk on "anyone can do this." You need the conformance suite, the frontier model, and the willingness to burn six figures of tokens. Most projects have exactly none of those.

The one-way door is no longer strictly one-way. But it only swings for teams who specified their software well enough to prove the new version behaves like the old one. Bun didn't win a bet on AI. It cashed in a decade of test discipline, and the model was just the crank it turned.

## Sources & further reading

-
[Rewriting Bun in Rust](https://bun.com/blog/bun-in-rust)— bun.com -
[Bun rewrote itself from Zig to Rust using an LLM in 9 days. That should terrify you.](https://dev.to/adioof/bun-rewrote-itself-from-zig-to-rust-using-an-llm-in-9-days-that-should-terrify-you-5om)— dev.to -
[Rewriting Bun in Rust](https://simonwillison.net/2026/Jul/8/rewriting-bun-in-rust/)— simonwillison.net -
[Why Bun is Rewriting in Rust (And What It Means for JavaScript Developers)](https://www.cosmicjs.com/blog/bun-rust-rewrite-javascript-runtime)— cosmicjs.com

[Rachel Goldstein](https://sourcefeed.dev/u/rachel_goldstein)· Dev Tools Editor

Rachel has been embedded in the developer tooling ecosystem for nearly eight years, covering everything from IDE wars and package-manager drama to the quiet rise of AI-assisted coding. She has a soft spot for open-source maintainers and an unhealthy number of terminal emulators installed on a single laptop.

## Discussion 0

No comments yet

Be the first to weigh in.
