FrameworksArticle Eleven days and a million lines of Rust reopened the real question: what counts as safe enough for a JS runtime.
Emeka Okafor When Bun shipped an AI-driven rewrite from Zig to Rust in eleven days, the story that stuck was the price tag: about $165,000 in API spend, fifty-odd Claude workflows in parallel, a peak of roughly 1,300 lines per minute, and more than a million lines of generated Rust that cleared Bun's million-plus assertion suite at 100 percent. Speed like that is the kind of number people quote when they want to declare the old cost model of large rewrites dead.
The more useful fight is not the benchmark. It is the argument Andrew Kelley made afterward: that Bun's problems were never primarily Zig's, that the project had been writing "slop" long before LLMs, and that the Rust port was the public end of diverging value systems rather than a language upgrade. That framing is sharper than the usual AI-codegen cheerleading, and it is only half the picture. The other half is a real class of memory bugs that Zig's explicit model does not magically prevent when you glue a GC'd JavaScript engine to hand-managed native code and ship hard.
What the rewrite actually changed #
Bun is not a toy. It is a runtime, package manager, bundler, and test runner built around JavaScriptCore, with Node-compatible surfaces and more than 22 million monthly CLI downloads. Anthropic bought it in December 2025 and already leans on it for tooling such as Claude Code. That makes stability a product problem, not a blog-post problem.
Jarred Sumner's own account of the move is blunt about the failure mode. Bun mixed garbage-collected JSC values with application-driven allocation. Zig expects cleanup to be written out with defer
and friends; it does not give you constructors, destructors, or an ownership system that tracks GC roots for free. The result, even with ASAN builds, Fuzzilli fuzzing, and leak tests, was a steady drip of use-after-frees, double-frees, and leaks in places like zlib streams, HTTP/2, UDP sockets, Buffer paths, and TLS session handling. A bundler bug that still emitted source maps when told not to helped produce a large Claude Code source leak. Sumner's claim is that fixing those one by one forever was the wrong game, and that Rust's ownership model is a better automated fit for that particular hybrid memory story.
A full human rewrite of roughly half a million lines of Zig, he argued, would have frozen a small team for a year. Claude Fable (pre-release) did the bulk of the mechanical work instead. Early in the run, enough of the existing suite went green that the merge decision flipped from experiment to plan. That is the technical case for the port: not "Rust is always safer," but "this codebase's bug class maps better onto Rust's defaults."
Kelley's critique hits process, not syntax #
Kelley is not primarily defending Zig's memory model. He is defending a culture of maintainability against a culture of release velocity. Bun had been one of Zig's highest-profile users and a real financial contributor (on the order of $60,000 a year). The Zig team still grew "increasingly horrified" at what they saw in the tree: feature velocity that outran reflection, weak error handling, assertion abuse, and technical debt that made Bun, in Kelley's words, the prime example of how not to write Zig rather than a poster child for it.
His line that Sumner "was already writing slop well before he had access to LLMs" is the load-bearing one. It reframes the Claude rewrite as continuity, not rupture. RoboBun had already become the top PR merger in the repo before the language switch. After the Anthropic acquisition, Zig also saw a surge of low-quality AI drive-by patches and community noise tied to the Claude–Bun–Zig association. The project already refuses AI-based contributions for that reason. Bun's earlier attempt to push a fork that claimed roughly 4× faster debug builds upstream went nowhere under that policy.
On values, Kelley is consistent. He wants long-horizon language work and code that can be read by humans who will still be on the hook in five years. Sumner wants a product that ships, absorbs Anthropic's needs, and uses every automation lever available. Those are not the same job. Pretending the fight is "Zig bad, Rust good" is how both camps lose the plot.
Tests green is not a threat model #
The impressive part of the port is also the dangerous part. Generating over a million lines in eleven days and watching a huge suite pass is evidence of transfer, not of review. Forum reaction around the Register coverage kept returning to the same point: a million assertions can still be shallow, duplicated, or written to the code rather than to the problem. Volume of green checks does not prove the absence of lifetime bugs, API footguns, or "it works until a re-entrant callback detaches the buffer" paths that only show up under real load.
There is also the simple bulk problem. Starting near half a million lines of Zig and landing north of a million lines of Rust is not free. Every unreviewed generated path is a place where unsafe blocks, incorrect assumptions about JSC exception edges, or subtle ABI mismatches can hide. Sumner himself has warned that naive prompts ("rewrite Bun in Rust") are a way to do this badly. The existence of a careful workflow does not make the default outcome careful.
For a JavaScript runtime used as infrastructure, the threat model is not "does CI pass on supported platforms." It is: who can audit the ownership story, how fast can a security fix land without fighting the generator, and what happens when the next class of bug is outside the suite's imagination. AI mass-rewrite does not remove that work. It front-loads a different kind of debt: human comprehension lag.
What this means if you ship on Bun #
If you run Bun in production, treat the rewrite as a major native-stack change, not a free memory-safety upgrade. Pin and stage. Do not assume "100% of our tests" means "100% of your workload." Run your integration suite, native addon paths, and long-lived process scenarios against the Rust builds before you cut over. Pay special attention to anything that crosses into zlib, HTTP/2, TLS, UDP, or Buffer-heavy code; those were the Zig-era hot spots for lifetime bugs.Watch the unsafe surface. Rust does not erase FFI and engine-boundary unsafety. Budget time for reading the hot paths that talk to JavaScriptCore and OS sockets the way you would for a large C++ dependency bump.Separate product risk from language risk. Anthropic ownership plus heavy Claude involvement means Bun's roadmap will track AI-product needs. That can be good for Claude Code users and noisy for everyone else. Plan exit options (Node, Deno, plain JSC/V8 embeds) the same way you would for any single-vendor runtime.Do not cargo-cult the method. An eleven-day port made sense for a team that already owned the test corpus, the product, and the willingness to merge at high risk. Replicating "50 agents, merge when green" on a smaller toolchain without that harness is how you get unreviewed infrastructure. If you experiment, fence the blast radius: one subsystem, mandatory human ownership of every unsafe and every free path, and a rollback story that does not depend on the model.Upstream politics matter. Zig's hard line on AI contributions and Bun's departure clarify the social contract. If you depend on a language project's review bandwidth, flooding it with generated patches is not contribution; it is externalized cost.
None of this requires rejecting AI assistance. It requires refusing to confuse generation speed with engineering completion.
The split that will keep showing up #
Kelley is right that Bun was a liability as a public Zig exemplar and that unreviewed volume is a maintenance hazard. Sumner is right that the hybrid GC-plus-manual design was a recurring crash factory and that waiting a year for a hand port was a non-option under product pressure. Both can be true at once.
What the episode really demonstrates is a coming default for large systems work: AI makes "rewrite the world" cheap enough that organizations will try it whenever the alternative is living with a known bug class. The winners will be teams that invent review, ownership, and rollback practices that scale with generation. The losers will be anyone who treats a green million-assertion run as a substitute for reading the code.
Bun's Rust tree is now the experiment. Watch the crash rate, the security advisories, and how long it takes a human to fix something the suite never imagined. That, not the eleven-day stopwatch, is the metric that matters.
Sources & further reading #
Zig creator calls Bun’s Claude Rust rewrite ‘unreviewed slop’— theregister.com - Zig creator calls Bun’s Claude Rust rewrite ‘unreviewed slop’ • The Register Forums— forums.theregister.com -
[My Thoughts on the Bun Rust Rewrite - Andrew Kelley](https://andrewkelley.me/post/my-thoughts-bun-rust-rewrite.html)— andrewkelley.me -
[Rewriting Bun in Rust | Bun Blog](https://bun.com/blog/bun-in-rust)— bun.com
[Emeka Okafor](https://sourcefeed.dev/u/emeka_okafor)· Security Editor
Emeka has spent over a decade tracking threat actors, vulnerability disclosures, and the evolving landscape of application security, bringing a sharp continent-spanning perspective to his reporting. He's known for translating dense CVE advisories into clear, actionable context that developers and security teams alike actually read.
Discussion 0 #
No comments yet
Be the first to weigh in.