groundy
developer tools

Bun's Rust Rewrite: The Zig Creator's Rebuttal

Andrew Kelley says Bun's Rust rewrite was not about Zig's features. Maintaining half a million lines in a niche language carries a hidden hiring cost.

9 min···4 sources ↓

Andrew Kelley’s rebuttal to Bun’s Zig-to-Rust rewrite is not the technical defense of Zig that its framing suggests. It is a relationship post-mortem in which Zig’s creator states plainly that the split had “nothing to do with programming language features” and that the Zig Software Foundation felt relief when Anthropic acquired Bun in December 2025. Read against Bun’s own justifications, the argument that survives scrutiny is not about borrow checkers or comptime. It is about who can be hired to maintain half a million lines of code once the original authors are gone.

What did Andrew Kelley actually say?

Kelley’s July 8 verdict on Bun’s Zig codebase is unambiguous: by the time of the acquisition, the Zig team “all felt at ZSF that Bun was a net liability.” He describes “hacks on top of hacks,” “abuse of assertions,” and “recklessly speeding past feature after feature with very little time taken for reflection and elimination of bugs and technical debt” (Kelley’s rebuttal).

The post spends more words on the social breakdown than on language features. Kelley recounts interviewing Oven employees and concludes that “Jarred was a stinky manager. Poor communication, unrealistic expectations, low empathy, no experience.” He notes that “most of the talent pool steered clear of Oven and Bun,” leaving Zig community members who wanted paid Zig work largely unable to get it through Bun.

The financial thread is concrete. Sumner donated $60,000 per year to the Zig Software Foundation, and that donation “silently stopped” after the acquisition. Kelley’s closing is the clearest signal of what the post is really about: “The main issue here was the relationship breakdown, as I’ve outlined above, nothing to do with programming language features.” He admits the Zig team was “rooting for” the Rust rewrite and “ecstatic” when it shipped, because it ended the indirect association between Zig and a codebase whose practices invited the memory-safety criticism Zig itself faces.

Was this a language decision or a contributor-economics decision?

The rebuttal, perhaps without intending to, makes the contributor-economics case. If the problem was engineering discipline and a broken relationship rather than Zig’s language features, then Bun’s move to Rust is defensible on a ground Kelley did not stress: Rust has a larger pool of engineers who can be hired to maintain the code. Akita on Rails’s technical analysis makes this explicit, listing “hiring, tooling, documentation, IDE, review culture, CI, examples, people in the market” as Rust advantages and concluding: “This is not a political detail. It is engineering. A language exists inside an ecosystem.”

The inference is supportable but should be read as analysis, not as a claim either source confirms directly. Kelley documents that even Zig-literate engineers avoided Oven, though he attributes that to Sumner’s management rather than to Zig’s market size. The broader asymmetry, that the pool of Rust engineers is simply larger, is Akita’s argument and is consistent with the general state of both ecosystems. Whether the rewrite was planned before the acquisition, as some Hacker News commenters speculated (HN discussion, 696 points), is unverified. The contributor-economics logic holds regardless of timing: a runtime employed by a company that sells Claude Code needed a language whose maintainers are replaceable.

Did Zig have the tools to prevent these bugs?

Kelley’s technical barbs target Bun’s process, not a claim that Zig was defenseless. He points out that the performance gains Bun attributes to LTO were available in Zig “for all of Bun’s existence,” that Bun told the Zig team during calls “they were not fuzzing anything” despite the blog post implying diligent fuzzing, and that the Zig compiler itself, at roughly 600,000 lines, builds from scratch in 16 seconds (Kelley’s rebuttal). He also notes years of unheeded warnings about comptime abuse.

The fuller defense of Zig’s tooling comes from Akita’s analysis, which walks through the mechanisms Kelley skipped. errdefer provides cleanup on error paths. DebugAllocator catches double-free and leaks with stack traces and deliberately never reuses memory addresses to surface dangling pointers. ASAN catches a broader class of memory errors at runtime. Akita’s caveat is precise: these are testing and debugging tools, not a borrow checker, and they only catch what flows through them on exercised paths.

Bug classIn ZigIn RustWhat Rust still leaves open
Use-after-freeDebugAllocator, ASAN (runtime)Borrow checker (compile time)unsafe escapes; foreign-heap pointers
Leaked resources on error pathserrdefer (manual)Drop tied to ownership (automatic)mem::forget, Rc cycles, abort
Double-freeDebugAllocator (runtime)Move semantics + Drop (compile time)None in safe code
Invalid borrows across FFIReview, ASANunsafe blocks, Pin, lifetimesForeign-call preconditions unproven

The difference is feedback timing. Rust surfaces ownership errors at compile time; Zig surfaces them in tests, fuzzing, and instrumented allocators. Akita’s honest conclusion is that Zig had tools and Bun did not use them well enough. Kelley says the same thing more bluntly: “You’re not giving TigerBeetle nearly enough credit. Quite simply they put in the time to find and eliminate the bugs, they make an effort to maintain a healthy relationship with ZSF, and Bun did neither of those things.” TigerBeetle is the counterexample, a Zig codebase that invests in discipline and ships memory-safe financial infrastructure.

Does the Rust rewrite fix the FFI boundary?

The “Rust won” narrative is hardest to sustain at the FFI boundary, and both sources concede it. Bun is a JavaScript runtime. It talks to JavaScriptCore, libuv, uWebSockets, BoringSSL, SQLite, and the Node API surface, none of which are governed by Rust’s borrow checker. The memory-safety bugs Bun listed in its own post, use-after-free crashes in node:zlib, node:http2, and UDPSocket.send(), and leaks in crypto.scrypt and fs.watch() (Bun’s blog post), cluster exactly at the boundaries where Rust’s guarantees stop.

Akita’s most instructive example is a uv_close bug from the rewrite itself. The first Rust version compiled cleanly but handed a Box to libuv for asynchronous closure and then dropped the Box at the end of the scope. The result was use-after-free followed by double-free, the exact class of bug the rewrite was meant to eliminate. The fix was Box::leak, transferring ownership out of Rust’s lexical control and into libuv’s callback protocol (Akita’s analysis). Review caught it, not the compiler.

What Rust buys at the FFI boundary is encapsulation, not safety. You can wrap unsafe behind handle types, NonNull, Pin, and lifetimes that tie a wrapper to its runtime, shrinking the auditable surface. Zig can do the same with explicit wrappers. The difference is that Rust makes the safe/unsafe boundary part of the language, so a reviewer knows where to look. For a codebase partly generated by Claude Fable 5 over 11 days, that boundary marker has real value. It documents the contract; it does not eliminate it.

What does this mean for niche systems languages?

The contributor-economics problem the Bun episode surfaces is structural, not specific to Zig. Any company that bets long-lived infrastructure on a niche systems language faces the same risk: when the original authors leave, the pool of engineers who can maintain the code is small, and the cost of replacing them is high. Bun’s 535,496-line Zig codebase, rewritten in 11 days with Claude Fable 5 after Anthropic’s December 2025 acquisition, is an extreme case, but the dynamic generalizes.

Kelley’s post, read against its own framing, is the case study. The Zig team could not keep Bun’s codebase healthy through social pressure or technical guidance. The talent pool that could have maintained it in Zig avoided the company. The donation that tied the two projects stopped. The rewrite to Rust resolved the relationship problem by making the codebase maintainable by a workforce Rust can supply. Akita’s formulation is the cleanest: “Bun chose to pay a large cost now to reduce recurring maintenance costs later” (Akita’s analysis).

Akita also flags the conflict of interest that complicates the story: Anthropic acquired Bun in December 2025 and sells Claude Code, the product used to perform the rewrite. Sumner and the Bun team now work at Anthropic. That does not invalidate the technical result, but it means the rewrite doubles as a demonstration for the acquirer’s flagship product. The contributor-economics argument survives that conflict, because Rust’s hiring advantage over Zig is independent of who owns Bun.

The hard part for language designers is that technical merit, memory-safety tooling, and compile-time feedback are necessary but not sufficient for adoption in infrastructure meant to outlive its authors. A language whose hiring pool cannot staff a half-million-line codebase after the founding team departs carries an adoption tax that surfaces only at the moment a company most needs to scale maintenance. Zig did not fail Bun. The economics did. Rust’s advantage in this case was less about the borrow checker than about the available workforce.

Frequently Asked Questions

Should teams avoid Zig for new infrastructure after the Bun rewrite?

Not necessarily. Zig remains viable for codebases with a small, long-tenured team that owns the full lifecycle and can invest in fuzzing, ASAN, and a working relationship with the Zig Software Foundation. The Bun case warns about maintainer succession in a mass-market runtime, not about the language itself. Projects that do not anticipate frequent contributor turnover, such as single-vendor databases or embedded firmware with controlled release cycles, face a very different risk profile than a general-purpose JavaScript runtime that must absorb outside patches.

How is Bun’s rewrite different from typical Rust adoption in large codebases?

Most large Rust adoptions, including the Linux kernel’s Rust drivers and Firefox Quantum, added Rust incrementally alongside existing code and matured FFI contracts over many release cycles. Bun did the opposite: a 535,496-line automated translation completed in 11 days with Claude Fable 5. That compression leaves less time for boundary ownership conventions to evolve through incremental failure, so the first Rust release may carry more latent FFI risk than a slower oxidation would have.

What should operators monitor after upgrading to the Rust-based Bun release?

Regressions will cluster where Rust’s ownership system ends and foreign runtimes begin. Prioritize stress tests for libuv async close callbacks, JavaScriptCore object lifetimes, and Node API handles, because these are the exact zones where Bun listed use-after-free crashes in node:zlib, node:http2, and UDPSocket.send, plus leaks in crypto.scrypt and fs.watch. A clean rustc build does not prove those boundaries safe; runtime instrumentation and targeted code review remain the only useful signals.

Can Rust’s borrow checker prevent all the memory bugs Bun reported in Zig?

No. The borrow checker only governs Rust-owned values, not JavaScriptCore’s garbage-collected heap, libuv handles, or C++ allocators. Akita’s uv_close example from the rewrite itself compiled cleanly yet freed a Box before the libuv callback ran, producing use-after-free and then double-free. The fix, Box::leak, is a manual ownership transfer the compiler cannot validate, which means the audit burden shifts from Zig’s runtime checks to careful review of every unsafe block and leak contract at the boundary.

What could make the Rust rewrite look like a poor decision later?

If Anthropic needs faster iteration than Rust’s compile-and-test cycles allow, especially after Zig’s 16-second full compiler build, the recurring maintenance savings may be eaten by slower feature velocity. More importantly, because Anthropic acquired Bun and used Claude Code to perform the rewrite, a high-profile memory-safety regression could be read as a verdict on AI-assisted rewrites as well as on Rust. That reputational coupling creates incentives to treat boundary bugs as product-level incidents, not ordinary runtime issues.

sources · 4 cited

  1. My Thoughts on the Bun Rust Rewriteandrewkelley.meprimaryaccessed 2026-07-10
  2. The Bun in Rust Response Andrew Kelly Should Have Writtenakitaonrails.comanalysisaccessed 2026-07-10
  3. Hacker News discussion, 696 pointsnews.ycombinator.comcommunityaccessed 2026-07-10
  4. Rewriting Bun in Rustbun.comvendoraccessed 2026-07-10