Bun's Rust Rewrite Has Undefined Behavior in Safe Code. That's a Problem.

4 min read 1 source clear_take
├── "Undefined behavior in safe Rust is a fundamental misuse of the language, not an ordinary bug"
│  ├── @ndiddy (Hacker News, 317 pts) → view

Filed the original GitHub issue documenting that Bun's Rust rewrite fails basic miri checks and contains UB in code marked as safe Rust. Their position is that these aren't minor bugs but violations of Rust's core memory safety invariants — the exact guarantees that justify choosing Rust over C or C++ in the first place.

│  └── top10.dev editorial (top10.dev) → read below

Argues that UB in safe Rust represents a category of bug that Rust's type system is specifically designed to prevent. The editorial emphasizes that miri failures mean the program violates Rust's fundamental memory safety invariants, and this isn't a 'we'll fix it later' problem but a fundamental misuse of the language's safety model.

├── "This undermines the credibility of Bun's Rust rewrite as a strategic bet"
│  └── top10.dev editorial (top10.dev) → read below

Frames the miri failures as particularly damaging to the rewrite's credibility because Bun migrated from Zig/C++ to Rust specifically for improved maintainability and to attract Rust ecosystem contributors. If the rewrite ships UB in safe code, it undermines the core rationale for choosing Rust and raises questions about whether the team understands the language's safety model deeply enough.

├── "Large codebases inevitably have bugs — the real question is how Bun responds"
│  └── top10.dev editorial (top10.dev) → read below

Acknowledges the counterpoint that every large codebase has bugs, noting Bun's rewrite is a multi-month effort involving significant portions of the codebase. The editorial raises but complicates this position by arguing the bugs are of a special category that Rust is designed to prevent, making a 'normal bugs in large projects' defense insufficient.

└── "Miri is the definitive tool for validating Rust safety guarantees and should be part of any serious Rust project's CI"
  └── @ndiddy (Hacker News, 317 pts) → view

By filing the issue with miri results as the primary evidence, implicitly argues that miri checking should be a standard practice for Rust projects. The fact that basic miri checks were apparently not run as part of Bun's CI pipeline before shipping suggests insufficient adoption of Rust's tooling ecosystem.

What happened

A GitHub issue filed against the Bun JavaScript runtime (oven-sh/bun#30719) has ignited a sharp debate in the systems programming community. The issue documents that Bun's ongoing Rust rewrite — one of the most watched language migration efforts in the JavaScript tooling ecosystem — fails basic miri checks and contains undefined behavior (UB) in code marked as safe Rust. The issue quickly accumulated over 317 points on Hacker News, drawing attention from both the Rust and JavaScript communities.

Miri is the Rust project's official interpreter for mid-level intermediate representation. Its purpose is singular and critical: detect undefined behavior that the compiler cannot catch at compile time. When code fails miri checks, it means the program violates Rust's fundamental memory safety invariants — the exact guarantees that justify choosing Rust over C or C++ in the first place. The fact that these failures occur in code not wrapped in `unsafe` blocks makes the finding particularly damaging to the rewrite's credibility.

Bun, created by Jarred Sumner and backed by Oven, has been one of the most ambitious JavaScript runtimes to emerge in recent years. Originally written in Zig with some C++, the team announced a gradual rewrite into Rust to improve long-term maintainability and attract contributors from Rust's large ecosystem. The rewrite has been a multi-month effort involving significant portions of the codebase.

Why it matters

The core issue isn't that a large codebase has bugs — every large codebase does. The issue is that the bugs are of a category that Rust's type system is specifically designed to prevent. Undefined behavior in safe Rust isn't a "minor issue" or a "we'll fix it later" problem. It represents a fundamental misuse of the language's safety model.

To understand why this matters, consider what miri actually checks for. Miri catches things like: reading uninitialized memory, use-after-free through raw pointer manipulation disguised behind safe abstractions, data races in concurrent code, out-of-bounds memory access, and violations of Rust's aliasing rules (the "stacked borrows" or "tree borrows" models). These aren't style issues. They're the kind of bugs that lead to security vulnerabilities, data corruption, and crashes that only manifest under specific conditions — often in production, rarely in tests.

The Hacker News discussion surfaced a recurring tension in the Rust ecosystem. Several commenters pointed out that large-scale rewrites often introduce UB when teams port patterns from C/C++ or Zig directly into Rust without fully internalizing Rust's ownership model. The temptation is to reach for `unsafe` to make things work, or worse, to construct safe-looking abstractions that actually violate invariants. One common pattern: building a safe wrapper around raw pointer arithmetic that technically compiles but violates stacked borrows rules — miri catches this, the compiler does not.

This incident is a case study in why "rewrite it in Rust" is not a magic incantation for memory safety. The safety guarantees only hold if the code actually respects Rust's invariants. A Rust codebase with UB in safe code is arguably *worse* than a C codebase with known unsafe regions, because Rust's safety promise creates a false sense of security. Developers downstream assume safe Rust code is, well, safe.

The community reaction has been split along predictable lines. Rust advocates argue this validates the importance of running miri as part of CI — a practice the Rust project itself follows rigorously. Skeptics see it as evidence that Rust's complexity makes correct code harder to write than advertised. Both perspectives have merit, but the more useful observation is structural: miri found the bugs. The tooling worked. The question is whether the Bun team integrates miri into their workflow going forward.

What this means for your stack

If you're running Bun in production, the immediate risk depends on which components have been migrated to Rust and whether those Rust paths are exercised in your workload. UB doesn't mean "will crash" — it means "behavior is not defined by the language specification," which ranges from "works fine on your machine" to "silently corrupts memory under specific optimization levels or CPU architectures." The practical advice: pin your Bun version, monitor the issue for upstream fixes, and don't rush to adopt Rust-backed Bun builds until miri passes clean.

For teams considering their own Rust rewrites, this is a sobering data point. Miri should be a non-negotiable part of your CI pipeline for any Rust code that touches FFI, raw pointers, or custom data structures. Running `cargo miri test` adds time to your CI but catches an entire category of bugs that are invisible to the compiler and conventional tests. The Rust project's own standard library runs miri in CI — if the stdlib needs it, your code does too.

More broadly, this incident reinforces a pattern we've seen repeatedly: the value of a language rewrite is not the language itself, but the engineering discipline the team brings to the migration. Rust doesn't write safe code — developers who understand Rust's invariants write safe code. Teams that port idioms from their previous language wholesale, without investing in miri, clippy, and Rust-specific code review practices, will reproduce their old bugs in a new syntax.

Looking ahead

The Bun team's response to this issue will be more telling than the issue itself. If they integrate miri into CI, fix the identified UB, and treat this as a learning moment, the rewrite can still deliver on its promise. If they dismiss it or paper over it, the Rust rewrite becomes a liability rather than an asset. The JavaScript runtime space is competitive — Deno and Node.js are not standing still — and trust in the foundation matters. For the broader ecosystem, this is a healthy moment: open-source accountability working exactly as designed, with the community catching what internal testing missed.

Hacker News 453 pts 324 comments

Bun Rust rewrite: "codebase fails basic miri checks, allows for UB in safe rust"

→ read on Hacker News
gorjusborg · Hacker News

Here's the thing:I was first interested in Bun because it was written in Zig. I was interested in Zig because I respected Andrew Kelley's decision-making, and his taste matched my own.I got really excited about Bun for many reasons after that, but they essentially came down to a similar ro

smasher164 · Hacker News

What I don't understand is if they were going to translate Zig to unsafe Rust, why not just build a translation tool for it? You could do a one-to-one mapping of language constructs, hardcoding patterns in your codebase, and as one friend put it "Tbh they could've just hooked up zig t

gpm · Hacker News

This issue is misleading.The issue isn't the existence of undefined behavior that miri would catch. The issue is exposing an API that allows undefined behavior from safe code - which miri only catches if you go write the test that proves it.This isn't an all together unreasonable thing to

pohl · Hacker News

This doesn't seem surprising, given the straight translation that they prompted.Couldn't a case be made that it's better to get Bun to the to the language with the stronger type system first and, once there, use that stronger type system as leverage for these kinds of improvements as

mohsen1 · Hacker News

I was a little shocked that they could get it fully working in a week to be honest. My side project is a very similar ambition (https://tsz.dev) but I am in no way claiming success. i keep adding more and more tests to ensure things works. Even after all of TypeScript's own tests pass

// share this

// get daily digest

Top 10 dev stories every morning at 8am UTC. AI-curated. Retro terminal HTML email.