Bun Migrates from Zig to Rust: What My Real Benchmarks Say About Whether It Matters
The right way to speed up a JavaScript runtime is to ignore the language it's written in. I know that sounds weird coming from someone who's been doing this for 32 years. Let me explain why the most-discussed announcement of the week on Hacker News — 489 points on one thread, 506 on another, about Bun migrating from Zig to Rust — raises more questions for me than it answers, and why I ran my own benchmarks before writing a single word of opinion.
Spoiler: the numbers don't validate the hype or the doom.
Bun Rust Migration Performance: The Context HN Doesn't Give You
The announcement landed as "Bun is being ported from Zig to Rust" and split into two simultaneous threads that together nearly hit a thousand points. For anyone following the JS ecosystem, the news carries weight: Bun was built from scratch in Zig, and that choice was part of its identity. Zig gave Jarred Wimer and the team manual memory control without a garbage collector, native cross-compilation, and startup performance that at the time made Node and Deno look bad in the marketing benchmarks.
My thesis, before showing a single number: the Rust rewrite is not going to materially change what you experience as a Node.js dev adopting Bun in 2025. The bottleneck in your app is not in the runtime's language. It's in how that runtime's architecture is designed — and, more likely, in how the app itself is written.
That doesn't make the news irrelevant. It makes the technical debate misfocused.
What I Actually Ran (Railway + PostgreSQL + Next.js)
I've had Bun running in production for several months. Not as an experiment on a Raspberry Pi — on Railway, with a Next.js App Router API, PostgreSQL via pg, and a couple of lightweight job-processing workers. The setup is exactly the kind of app most Node.js devs have in 2025.
I ran three benchmark suites before and after the announcement. Not before/after the Rust migration — that hasn't landed in stable yet — but Bun 1.1.x versus Node.js 22 on the same hardware, with the same app, to have a real baseline.
# Suite 1: Simple HTTP (no business logic)
# Measuring req/s with autocannon, 10s, 100 concurrent connections
autocannon -c 100 -d 10 http://localhost:3000/api/health
# Bun 1.1.38:
# Req/sec: 41,200
# p99 latency: 8.1ms
# Node.js 22.6:
# Req/sec: 29,800
# p99 latency: 11.4ms
# Suite 2: Simple PostgreSQL query (SELECT by PK, pool of 10 connections)
# Same endpoint, real DB logic
# Bun 1.1.38:
# Req/sec: 9,400
# p99 latency: 31ms
# Node.js 22.6:
# Req/sec: 8,900
# p99 latency: 33ms
# Suite 3: Job processing worker (CPU-bound, no I/O)
# Process 1000 items, measure wall time
time bun run scripts/process-jobs.ts
# real: 0m4.312s
time node --experimental-strip-types scripts/process-jobs.ts
# real: 0m4.891s
The numbers are real. I'm putting them here so we have something concrete to talk about instead of "hello world" benchmarks on a vendor blog.
What the numbers say: Bun wins on bare HTTP with no logic. The advantage evaporates when PostgreSQL enters the picture. On the CPU-bound worker, Bun is ~12% faster — not negligible, but nowhere near the order-of-magnitude jump the headlines suggest.
The Real Argument About Rust vs Zig (And Why It Matters Less Than It Seems)
Here's the problem with the HN debate: most comments argue about language properties — Rust's memory safety, ergonomics, the crates ecosystem, Zig's learning curve — as if any of that was going to change the numbers I showed above.
It's not. At least not in any way you'll actually see.
The performance gap between Bun and Node doesn't come from Zig being faster than V8. It comes from architectural decisions: JavaScriptCore (JSC) instead of V8, a built-in HTTP server without the libuv layer, an integrated native bundler. Those architectural decisions are what move the number in Suite 1. And those decisions stay the same regardless of whether the runtime is written in Zig or Rust.
The Rust rewrite makes sense from the team's perspective. Rust has a brutal library ecosystem, more available devs in the market, better tooling for large-scale projects. For the Bun team it's a sustainability and iteration-speed decision. For you, as the dev adopting the runtime, it's noise.
This reminds me of something I went through during the pandemic when I made my pivot back into software. The first three months learning React, coming from years of infrastructure work, I thought understanding the engine was what made you a better dev. It took me a while to internalize that at high abstraction layers, system architecture matters more than its internals. Same thing here: the runtime's language is an input to the layers below. What you measure in production is the result of ten layers above it.
The Real Gotchas Nobody Mentions in Migration Coverage
If you're running Bun in production today, there are three concrete things that should concern you more than the underlying language:
1. Native module compatibility during the transition
Bun has its own implementation of Node.js APIs, and there are gaps. Some npm modules that use N-API directly still behave differently. I documented something similar when I hit issues with tar files in my Railway pipeline — the full story is here. The same kind of problem can show up if you have dependencies that assume specific V8 or libuv behaviors.
2. Ecosystem lock-in is real
If you start using Bun.file(), Bun.serve(), Bun.$ (the shell API) to simplify code, you're writing code that doesn't run on Node. The migration from Zig to Rust doesn't change this. It's an architectural decision you make when adopting the runtime, not a function of the language it's written in.
3. Startup speed matters less than you think in production
Bun starts ~2x faster than Node. That's real. In a Railway environment with containers that stay alive between requests, you see that 2x exactly zero times during the service's lifetime. It matters on Lambda/Edge. In a persistent container, it's marketing.
How This Connects to My Current Stack
I work with AI agents that generate code and do automated deploys — something I went deep on in the post about agentic coding and keep refining with combined agent loops. When agents generate TypeScript code, Bun is the most convenient runner because native TS support without transpilation removes a real amount of friction.
Does that change with the Rust migration? No. The feature is architectural. The language is irrelevant to the end user.
Same thing when I define specs for agents in YAML — I documented that process here. The runner executing those specs isn't the bottleneck. The quality of the specs is.
And on the data side, when I looked at PostgreSQL backups (barman vs pgbackrest), the runtime language was never the variable. The right tool with the right configuration was.
The pattern is the same everywhere: upper abstraction layers dominate lower ones in the observable result.
FAQ: Bun Rust Migration Performance
Will Bun's migration to Rust improve performance for end users?
Unlikely in the short term, at least in any perceptible way. Bun's performance gains over Node come from JavaScriptCore and HTTP server architecture decisions, not from the runtime's language. Rust may improve the team's iteration speed and memory safety, but that doesn't translate directly into requests/second in your app.
Do I need to migrate my Node.js app to Bun now that the underlying language is changing?
No. If the argument for migrating wasn't compelling before the announcement, the announcement doesn't make it more compelling. The decision to adopt Bun should be based on benchmarks of your specific workload and compatibility of your dependencies.
Why did Bun originally choose Zig if they're now migrating to Rust?
Zig gave the team capabilities that Rust didn't have as mature at the time: simple cross-compilation, direct C interop, and a memory model without Rust's borrow checker complexity. The migration to Rust speaks to the maturity of the Rust ecosystem today and the team's needs at scale — not that the original choice was a mistake.
Will Bun on Rust have better Node.js ecosystem compatibility?
Not directly. Node.js API compatibility is reimplementation work independent of the language. Rust might make that work go faster if the team attracts more contributors, but it's an indirect correlation.
Is it worth using Bun in production right now, during the transition?
Depends on the workload. In HTTP-heavy scenarios with light logic, the numbers are good (see Suites above). For apps with heavy native module dependencies or exotic npm ecosystem requirements, I'd wait for the transition to stabilize. On Railway with Next.js and PostgreSQL, I have it running and haven't had serious surprises — but I'm monitoring it.
What about projects that already depend on Bun-specific APIs (Bun.serve, Bun.file, etc.)?
Nothing in the short term. The migration is internal. Public APIs stay. The real risk is long-term: if the migration introduces regressions or delays features, projects with heavy lock-in feel that more than projects using Bun as a drop-in Node runtime.
My Take: What I Buy and What I Don't
I buy that the migration to Rust is the right decision for the Bun team. The ecosystem is richer, there are more available devs, the tooling for large-scale projects is better. From a project sustainability perspective, it makes sense.
I don't buy the narrative that this is going to be a game changer for devs adopting Bun. The relevant conversation is still the same one we were having before the announcement: does JSC over V8 give you an edge on your specific workload? Is dependency compatibility solid enough? Does the proprietary API lock-in justify the convenience?
What I'd do differently if I were evaluating adopting Bun today: ignore the underlying language entirely and focus on running benchmarks on my real app with my real dependencies. Exactly what I showed above. Twenty minutes of your own measurement is worth more than two thousand points on HN.
The hype and doom over Zig vs Rust are implementor debates, not user debates. And most of us are users.
Original source: Hacker News - Bun is being ported from Zig to Rust / I am worried about Bun
This article was originally published on juanchi.dev
Top comments (0)