One Node service of mine carried eleven dev dependencies. Bun deletes nine of them.
Speed is the wrong reason to look. Bun 1.0 shipped last week and every benchmark chart is the same shape: tall green bar, short gray bar. Forget the charts. Bun's actual pitch is deletion.
The kill list
One binary replaces an ecosystem of duct tape.
ts-node,tsx, thetsc --watchsidecar: Bun runs TypeScript natively.bun run index.ts, no transpile step, nomoduleResolutionséance.nodemon:bun --watch.dotenv:.envfiles load natively. The most-installed workaround in the ecosystem, gone.jestplusts-jestplus the babel transform between them:bun test, Jest-compatible expectations, TypeScript included. Bun's own numbers on Zod's suite: 13x Jest, 8x Vitest.npm:bun installagainst the same registry andpackage.json.bun run xtakes ~7ms andnpm run xtakes ~176ms. You feel 170ms a hundred times a day.- ESM and CommonJS interoperate in the same file. Bun refused to inherit the holy war.
Where the speed comes from
Two engineering decisions, not pixie dust.
JavaScriptCore, not V8. JSC runs a four-tier pipeline: LLInt interpreter → Baseline JIT → DFG → FTL. Apple tuned it for fast startup and low memory. Its life is Safari page loads. Filip Pizlo's Speculation in JavaScriptCore is the canonical deep dive. V8 tolerates slower warmup for peak throughput. A CLI tool and a test runner live and die in the warmup phase, so Bun's startup edge is structural. Bun itself is written in Zig, and the perf-critical glue is hand-rolled instead of layered over libuv.
bun install skips the copy. Packages land in a global cache (~/.bun/install/cache). They materialize into node_modules via clonefile(2) copy-on-write on macOS and hardlinks on Linux. Bun caches registry metadata in a binary format, and the lockfile (bun.lockb) is binary too. No YAML parse, no JSON diff. That is where the order of magnitude comes from. The tradeoff is a lockfile you cannot read in a PR. bun install -y emits a Yarn-format one for auditing.
The price
- Windows is experimental. The 1.0 build runs the runtime only: no
bun install, nobun test, no bundler. WSL is the honest recommendation for now. - Node compatibility is extensive, not total. Bun does not run Node's internals. It reimplements the
node:*surface natively, so the long tail bites. Native addons want V8 internals, and JSC has a different object model. Packages sniffprocess.versions.node:cryptohas obscure corners. Your express app runs. Your fifteen-year-old SOAP client maybe does not. - A one-company runtime in year one. Oven raised $7M from Kleiner Perkins last summer, and the first public release hit 1.400 points on HN in July 2022. Momentum is real, and so is the bus factor. Price accordingly.
The verdict
The interesting move is strategic. Node won on minimalism and let the community fill the gaps. Ten years later the gaps are the stack: transpilers, test runners, watchers, env loaders. Each one has its own config file and its own way to break. Deno saw this first but asked everyone to change their code. Bun asks you to change nothing and delete things. Better sales pitch.
Spend it today on scripts, CLIs, CI pipelines and greenfield services with boring dependencies. Keep it off the money path this quarter and let the point releases land. The pressure already works. Node shipped node:test in 18.0, --watch in 18.11, and --env-file in 20.6, twelve days before Bun hit 1.0. Three of those deletions now ship inside Node. Funny how that goes.