Bun vs Deno: Which JavaScript Runtime to Pick in 2026?
Bun leads on raw speed and cloud primitives; Deno leads on toolchain completeness and production stability. Here is which one to pick for your next project.
By Ethan · Updated May 20, 2026
1,855 words · 10 min read
Pick Bun if you need the fastest possible HTTP throughput, the snappiest cold starts, or a batteries-included runtime that ships S3, Postgres, and Redis clients out of the box. Pick Deno if you want a complete, zero-config toolchain, explicit permission controls, and a native edge-hosting platform. Both run npm packages in 2026 — the choice is about everything else.
Who this is for
JavaScript and TypeScript engineers choosing a runtime for a greenfield project in 2026. If you are migrating from Node.js, this will tell you which path has fewer bumps. If you are already on one of these runtimes and evaluating the other, skip straight to the section that most applies.
Version pins
All findings below are specific to:
| Runtime | Version | Released |
|---|---|---|
| Bun | 1.3.14 | May 13, 2026 |
| Deno | 2.7.0 | February 25, 2026 |
Bun vs Deno Performance
HTTP throughput
The BetterStack benchmark (Bun HTTP Framework Benchmark methodology, Express.js on identical hardware, 2026) shows a large gap:
| Runtime | HTTP req/s (Express) |
|---|---|
| Bun 1.3.x | 52,479 |
| Deno 2.x | 22,286 |
| Node.js 22 | 13,254 |
Bun is 2.4× faster than Deno on Express and 4× faster than Node.
The TechEmpower FrameworkBenchmarks were discontinued on March 24, 2026. Community benchmarks are now the de facto reference.
Other operations (Bun vs Node.js baseline)
Bun’s internal clients beat their Node.js ecosystem equivalents by significant margins:
| Task | Bun vs equivalent Node package |
|---|---|
| S3 reads | 5× faster than @aws-sdk/client-s3 |
| Postgres reads | 1.5× faster than node-postgres |
| Redis | 7.9× faster than ioredis |
| DiffieHellman crypto | 400× faster |
Node.js compatibility
Bun
Bun runs its compatibility checks against the Node.js v23 test suite on every commit. Of the commonly used modules:
- Fully implemented:
assert,buffer,console,events(100%),fs(92%),http,net,os(100%),path(100%),stream,string_decoder(100%),url,zlib(98%) - Partially implemented:
async_hooks,child_process,cluster,crypto,http2(95.25% of gRPC tests),https(Agent not always used),module,process,tls,util,v8,vm,worker_threads,inspector - Not implemented:
node:repl,node:trace_events(usebun:sqlitein place ofnode:sqlite)
Notable: node:cluster load-balancing across processes is Linux-only via SO_REUSEPORT. V8 heap snapshots use JavaScriptCore’s wire format, not V8’s — this breaks some profiling workflows.
Deno
Deno 2.0 landed full package.json, node_modules, and npm: specifier support. As of v2.7:
- Fully supported (22 modules):
assert,buffer,child_process,console,crypto,events,fs,module,os,path,readline,sqlite,stream,string_decoder,test,timers,tty,url, and others - Partially supported (16 modules):
async_hooks,dgram,dns,http,http2,https,net,perf_hooks,process,tls,util,v8,vm,worker_threads,zlib,inspector - Non-functional stubs (6 modules):
cluster,domain,repl,sea,trace_events,wasi
Deno fully supports node:sqlite and node:test — Bun shows those as red or partial. Bun has the edge on native addons: its V8 C++ API compatibility layer handles .node files better than Deno’s --unstable-node-addons flag.
Practical bottom line: both run Next.js, Astro, Remix, SvelteKit, Express, Prisma, and gRPC without patches. Complex native addons work better in Bun.
For a head-to-head look at each runtime against Node.js, see Bun vs Node.js and Deno vs Node.js.
Ecosystem
Package management
Bun ships bun install, bun add, bun remove, bun audit, bun why, and dependency catalogs for monorepos. Since 1.2, the default lockfile is bun.lock (JSONC, human-readable) rather than the old binary bun.lockb. bun install is 30% faster in 1.2 compared to 1.1.
Deno ships deno add / deno remove and integrates with both package.json and deno.json. deno install benchmarks at 15% faster than npm cold-cache and 90% faster warm-cache.
Deno’s JSR registry (jsr.io) is a TypeScript-native publishing platform: packages ship TypeScript source plus type info, so there are no separate @types/* packages. In 2026 it is gaining traction but npm’s 2 million+ packages remain the default pool for both runtimes.
Developer experience
Toolchain comparison
| Tool | Bun 1.3 | Deno 2.7 |
|---|---|---|
| TypeScript (native) | ✅ | ✅ |
| Test runner | ✅ bun test | ✅ deno test |
| Bundler | ✅ bun build | ✅ deno bundle (restored in 2.4) |
| Formatter | ❌ use Biome/Prettier | ✅ deno fmt (HTML, CSS, YAML, TS) |
| Linter | ❌ use ESLint/Biome | ✅ deno lint (plugin API since 2.2) |
| REPL | ✅ (native since 1.3.10) | ✅ deno repl |
| Security model | ❌ unrestricted | ✅ explicit permission flags |
Bun’s test runner is mature: --parallel, --isolate, --shard, inline snapshots, expectTypeOf(), and VS Code Test Explorer integration. The absence of a built-in formatter and linter is not catastrophic — Biome covers both — but it is a gap.
Bun 1.3 also added a zero-config HTML dev server with HMR:
bun ./index.html
That command starts a dev server. No config file needed.
Code examples
HTTP server
// Bun 1.3 — native API
Bun.serve({
port: 3000,
routes: {
"/": new Response("Hello from Bun!"),
"/api/users": {
GET: async () => Response.json({ users: [] }),
},
"/api/users/:id": async (req) => {
const { id } = req.params;
return Response.json({ id });
},
},
});
console.log("Listening on http://localhost:3000");
// Deno 2.x — native API
Deno.serve({ port: 3000 }, (req) => {
const url = new URL(req.url);
if (url.pathname === "/") return new Response("Hello from Deno!");
if (url.pathname.startsWith("/api/users")) {
return Response.json({ users: [] });
}
return new Response("Not Found", { status: 404 });
});
File read
// Bun
const file = Bun.file("./data.json");
const data = await file.json();
const stat = await file.stat();
console.log(stat.size);
// Deno
const text = await Deno.readTextFile("./data.json");
const data = JSON.parse(text);
const stat = await Deno.stat("./data.json");
console.log(stat.size);
Test runner
// Bun — bun:test
import { test, expect } from "bun:test";
test("add numbers", () => {
expect(1 + 1).toBe(2);
});
test("async fetch", async () => {
const res = await fetch("https://example.com");
expect(res.status).toBe(200);
});
// Deno — deno test
import { assertEquals } from "jsr:@std/assert";
Deno.test("add numbers", () => {
assertEquals(1 + 1, 2);
});
Deno.test("async fetch", async () => {
const res = await fetch("https://example.com");
assertEquals(res.status, 200);
});
Deployment
Hosted platforms
Deno has a native hosting story; Bun does not.
Deno Deploy (console.deno.com) runs on a V8 isolate model with faster cold starts than traditional lambda functions and a generous free tier. One important note: Deno Deploy Classic (dash.deno.com) is sunsetting July 20, 2026. If you are on Classic, migrate to the new console before that date.
Bun deploys as a Docker container or via platforms that support custom runtimes: Fly.io, Render, Railway, Vercel (Vercel adopted Bun natively for Next.js deployments in late 2025). No official edge hosting service from Oven/Anthropic has launched as of May 2026.
Edge runtimes
| Platform | Bun | Deno |
|---|---|---|
| Cloudflare Workers | ⚠️ Use Bun as bundler; Workers run V8 isolates | ✅ Official tutorial + docs |
| AWS Lambda | ✅ Custom layer or Docker | ✅ Docker or WASM |
| Vercel | ✅ Native Next.js | ✅ |
| Supabase Edge Functions | ❌ | ✅ Powered by Deno |
| Deno Deploy | ❌ | ✅ Native |
For Cloudflare Workers deployments, Deno has official documentation and an explicit tutorial. Bun can produce the output bundle but the Workers runtime itself is V8-based — you are not running Bun in production there.
Stability
Open issues (GitHub, May 2026)
| Metric | Bun | Deno |
|---|---|---|
| Stars | 92,079 | 106,790 |
| Open issues | 6,983 | 2,257 |
Deno has 3× fewer open issues despite being further ahead in stars. Bun ships fast and accumulates more unresolved bugs. Neither is alarming for non-cutting-edge usage, but the gap is meaningful if you are running production workloads and cannot tolerate surprise breakage.
Release cadence
Bun: aggressive. Major releases (1.1, 1.2, 1.3) roughly quarterly; weekly or biweekly patches.
Deno: monthly major point releases — 2.1 through 2.7 shipped in about nine months. Deno introduced an LTS model in 2.1 with 6-month bug-fix windows. If you need a stable target for enterprise deployments, Deno’s LTS track is the only option between the two.
Governance
| Aspect | Bun | Deno |
|---|---|---|
| License | MIT | MIT |
| Owner | Oven (Anthropic subsidiary since Dec 2, 2025) | Deno Land Inc. |
| Founder | Jarred Sumner | Ryan Dahl (original Node.js creator) |
Bun joined Anthropic on December 2, 2025. Anthropic uses Bun to power Claude Code and the Claude Agent SDK — significant production validation and financial backing. The tradeoff is single-entity concentration risk: one company controls the runtime, the primary hosting integrations, and the main production use case.
Deno Land is VC-backed and profitable from Deno Deploy SaaS. Ryan Dahl created Node.js before building Deno, which gives the project credibility in the “long-term runtime thinking” category. Neither project has an OpenJS-foundation-style governance model.
Verdict
Pick Bun if:
- Raw HTTP throughput matters — 52,479 req/s vs 22,286 req/s is not marginal
- Fast cold starts are critical (serverless, CLI tools) — Bun’s JavaScriptCore engine prioritises startup speed
- You want built-in S3, Postgres, and Redis clients with no extra packages
- You need a full-stack dev server with zero-config HMR
- You are building standalone executables compiled from TypeScript
- Your team is on the Anthropic/Claude Code toolchain already
- You need a closer Node.js drop-in (fewer stub modules, better native addon support)
Pick Deno if:
- You want one binary that formats, lints, bundles, and tests — no separate tools
- Security matters: explicit permission flags catch accidental file or network access
- You want native edge hosting with no DevOps overhead — Deno Deploy is the easiest path to global deployment
- You need an LTS track for enterprise or regulated workloads
- You are publishing TypeScript libraries and want JSR’s type-in-registry model
- You are deploying to Supabase Edge Functions or want the cleanest Cloudflare Workers path
- Fewer open bugs matters more than peak performance
Caveats
These benchmarks come from BetterStack’s 2026 test run using Express.js. TechEmpower, historically the most rigorous benchmark, was discontinued March 24, 2026, so independent community benchmarks are now the best data available.
Neither runtime is Node.js. Both have partial module coverage. Before committing, check your critical dependencies against each runtime’s compatibility matrix (Bun, Deno).
This article contains affiliate links to Cloudflare Workers. toolchew earns a commission if you sign up through those links.
References
- Bun v1.3 release — static routes, Redis, SQL, standalone executables
- Bun v1.2 release — S3, Postgres, lockfile changes
- Bun Node.js compatibility — module-by-module status
- Deno 2.0 announcement — npm/Node compat, JSR, LTS
- Deno 2.7 release — Temporal, Windows ARM
- Deno Node API reference — module support matrix
- Deno Deploy docs — Classic sunset July 20, 2026
- BetterStack benchmark — HTTP req/s comparison (2026)
- Bun joins Anthropic — acquisition announcement, Dec 2, 2025