groundy
developer tools

Bun Rewrites Its Core From Zig to Rust, Putting Downstream Zig Bindings at Risk

Bun is rewriting from Zig to Rust (PR #30412) to end memory bugs costing years of debugging, putting downstream frameworks with Zig bindings on watch for compatibility breaks.

11 min · · · 13 sources ↓

Jarred Sumner opened PR #30412 with a three-word title: “Rewrite Bun in Rust.” [Updated June 2026] It merged into main on 2026-05-14, roughly eleven days after Sumner started, and the diff is the headline: 1,009,257 lines added, 4,024 deleted, 2,188 files changed across 6,755 commits. The PR description claims it passes Bun’s pre-existing test suite on all platforms, fixes several memory leaks and flaky tests, and shrinks the binary by 3 to 8 MB. Benchmarks are, in Sumner’s characterization, “between neutral and faster.” The Rust code ships in the 1.4 canary channel via bun upgrade --canary; it has not reached a stable release.

This is not a fork. It is not a community contribution. It is also, by Sumner’s own account, not hand-written: the port was generated by Anthropic’s Claude Code agents working off the original Zig source, on a branch named claude/phase-a-port, reviewed by the claude[bot] and coderabbitai[bot] accounts, and merged by Sumner. He is replacing the Zig codebase he spent years building with a Rust one that preserves Bun’s existing architecture and data structures, on a timescale no human team could have matched.

An AI-written runtime

The scale is the point. A million-line cross-language port that passes the original test suite is the kind of project a staffed team would budget in person-years. Bun did it in under two weeks because, as Sumner put it when asked whether Claude would maintain the Rust version, “we haven’t been typing code ourselves for many months now.” The diff was authored by agents and signed off by bot reviewers. Bun’s own Rust codebase audit, published May 21, labels the work “AI generated” in its header.

The test claim deserves a footnote. Before the merge, Sumner reported 99.8% of the suite passing on Linux x64 glibc specifically, with other platforms not yet green. The merged PR upgrades that to an unqualified “passes on all platforms” with no percentage attached. Both numbers are self-reported by the author of the code, in the PR that merges it, with no independent human having read the full diff. That last part is the recurring objection. As one Hacker News commenter noted, reviewing a million lines in a week would require reading thousands of lines an hour without a break, which means Bun is now, in his phrasing, a black box of largely unread code. Whether that matters depends on how much you trust the test suite to be the spec. For a runtime, where a single bug propagates into every application above it, the bar for that trust is high.

Why Rust, why now

The PR description is direct about the motivation. Sumner writes that memory bugs have “costed the team an enormous amount of development & debugging time over the years,” and that Rust’s compiler-assisted tools for catching and preventing those bugs are the primary benefit. Not performance. Not ecosystem. Safety, specifically the class of safety that costs maintainer hours when it fails.

The rewrite uses no async Rust and few third-party libraries. This is a narrow, architectural swap: same data structures, same external behavior, different systems language underneath.

Rust’s safety guarantee is not free here, and the audit is honest about that. [Updated June 2026] Bun’s published numbers show 13,365 unsafe blocks in the unreleased Rust codebase, of which roughly 9,300 could be rewritten as safe code and about 4,000 must stay unsafe, mostly at the foreign-function-interface boundary where Rust talks to JavaScriptCore and the OS. The audit also lists five functions that are unsound today, meaning undefined behavior is reachable from ostensibly safe Rust. The pitch is not that the borrow checker eliminates memory bugs in a runtime this low-level. It is that the compiler localizes them: every place memory safety is hand-asserted is now a marked block a tool can find, rather than an implicit assumption spread through Zig that only surfaces under load. That is the “compiler-assisted tools for catching & preventing memory bugs” the PR names as the primary benefit.

There is a second motivation Sumner has been less direct about, and it is structural. Zig is pre-1.0 (the current release is 0.16, shipped in April 2026) with a small contributor pool, and its project bans AI-generated contributions outright in its code of conduct. Andrew Kelley, Zig’s creator, holds AI code to what he calls “uncompromising perfection” and has called the typical AI contribution garbage that wastes reviewer time. Once Bun’s development moved to writing almost no code by hand, a language whose maintainers will not accept that workflow upstream became a poor fit by construction. Rust’s ecosystem is large, mature, and indifferent to how the code was produced. For a team that has decided agents write the code, that indifference is the feature.

Anthropic acquired Bun in December 2025. At the time, Bun had 7.2 million monthly downloads and zero revenue. Anthropic uses Bun as the infrastructure for Claude Code, the Claude Agent SDK, and planned AI coding products. A runtime with memory leaks and flaky tests is a liability when your parent company ships it as the foundation of a developer tool used in production. The Rust rewrite is, among other things, a reliability investment that aligns with Anthropic’s interests, and a demonstration of what Anthropic’s own agents can do on a real codebase.

The Electrobun dependency chain

Electrobun is a desktop application framework that uses Bun as its main-process runtime, with native bindings written in Objc, C++, and Zig. Per its GitHub repository, Electrobun claims 14 MB bundles, sub-50ms startup, and 15 to 30 MB memory usage by using system WebViews instead of bundling Chromium, compared to Electron’s 150 MB+ bundles and 2 to 5 second startup.

Electrobun has not announced a version 2.0, a Rust rewrite, or any plan to decouple from Bun. Its README and documentation still list Bun as the runtime. But Electrobun’s Zig native bindings sit on top of a Bun core that is now rewriting itself in Rust. When Bun finishes the Zig-to-Rust transition, every downstream project with Zig bindings layered on the Bun API will need to evaluate whether those bindings still work against the new core, and whether to follow Bun to Rust or maintain a divergent integration path.

This is the pattern worth watching. Bun is not the only JavaScript toolchain component built in Zig. If Bun’s own creator concluded that the memory-safety tooling in Zig was insufficient for a production runtime under real load, maintainers of smaller Zig-dependent projects face the same calculus with fewer resources.

What the rewrite preserves

Bun’s current stable release, v1.3.14, includes built-in PostgreSQL, MySQL, and SQLite drivers, a Redis client, an S3 client, a frontend dev server, single-file executable compilation, and a Jest-compatible test runner. [Updated June 2026] It is also, per Sumner, the last release built from Zig; everything after it comes from the Rust tree, with the 1.4 canary as the first build to ship it. The Rust rewrite targets all of these features. Sumner’s PR states that the existing architecture is preserved, which means the external API surface (the JavaScript and TypeScript interfaces developers actually call) should remain stable.

For teams currently using Bun in production, the immediate question is whether the canary build passes their integration tests. The PR claims the full pre-existing test suite passes, but Bun’s test suite is not your test suite. The binary is smaller and benchmarks are neutral-to-faster, but those benchmarks measure Bun’s internal regressions, not the behavior of applications built on Bun.

The practitioner calculus

The Rust rewrite changes the evaluation for teams choosing a JavaScript runtime today in two ways.

First, Bun is now a runtime in transition. Its internals are being rewritten while its stable channel continues to ship Zig-based builds. Bug reports against the current stable may be addressed in a codebase that is being replaced. Feature requests may land in the Rust branch first. Teams on Bun need to decide whether to track canary or wait for stable, and either choice carries a different support profile.

Second, the Anthropic acquisition gives Bun a financial backer with a specific interest in reliability. That is a strength. It is also a concentration of dependency: Anthropic’s AI tooling depends on Bun, and Bun’s development priorities will inevitably reflect that dependency. Teams using Bun for non-AI workloads should expect that the roadmap serves Anthropic’s needs first, and the broader ecosystem second.

For desktop framework maintainers specifically, the Electrobun pattern is instructive. Electrobun chose Bun for its main process and Zig for native bindings. Both of those choices are now in flux. The framework still works, the README still says Bun, and nothing has broken yet. But the runtime is moving from Zig to Rust, and the native-binding layer shares a language with the runtime’s outgoing implementation. That is a coupling worth auditing in any project that depends on Bun’s native interface.

Early production reports

The first substantive downstream data point landed June 11, when Prisma described running the Rust canary in production on Prisma Compute. The decision was not ideological. In their words, “that decision had nothing to do with how we feel about rewrites in general. It came down to test results.” The specifics are the kind of thing a synthetic benchmark misses. On stable Bun 1.3.14, a looping S3 read test crossed 900 MiB of resident memory around iteration 96; on the canary, the same test stayed flat at roughly 118 MiB. A SQL connection pool that “reliably deadlock[ed] after a restore from scale-to-zero” on stable recovered on the rewrite. For a long-lived server, where memory growth has nowhere to hide, that gap is the difference between a restart loop and a process that runs. The Rust build passed the tests the Zig build failed, and Prisma shipped the one that passed.

That is one report, not a trend, and it cuts against the more cautious read. The same week surfaced the other side: issue #31503, a panic in the 1.4 canary’s CommonJS resolver (a fixed-size path buffer not reset across recursive Module._resolveFilename callbacks) that broke react-scripts and webpack production builds. The reporter noted that git bisect was useless because the 1.4 line is the entire Zig-to-Rust drop, with no incremental history to walk. It was fixed within days, which is the optimistic framing; the pessimistic one is that this is the first of a class of regressions a million-line port produces, surfacing one application at a time.

Community reaction has split along predictable lines, and the dividing question is not Rust versus Zig but trust in code no human read. Supporters point out that the unsafe blocks are now declared rather than hidden, so you at least know where the risk lives. Skeptics, including some prominent runtime authors, were blunter: developers building competing tools argued the output reads as C++ transliterated into Rust rather than idiomatic Rust, and that trading a known set of bugs for an unknown set written and reviewed by agents is not obviously a good trade. Charlie Marsh of Astral, which builds the Rust-based uv, framed the open question directly: how do you ship a million-line agent-written rewrite with confidence? The contrast with uv is the one the critics keep returning to, since that project’s Rust was hand-written and reviewed line by line.

The broader backdrop is that Rust keeps winning these arguments by attrition rather than by any single decision. Across systems and AI infrastructure, performance-critical components are migrating to Rust while the higher layers stay in whatever language the team already knows. Bun is an unusually loud instance of that pattern, both because the rewrite was AI-generated and because the language it left, Zig, is the one whose maintainers most explicitly rejected the workflow that produced it.

Frequently Asked Questions

How does Electrobun compare to Tauri, not just Electron?

Tauri produces ~25 MB bundles with ~500ms startup, versus Electrobun’s claimed 14 MB and sub-50ms. Both avoid bundling Chromium by calling system WebViews (WebView2, WebKitGTK) at runtime. The practical difference: Tauri is already Rust-native with no Bun dependency, so it faces no migration risk from this rewrite. Electrobun’s smaller footprint comes with a runtime that is actively swapping its systems language.

Which Bun features carry the most regression risk in the Rust build?

The built-in PostgreSQL, MySQL, and SQLite drivers are implemented in the native layer, not in JavaScript. Connection pooling, prepared-statement caching, and large result-set handling all depend on memory management that changes when the underlying systems language changes. Drivers that interact with external services have failure modes (timeout behavior, encoding edge cases, reconnection logic) that synthetic test suites rarely exercise.

Will Anthropic prioritize the Bun features most teams rely on?

Anthropic’s products (Claude Code, Agent SDK) primarily need fast startup, low memory overhead, and native file system access. Features like the built-in S3 client, frontend dev server, and Jest-compatible test runner serve general-purpose Node.js replacement use cases that are less central to Anthropic’s AI tooling. The passing test suite confirms API compatibility, but test coverage depth may not be uniform across all features.

What does ‘no async Rust’ mean for projects with native bindings to Bun?

Bun is built on the JavaScriptCore engine, which provides its own event loop. Adding a Rust async runtime on top would introduce a competing event loop and complicate the C FFI boundary that external bindings use. By restricting the rewrite to synchronous Rust, the external C API surface stays more predictable. Projects binding to Bun through that C layer, like Electrobun’s Zig bindings, face a more stable interface contract than if async patterns had been introduced.

sources · 13 cited

  1. Rewrite Bun in Rust — Pull Request #30412 primary accessed 2026-05-26
  2. Bun is joining Anthropic vendor accessed 2026-05-26
  3. Electrobun GitHub Repository primary accessed 2026-05-26
  4. Building Ultra-Fast Desktop Apps with Electrobun — Better Stack analysis accessed 2026-05-26
  5. What is Electrobun? — Electrobun Documentation vendor accessed 2026-05-26
  6. Bun — A fast all-in-one JavaScript runtime vendor accessed 2026-05-26
  7. Anthropic's Bun Rust rewrite merged at speed of AI — The Register analysis accessed 2026-06-20
  8. Bun Rust codebase audit (unsafe blocks) vendor accessed 2026-06-20
  9. Jarred Sumner: Bun v1.3.14 might be the last version in Zig community accessed 2026-06-20
  10. Bun's experimental Rust rewrite hits 99.8% test compatibility (HN discussion) community accessed 2026-06-20
  11. Zig creator seeks 'uncompromising perfection' before blessing 1.0 — The Register analysis accessed 2026-06-20
  12. bun --bun 1.4 canary panics in the CJS resolver — Issue #31503 primary accessed 2026-06-20
  13. We put Bun's Rust rewrite in production on Prisma Compute — Prisma analysis accessed 2026-06-20