Bun Rewrote Itself in Rust. Here's What That Actually Means.
Michael Sintim-Koree · July 2026
Bun launched in 2022 as a JavaScript runtime written primarily in Zig. That was a deliberate, provocative choice: Zig gave the team fine-grained memory control, close-to-the-metal performance, and the ability to embed JavaScriptCore directly without the overhead that comes with Node's architecture. The benchmarks were real. The speed was real. And Zig, a language most JavaScript developers had never heard of, became one of the more interesting bets in the runtime space.
Now Oven has rewritten Bun in Rust: not incrementally, but as a full port completed in May 2026 over roughly 11 days, using AI-assisted tooling. That's not a small decision, and the public framing around it has generated a lot of noise. Worth digging into what actually changed and why.
Why Zig in the first place
The original choice of Zig made sense at the time. Jarred Sumner wanted a language that compiled to fast native code, had no runtime, and let the team write allocator-aware code without fighting a borrow checker. Zig delivered that. It also gave the team comptime, which made certain patterns around embedding JavaScriptCore and handling cross-platform builds genuinely elegant.
The downside is that Zig's ecosystem is still early. Tooling is thin compared to Rust. The language itself continues to evolve in ways that occasionally break things. Finding engineers who know Zig well enough to contribute meaningfully is harder than finding engineers who know Rust. And as Bun scaled in complexity, some of the pain points of working in Zig at this scope started showing up in ways they didn't at the prototype stage.
That's not a criticism of Zig as a language. It's the practical reality of betting on a pre-1.0 language for a production runtime that a lot of people depend on.
What was rewritten and what wasn't
This was not a targeted, subsystem-by-subsystem migration. The Bun blog post describing the rewrite is explicit: it was a full mechanical port of the Zig codebase to Rust, passing the existing TypeScript test suite as a conformance target. The rewrite landed as a single PR adding over one million lines of code across 6,502 commits, and was merged to main in May 2026. As of the post date, Bun is predominantly Rust (around 46% of the codebase), with C++ retained for the JavaScriptCore bridge layer and some remaining Zig.
The team reached 99.8% test compatibility before shipping the rewrite publicly. JavaScriptCore itself is not going anywhere. Bun continues to use it as its JavaScript engine, and the C++ integration layer that connects Rust code to JavaScriptCore's APIs stays in place.
Three concrete reasons the shift to Rust makes sense
Rust has a large, active community of systems programmers who want to work on interesting projects. Zig does not, yet. For an open-source runtime that benefits from external contributions, this matters more than it might seem. The number of developers who can meaningfully review a Rust PR versus a Zig PR is not close right now, and that asymmetry affects both the speed of development and the quality of outside scrutiny.
Rust's crate ecosystem is also deep in exactly the areas relevant to a bundler and package manager: parsing, serialization, async I/O, concurrency primitives. Writing the same infrastructure in Zig means building more of it from scratch or maintaining forks of less-mature libraries. That overhead compounds quickly when you're trying to ship.
The third reason is arguably the most defensible: memory safety in correctness-critical code. Zig gives you the tools to write safe code. It does not enforce safety at compile time the way Rust does. For a runtime processing arbitrary user code, that distinction matters. Rust's borrow checker catches a class of bugs at compile time that in Zig require discipline, careful review, and runtime checks to prevent. The team made a judgment that the safety guarantees are worth the ergonomic cost of the borrow checker. That judgment holds up.
Where things stand right now
The rewrite merged in May 2026 but, as of late July 2026, has not yet shipped in a stable release tag. Claude Code v2.1.181 (released June 17th) was one of the first major consumers to run on the Rust build; startup on Linux improved roughly 10% with otherwise minimal observable difference. The Bun team's own blog post on the rewrite appeared July 9th, significantly after the merge. Jarred Sumner noted the blog post took longer to write than the rewrite itself took to execute.
Performance benchmarks from the Rust codebase have been competitive with the Zig equivalents. On a 10,000-module bundler benchmark, the Rust bundler came in at 1.05× faster than the Zig v1.3.14 baseline, with 41% lower total CPU usage attributed to better parallelism. These are early numbers, and real-world project graphs will be the more meaningful test.
One thing that is no longer a concern is an extended FFI boundary between Zig and Rust. Because the rewrite was a full port rather than an incremental migration, the in-flight complexity of two systems languages calling into each other through a shared ABI is largely behind the project rather than ahead of it. The remaining seam is between Rust and the C++ JavaScriptCore integration layer, which existed before the rewrite and is well-understood.
No measurable regression yet, but the stable release is the real test
The short version: no measurable regression in the data available so far, and some improvements in specific areas. The longer version is that a stable release has not yet shipped as of late July 2026, so the full range of user-facing edge cases hasn't been stress-tested at scale.
Bun's performance advantage over Node and Deno on most benchmarks has held through the rewrite. Across multiple benchmark suites, Bun leads the majority of tests, particularly on server-style throughput, HTTP handling, and large JSON parsing. The bundler specifically showed improved CPU efficiency in early benchmarks, which is where the parallelism benefits of Rust's ecosystem were expected to show up most clearly.
Measurements on large monorepo builds specifically would be the most informative next data point. That's where bundler performance differences between implementations are most visible, and it's also where the parallelism characteristics of Rust's ecosystem should theoretically shine. The benchmarks that exist today tend to run on smaller projects where the differences compress.
What this means for people actually using Bun
For most users, the rewrite is invisible. The Bun team has been consistent about backward compatibility: the Rust port was validated against the existing TypeScript test suite, and the stated goal was behavioral parity before any new feature development. The Anthropic acquisition in December 2025 provides additional engineering resources behind the project.
Bug reports during and immediately after the stable release are worth taking seriously and filing. A full port of over a million lines of code will have edge cases that the test suite didn't cover. If something in bun build or bun install behaves unexpectedly on an unusual input, reporting it is more useful right now than at any other point in Bun's history.
The places to watch for instability when the stable release ships:
- Complex bundler configurations with unusual module resolution rules or large plugin chains. Plugin chains push code paths that don't get much automated test coverage.
- Workspaces in bun install with non-standard package.json configurations. Package manager rewrites reliably surface edge cases in resolution logic that weren't visible before.
- Large builds that stress the parallelism paths: that's where the new implementation diverges most from the Zig baseline and where unexpected behavior is most likely to appear.
- Windows builds. Platform-specific issues surface during transitions like this earlier on Windows than on macOS or Linux, almost every time.
Is this the end of Zig in Bun?
For practical purposes, yes. The rewrite was a full port, not a targeted migration. Some Zig remains in the codebase as of the merge, but the direction of travel is unambiguous. The Bun blog post frames it as a complete rewrite, not an incremental transition. The Wikipedia entry for Zig already lists Bun as having been originally written in Zig until v1.3.14, with the Rust rewrite starting with v1.4.0.
Zig's path to 1.0 and the ecosystem improvements that come with it could have changed that calculus, but the rewrite happened before that maturation arrived. The Bun team's stated reasons (contributor accessibility, ecosystem support, memory safety) point toward Rust as the long-term foundation. The remaining question is how quickly the new codebase matures from a faithful mechanical port to idiomatic Rust, which the team has acknowledged is ongoing work.
The Bun rewrite is more significant than early coverage suggested. It wasn't an incremental migration of specific subsystems: it was a full mechanical port of the entire codebase, executed in under two weeks with heavy AI assistance, validated against the existing test suite. Good engineering judgment about contributor accessibility and memory safety drove the decision. The execution approach was genuinely novel.
Whether the rewrite delivers on its potential is the concrete thing to watch when the stable release ships. If it holds the performance characteristics of the Zig implementation while opening the codebase to a broader contributor base, the decision will look obviously correct in retrospect. The early data is encouraging. The stable release is what matters.
If you're running Bun canary builds and have hit something that smells like a behavioral regression from the Zig baseline, sharing what you ran into would be valuable. That's where the useful signal about how the rewrite is actually holding up lives right now.