5 min left
Back to Series

The Stack > Article 21 | Intermediate | 5 min read

Article 21Intermediate5 min read

Claude Code quietly shipped a Rust-rewritten Bun to millions of devices

Simon Willison used binary string analysis to confirm Claude Code now ships on Bun 1.4.0, a Rust-based rewrite of the JavaScript runtime — and nobody noticed until he went looking.


A binary diff view showing runtime internals of a developer tool

Simon Willison ran string analysis on the Claude Code binary and found something Anthropic never announced: recent versions ship on Bun v1.4.0, a preview build of a Rust-based rewrite of the Bun JavaScript runtime — not yet publicly released. He extracted 563 references to Rust source files inside the binary, confirming a claim Bun creator Jarred Sumner had already made about the port.

This article explains what changed under the hood, why nobody noticed, and why a runtime swap of this scale going unnoticed is itself the interesting part.


What actually shipped

Bun started as a JavaScript/TypeScript runtime written primarily in Zig, positioned as a faster alternative to Node.js. The version now inside Claude Code — v1.4.0 — is built on a Rust port of Bun's core, ahead of its official public release (the latest published version at the time was v1.3.14).

Willison didn't get this from a changelog. He got it by running string extraction on the compiled Claude Code binary and finding Rust file paths and symbols baked into the executable, then cross-referencing that against Sumner's public statement that Claude Code v2.1.181 and later shipped with the Rust rewrite.

FactDetail
Runtime swappedBun (Zig core) → Bun (Rust core), v1.4.0 preview
Detection methodBinary string analysis, no source access needed
Confirmed by563 Rust source file references extracted from the binary
Public release statusUnreleased preview at time of discovery
Measured effect~10% startup improvement on Linux

Why swap the runtime at all

A CLI tool like Claude Code launches constantly — every command, every session start pays a startup cost. Shaving even a modest percentage off that cost compounds across millions of invocations a day. A 10% startup improvement on Linux is a small number per-launch and a large number in aggregate.

Think of it like a delivery company quietly replacing its engine supplier mid-fleet. Riders don't notice a different engine under the hood; they notice whether the truck shows up on time. Anthropic (and Bun's maintainers) evidently judged the Rust core stable enough to ship in production ahead of its own public release — a bet that the internals were solid even before the wider Bun user base got to test them.

The transition went largely unnoticed by users — the strongest evidence that a rewrite this size was executed correctly.


Why binary analysis, not an announcement

Runtime internals are usually invisible to a CLI's end users by design — you install the tool, you don't audit its dependency tree on every update. That's exactly why this went unannounced: from Anthropic's side, swapping Bun's internals doesn't change any user-facing behavior, so there's no changelog entry a typical user would expect.

That invisibility is also why detecting it required Willison's approach rather than reading documentation. String analysis on a compiled binary is a blunt but reliable tool: any embedded file path, symbol name, or debug string survives compilation and shows up in a simple strings pass. It's a technique more associated with security research and reverse engineering than with tracking a JavaScript runtime's supply chain — but it works precisely because compiled binaries leak more information than their maintainers intend.


What this reveals about shipping rewrites at scale

A full runtime rewrite — Zig core to Rust core — is the kind of change that would normally warrant a major version bump, a migration guide, and a rollout plan with careful monitoring. Here, it shipped inside a preview build, inside a developer tool, inside another company's product, and the first public confirmation came from a third party's binary forensics rather than either company's own announcement.

That's not necessarily a criticism. It suggests the rewrite's behavioral surface — how Bun executes JS/TS, not how it's implemented — stayed stable enough that swapping the implementation was genuinely transparent to callers. A rewrite that requires an announcement is often one that changed observable behavior somewhere; a rewrite that ships silently and only surfaces via forensic analysis is closer to the ideal outcome for that kind of infrastructure work.

What this means for builders

If you maintain a CLI or developer tool with an embedded runtime, this is a case study in how much internal change downstream users will tolerate silently — provided the interface contract doesn't move. It's also a reminder that your binary's internals aren't private just because you didn't publish them: anyone with strings and patience can and will read them. If there's anything in your build that shouldn't be inferable from the shipped artifact — internal service names, unreleased feature flags, dependency versions you'd rather not confirm — assume it's already legible.

Conclusion

Claude Code has been running on a Rust-rewritten Bun since at least v2.1.181, and the swap was invisible enough that it took a third-party binary analysis to confirm it. The interesting story isn't the 10% startup gain — it's that a rewrite of this scope, shipped ahead of its own public release, produced zero user-visible friction. That's the bar infrastructure rewrites are supposed to clear, and it's rare to see it cleared this cleanly.


Claude CodeBunRustruntimebinary analysisSimon WillisonAnthropic

Up next in the series

Article 22Live

What the Claude Code team’s own workflow reveals about shipping AI tools

A fireside chat with Anthropic’s Claude Code team shows a system prompt cut 80%, automated review handling most PRs, and retention metrics driving feature decisions — a case study in building for a moving-target model.

Claude CodeAnthropicharness engineeringAI tooling