The Pulse: What can we learn from Bun’s rapid Rust rewrite with AI?
The Pragmatic Engineer
SubscribeSign in
The Pulse<br>The Pulse: What can we learn from Bun’s rapid Rust rewrite with AI?<br>To a sceptic, spending $165K to migrate Bun from Zig to Rust sounds very expensive. But to a realist, shortening a 1-2 year migration down to 11 days opens amazing new opportunities for devs.
Gergely Orosz and Ivan Klaric<br>Jul 16, 2026
68
Share
Hi, this is Gergely with a bonus, free issue of the Pragmatic Engineer Newsletter. In every issue, I cover Big Tech and startups through the lens of senior engineers and engineering leaders. Today, we cover one out of four topics of a past The Pulse issue. Full subscribers received the article below a week ago. If you’ve been forwarded this email, you can subscribe here.
Last week in San Francisco, I met Jarred Sumner, creator of JavaScript runtime, Bun, and was keen to learn more about the rewrite of Bun from Zig to Rust. But at the time, Jarred didn’t want to say too much, as the tool used for the migration, Fable, was out of action due to the US government imposing export controls.
Jarred and I at Anthropic’s HQ, last week<br>Fortunately, the situation is now resolved and Fable is available globally, and Jarred has published a detailed post about the project. Before we get into the migration, some context:<br>Bun is a complex project, with lots of production software depending on it. Bun itself does many things:<br>JavaScript, TypeScript and CSS transpiling, minifying and bundling
A test runner
A package manager (npm-compatible)
Other things: module resolution, a WebSocket client, Node.js implementations and many modules
Today, Bun has 22 million monthly downloads, and software like Claude Code and OpenCode depend on it, while hosting providers like Vercel, Railway and DigitalOcean do first-party support for Bun.<br>Why a rewrite?
Zig is not a memory safe language, and memory-related bugs occurred continuously. Jarred lists memory-related bugs in the latest version of Bun: memory leaks, crashes due to memory issues, heap-out-of-bounds writes, and so on. This was after the Bun team patched the Zig compiler to reduce memory-related issues, and put end-to-end memory leak tests in place. As Jarred says:<br>“Our bugfix list felt bad and I was tired of going to sleep worrying about crashes in Bun. I don’t blame Zig for that - other users of Zig don’t have the bugs we had, and mixing GC with manually-managed memory is an uncommon enough thing for software to need that no language really designs for it. (...)<br>For Bun, correctly handling the lifetimes of garbage-collected values and manually-managed values has been a major source of stability issues - most often small memory leaks and occasionally crashes. Every memory allocation has to be meticulously reviewed. Where do these bytes get freed? How do we ensure it only gets freed once? Did we check for JavaScript exceptions properly? Is this garbage-collected pointer visible to the conservative stack scanner? Is this garbage collected memory or manually managed memory?”
Moving to a memory-safe, yet performant language could eliminate such errors, and Rust is one such language that fitted the bill. Jarred:<br>“A large percentage of bugs from that list are use-after-free, double-free, and “forgot to free” in an error path. In safe Rust, these are compiler errors and RAII-like automatic cleanup with Drop. Compiler errors are a better feedback loop than a style guide.”
However, doing a full rewrite on Rust has always been a terrible idea. Or at least, it used to be, because of how unberabaly long it would have taken:<br>There are two problems with rewrites: they take too long, and they take waaaay too long. A dev who has done rewrites probably knows how things tend to go:<br>Make an educated guess about how long it will take; say, nine months.
Nine months later, there’s still another ~6 months to go because new functionality is added to the original codebase, and now that new functionality needs to be added in!
By 15 months in, there’s still months left to go for the same reason!
In the end, you manage to mandate a “feature freeze” for two months and finish the rewrite in ~18 months, if lucky. The original nine-month estimate can end up taking 2+ years.
Jarred likened rewriting Bun in Zig to this:<br>“Historically, rewrites are a terrible idea. Excluding comments, Bun is 535,496 lines of Zig.<br>A rewrite in another language would take a small team of engineers a full year.<br>A year of zero user-facing impact is not a realistic option we could consider. So, enforcement through code-style to fix stability issues was our best bet, and was our plan when we added Rust-inspired smart pointers to Bun’s codebase.<br>But honestly, I didn’t want to do it. Homegrown smart pointers offer worse ergonomics than Rust, with none of the guarantees.<br>What if, instead, I spend a week testing if Anthropic’s new model [Fable] can rewrite Bun in Rust?”
Rewriting Bun with...