Bun vs Deno: The Short Answer

Pick Bun for an existing Node.js codebase, or for any job where install time and cold starts get multiplied across hundreds of runs a day. Pick Deno when the code you run includes dependencies you have never read, which for most npm projects means all of them. Speed is the headline in every Bun vs Deno comparison. In our own testing it was also the least decisive factor once a real database entered the picture.

We have benchmarked these two runtimes twice on this site. The first run was on an M3 MacBook Pro for our original three-way runtime review. The second used Bun 1.3 and Deno 2.6 on an M4 Max and an AWS Graviton4 instance for the 2026 Bun, Deno and Node.js benchmark. This page puts only the Bun and Deno results side by side, then works out what the difference is worth in an app that does actual work.

Bun vs Deno Benchmarks: Both of Our Runs

TestBunDenoBun's lead
Hello-world HTTP, M3 run (bombardier)142,000 req/s95,000 req/sabout 49%
Hello-world HTTP, 2026 run114,500 req/s62,100 req/sabout 84%
Cold start, M3 run6ms18ms3x
Cold start, 2026 run4ms15ms3.75x
Read 10,000 small files120ms280ms2.3x
Parse 100MB of JSON85ms195ms2.3x
Install 100 dependencies0.8s8.2sabout 10x
REST API with PostgreSQL and JWT auth12,400 req/s10,600 req/sabout 17%

Bun won every row. Nobody who has followed either project will be surprised.

The two hello-world rows deserve a second look, though. Same two runtimes, same kind of request, and the lead came out at 49% in one run and 84% in the other, because the hardware changed between them and so did both runtime versions. A synthetic HTTP test measures the runtime's server loop and almost nothing else, so small changes in that loop swing the result hard. Any article that quotes a single throughput multiple as the Bun vs Deno number (ours included) is quoting one weather reading.

What the Speed Gap Is Worth Once a Database Gets a Vote

The bottom row of that table is the one we would put on a whiteboard. Our test API ran an Express-compatible framework against PostgreSQL through a connection pool, with JWT auth and JSON serialization on every request. Bun served 12,400 requests per second at a 4.1ms average response. Deno served 10,600 at 4.8ms.

That gap is 0.7 milliseconds per request.

The rest of each response belongs to the Postgres round trip and your own handler code, and neither runtime makes a query plan any faster. If your service idles along at modest CPU, a 17% throughput edge will never show up on a dashboard. If it runs hot across a fleet of instances, 17% becomes a real line on the hosting bill, and that is the one situation where we would let raw request speed make the call.

Cold starts shrink the same way. Bun's 11 to 12 millisecond advantage is easy to feel in a CLI you run forty times an hour. In serverless it sits next to platform overhead that is much larger: in our Supabase vs Firebase vs Amplify benchmark, Supabase Edge Functions (which run on Deno) averaged an 85ms cold start in US-West-2, against 210ms for AWS Lambda on Node.js 20. The spread between those two platforms is 125ms, roughly ten times the distance between Bun and Deno on a bare cold start.

Where Bun's Lead Compounds: Installs and CI

Package installs are the exception. A big one.

In the 2026 run Bun installed 100 dependencies in 0.8 seconds and Deno took 8.2. Bun keeps a global cache and clones files out of it with copy-on-write instead of copying them, which is why the number looks like a typo. Seven and a half seconds means nothing on a laptop, but multiply it by every job in a pipeline and every push from every developer on a monorepo, and it turns into the one Bun advantage that shows up on a CI invoice. If install time is the actual problem and you would rather stay on Node, our pnpm vs npm vs Yarn comparison covers that route.

Security: Where Our Recommendation Flips

Deno starts every script with no file, network, environment or subprocess access, and you grant each one with a flag that can be scoped to specific hosts or paths:

deno run --allow-net=api.stripe.com --allow-read=./data server.ts

Run that, and a compromised dependency deep in your tree can reach Stripe and read ./data. It cannot open your home directory, and it cannot send anything to a host you did not list. Bun has no permission system at all. Like Node.js, it gives every imported package the same access as the user who started the process, so a malicious transitive dependency can read ~/.aws/credentials and post it anywhere it likes.

The honest caveat is that plenty of teams run Deno with -A (allow everything) out of habit, and at that point the sandbox does nothing for them. Used properly, though, it is the only feature in this comparison that changes what a supply-chain attack can cost you, and we weigh it above every number in the table.

TypeScript and Built-In Tooling

Both run .ts files directly with no build step. The difference shows up in type checking: Bun strips the types and runs the file, while Deno can also check them with deno check, so you can drop a separate tsc pass from CI.

The bundled tools lean in different directions. Bun replaces things you already have installed, with bun install standing in for npm and bun test running Jest-style suites; bun build handles bundling if you want it. Deno replaces things you would otherwise have to configure: deno fmt and deno lint cover the Prettier and ESLint setup, and deno bench and deno doc come along too. Both produce single-file executables, via bun build --compile and deno compile. Deno also publishes to JSR as well as consuming npm.

Node.js Compatibility

Bun was designed to run Node projects unchanged and is the closer drop-in; in the original review we estimated about 98% of commonly used npm packages worked on Bun against roughly 95% on Deno. Deno 2 narrowed the gap with package.json, node_modules and node: imports. Native C++ addons are the usual breakage on both. Our own Bun test tripped on bcrypt, and switching to bcryptjs fixed it.

Deployment Options

Deno has a first-party host in Deno Deploy, plus Deno KV, a key-value store that works the same locally and on Deploy. Supabase Edge Functions run on Deno too, so if your backend already lives in Supabase, the runtime decision has been made for you. Bun has no host of its own. Vercel and AWS Lambda support it directly, and it runs anywhere you can ship a container or a compiled binary. Our three-way review listed Cloudflare Workers as reachable from Deno through compatibility and unsupported for Bun, which matters if you are weighing Vercel against Cloudflare Pages at the same time.

A Note on Our Own Numbers

If a future run of ours shows Deno closing to within 10% on hello-world HTTP, nothing in the security section above changes, and that is most of the argument.

Which One We Would Pick

For an existing Express or Hono service whose CI spends real time in npm install, move it to Bun. Expect to swap a native addon or two and little else.

For a new service that fetches or executes anything you did not write (webhook processors, scrapers, plugin hosts, an internal script that pulls a vendor SDK), use Deno with scoped --allow-* flags and keep them scoped when deadlines get tight. That is where we would put our own money.

Supabase Edge Functions: Deno. No debate.

For a command-line tool you will run dozens of times a day, either works, though Bun's 4ms cold start feels nicer under your fingers and deno compile ships a single binary just as cleanly, so pick whichever one the rest of your stack already uses and stop thinking about it.