On Wednesday, May 14, Jarred Sumner merged PR #30412 into Bun's main branch: a Rust rewrite of the runtime, roughly a million lines across about 6,755 commits, produced in under a week of active development, mostly by Claude. The previous afternoon he had shipped Bun 1.3.14 with a quiet line: this is the last release built from the Zig source. The next one will be Rust.
It is the largest AI-authored merge in a major open-source runtime to date. It is also a useful case study in what changes - and what does not - when a single maintainer can land a rewrite at agent speed.
What actually shipped
The shape of the PR is the story. Per the merge, the Rust tree contains over a million lines and roughly 6,755 commits, accumulated since the experiment became public on May 3. GitHub's review UI could not load all of its comments. The companion PR removing the Zig sources - about 600,000 lines deleted - was auto-flagged by GitHub as "AI slop."
Sumner has been explicit about how it was built:
this is already the status quo; we haven't been typing code ourselves for many months now.
The pipeline is a four-phase loop: agents receive the Zig source, generate Rust in parallel, feed compiler errors back as correction prompts, and verify behaviour against the existing test suite. A ~300-rule porting guide pins the translation conventions so the parallel agents converge on a single style. By the time of the merge, 99.8 percent of Bun's pre-existing test suite passed on Linux x64 glibc.
Bun's older C and C++ code - including JavaScriptCore and the bundler's hot paths - is not part of the rewrite. Sumner has been clear on that point:
most of Bun is written in C and C++, that's not going to change.
This was the Zig layer.
The argument for Rust
Sumner's stated motivation is not ideological. It is operational: memory bugs have been a tax on the team, and Zig does not help him collect it.
Most importantly, we now have compiler-assisted tools for catching and preventing memory bugs, which have cost the team an enormous amount of development and debugging time over the years.
He is careful about the bound. Rust will not catch every leak - references held too long across the JS boundary still escape the borrow checker - but the long tail of use-after-free, double-free, and forgot-to-free-on-error-path becomes a compile error or an automatic drop. For a runtime whose bug tracker has churned through hundreds of those, that is real money.
There is a second motivation he says less about, but the timing reveals: in December 2025 Anthropic acquired Bun to accelerate Claude Code, and a Rust codebase is, today, a substantially better fit for AI-assisted contribution than a Zig one. Zig's project posture toward AI-generated patches has been one of the strictest in the language ecosystem; Rust's tooling, by contrast, is what every coding agent has been trained against. The choice of target language is not separable from the choice of author.
The 13,000 unsafe blocks
The number that has the Rust community alarmed is the count of unsafe blocks in the merged tree. Estimates from readers walking the diff put it above 13,000, later reduced to around 10,000 as cleanup PRs landed. For comparison, uv - Astral's Rust-written Python package manager, of similar systems-level scope - has on the order of 73 unsafe calls across roughly 350,000 lines. Per line of code, Bun's Rust has roughly sixty times the unsafe density.
Some of that is inherent to a port. Zig's pointer semantics map cleanly onto raw pointers, and an agent translating line-by-line will reach for unsafe before it reaches for a redesign. The honest framing - that initial ports from a memory-unsafe language always sit on a transitional ledge of unsafe before the idiomatic rewrites land - is fair. The question is whether this codebase will walk off that ledge or live on it.
And here the safety story breaks in a way the test-pass rate cannot patch. A passing test asserts behaviour; it does not assert that the invariants an unsafe block claims to uphold are actually upheld. Undefined behaviour under the right schedule is consistent with a green CI run. One reader on Lobsters pointed out cases of incorrect lifetime annotations wrapping unsound primitives - "something you'd learn on the first day of Unsafe Rust 101" - and got little pushback on the substance.
Sumner's earlier framing from May 11 acknowledged this:
We haven't committed to rewriting. There's a very high chance all this code gets thrown out.
Three days later it was merged.
Tests prove behaviour, not soundness
99.8 percent is a great number for a behavioural port. It is the wrong number to lead with for a Rust merge. There is no test for soundness in the general case; Miri can find some violations under interpretation, formal models can prove invariants for some narrow surfaces, and concurrency stressors like loom can shake out a particular class of race. None of those are equivalent to running the existing suite green. A Rust program that compiles and passes its tests can still corrupt memory the first time a real workload hits an unconsidered schedule.
For a runtime, that distinction is load-bearing. Bun is the thing other code runs inside of. A memory-corrupting bug in the runtime is, at best, an outage in someone else's process; at worst, it is a sandbox escape. The bar for landing 13,000 unsafe blocks should be higher than the bar for landing 13,000 lines of application code, not lower.
What this changes about review
The technical content of the PR is half the story. The other half is the process it normalizes.
A million-line PR is not reviewable in the human sense. The maintainer who wrote it cannot review it; the contributors who might have caught a soundness bug in a 200-line patch are not going to read a 6,755-commit branch. What review means here is something new: a test suite, a property-checker, a fuzzer, and the maintainer's confidence in the agent pipeline that produced the diff. That is a defensible position for some changes. It is a different kind of position than the one the open-source ecosystem has spent two decades writing tooling for.
The community reaction has split along that fault line. The Zig project maintains an essentially anti-AI contribution stance and the Bun rewrite has been read inside Zig circles as a vote against the language. Rust observers, more pragmatically, are watching whether the unsafe surface gets paid down - and whether the next class of bug is one the borrow checker would have caught, or one it never could.
Either way, PR #30412 is a marker. It is the first time an agent has authored a runtime-scale codebase end-to-end and gotten it merged the same week. It will not be the last. The interesting question for any project of comparable scope is not whether to allow agent-authored contributions, but what the review pipeline for a million-line patch actually looks like - and whether "99.8 percent of tests pass" is the top line on that pipeline, or somewhere further down.
What to watch
- The
unsafeblock count over the next six weeks. If it drops fast as idiomatic rewrites land, the transitional-ledge framing holds. If it plateaus near 10,000, it does not. - The first post-merge CVE. The class matters more than the severity: a use-after-free in the JS boundary tells a different story than a logic bug in a parser.
- Whether other maintainers attempt the same playbook. The Deno and Node.js teams have no incentive to port wholesale, but smaller systems projects - package managers, build tools, language servers - have every incentive to try a six-day rewrite.
- Whether GitHub's "AI slop" auto-flag becomes a real signal or a piece of folklore. The classifier fired on the Zig deletion PR; it will fire on others.
Bun 1.3.14 is the last Zig version. The next release tag will compile from cargo. Whether that turns out to be a better runtime - fewer memory bugs, smaller binaries, faster cold start - is a question with an answer in months, not days. Whether it turns out to be a safer runtime is a question the tests cannot answer at all.
