Bun's unreleased Rust port has 13,365 unsafe blocks According to the article, Bun's unreleased Rust port contains 13,365 unsafe code blocks, which were counted using a single ripgrep command and categorized by root cause. The audit found that approximately 9,300 of these unsafe sites could be moved to safe code, leaving around 4,000 that must remain unsafe, with the largest patterns involving raw `*mut Self` state machines and `&self` to `&mut` casts. The analysis was conducted through independent classifiers and adjudicated reviews, with the data snapshot taken from a specific commit before the port has shipped in a release build. unsafe blocks.Bun's Rust port has not shipped in a released build yet. The Bun you install today still runs the original Zig implementation. This audit is the pre-release pass over the port. Every unsafe counted with one ripgrep command, then sorted by what removing it takes — command and raw data at the bottom, re-run it yourself. The bar groups all 13,365 by where each could go. Every site by root cause. Three — performance, the Zig port, the FFI boundary — cover two-thirds. Unsafe per 1,000 lines of Rust, measured the same way in each project. Density tracks how close the code sits to a C boundary: a crate that only binds a C++ engine is densest, a runtime that writes its own engine in Rust is sparsest. Bun keeps its bindings and runtime in one workspace; Deno splits the binding into rusty v8 and writes much of its runtime in TypeScript. Draw your own conclusions. Counted with the measurement command from the methodology section, vendored C/C++ excluded, May 21 2026, commits pinned per row. Lines are Rust source only. Area = unsafe sites. Greener = more of them replaceable. Click a tile for its breakdown. Root cause → pattern → outcome, for every site. Click a node to trace it. The Zig-port and callback unsafe mostly ends up green replaceable ; the FFI unsafe mostly ends up blue stays, behind a wrapper . Six facts about the 13,365 that the raw number doesn't carry. A site counts as fixed only if safe code can't cause undefined behavior in a release build. Debug assertions don't qualify; neither do wrappers that just hide the invariant. Everything else stays unsafe — the blue and gray. The four largest patterns were measured per site; the rest are estimates over verified counts. Expand a row for examples and the fix. Three questions determine most of the ledger, and each one means reading the site. Two classifiers answered independently; an adjudicator settled every disagreement against the code. Where agreement was low, trust the number less. Each pass samples by its own membership rule — the first read 3,531 sites, of which 2,750 are the two largest patterns in the ledger — raw mut Self state machines and &self→&mut casts. The measured ratios apply to the ledger counts, and the steps consume the ledger cells. Eight steps. The first fixes the safe functions that are wrong today — no change to the count. The rest move ~9,300 sites to safe code and leave ~4,000 unsafe. Per-pattern figures are in the ledger above. A snapshot of the Rust port at commit 3eb0fda021 , before it has shipped in a release — counts and line numbers move as the code does. The ground truth is one ripgrep command anyone can re-run, and everything above reconciles to it. Measurement command: Raw data: per-group census reports and adversarial reviews 102 + 102 files · per-site classifications from both independent classifiers plus the adjudicated final 33 × 3 files · the flagged safe-function list with claimed trigger sequences · the synthesis documents this page renders.