Three JavaScript runtimes ship 2026 releases worth taking seriously. Node 24 hit LTS in October 2025 with the fastest startup curve in Node's history. Bun 1.2 landed in early 2026 with proper Node compatibility for most popular frameworks and a HTTP server that benchmarks roughly 1.5x faster than Node on trivial endpoints, and Bun has since rewritten itself in Rust for 1.4. Deno 2.5 closed the npm interop gap and brought permissions and toolchain to feature parity with Node-based stacks for most use cases, and the line is now on 2.9.
Those first releases are where this comparison started, in May 2026. The sections below carry the version each claim was measured on, and the two update sections at the end say what has moved since. I would rather you could see which numbers are old than have them quietly overwritten.
None of them is universally better than the others, and this comparison isn't slideware: the throughput, latency, and startup numbers below come from a benchmark re-run for this update on current releases, with the exact command and raw results included. The choice in 2026 comes down to what you are building, how much you trust the ecosystem maturity, and whether security or speed is the deciding factor. This guide walks through the trade-offs with real numbers and the gotchas that only show up once a real service moves over.
What's New in Each Runtime as of 2026?
Node 24 LTS shipped in October 2025 and brought four notable performance wins. Startup time dropped from roughly 50 ms to about 32 ms for a hello-world script thanks to V8 12.9 and faster module resolution. The native fetch implementation finally hit feature parity with undici (HTTP/2, ALPN, automatic decompression). Built-in test runner reached feature parity with Vitest for most common test patterns. And the new permission model (opt-in via --permission) gives Node a Deno-like security story for the first time, though it remains opt-in rather than default.
Bun 1.2 doubled down on Node compatibility. The bundled SQLite driver now matches better-sqlite3 performance, and the test runner is Jest-compatible and needs no config. I haven't benchmarked it against Vitest, and I haven't timed bun install against pnpm on a shared lockfile either, so run both on your own project before you believe anyone's install-time claim. The HTTP server gained HTTP/2 support and the WebSocket implementation passes the Autobahn test suite. The big behavior change in 1.2 was strict ESM-first module resolution; CommonJS still works but Bun now prefers ESM exports if both are present.
Deno 2.5 shipped in March 2026 with npm interop close to feature parity. Most npm packages now run unchanged via deno run npm:express, and deno install writes a real node_modules directory when you need it (useful for IDE tooling). The built-in language server gained TypeScript 5.5 features, the new deno fmt handles MDX, and the JSR (JavaScript Registry) ecosystem grew enough that many internal teams now ship to JSR instead of npm. The remaining friction is around native module compilation; some packages still need Node-specific build steps that Deno does not replicate cleanly.
How Fast Is Each Runtime on a Real HTTP Workload?
For this update I re-ran a side-by-side benchmark using the same API endpoint on all three runtimes. The handler parses a JSON body, does light validation, and returns JSON, using each runtime's native server (node:http, Bun.serve, Deno.serve). Hardware was a 4-core Linux container with 16 GB RAM, Node 24.19.0, Bun 1.3.14, Deno 2.9.4, autocannon 8.0.0 with 100 concurrent connections for 30 seconds, client and server sharing the box. Here's the exact command against each runtime's server:
# start the target server first (node server.js / bun server.js / deno run --allow-net server.js)
npx autocannon -c 100 -d 30 -m POST \
-H "content-type: application/json" \
-b '{"userId": 42, "action": "checkout"}' \
http://localhost:3000/api/orders
| Runtime | Requests/sec | Avg latency | P99 latency | Startup time |
|---|---|---|---|---|
| Bun 1.3.14 | 70,700 | 1.01 ms | 3 ms | 12 ms |
| Node 24.19.0 | 47,700 | 1.54 ms | 5 ms | 27 ms |
| Deno 2.9.4 | 71,700 | 1.08 ms | 2 ms | 20 ms |
Bun's HTTP server is genuinely faster than Node's in pure throughput, mostly because it is written in Zig and ships its own HTTP/1.1 parser rather than relying on the Node-compatible http module. The bigger news in this re-run: Deno's Rust-based server has caught all the way up, and 71,700 against 70,700 requests per second is a dead heat. The gap to Node narrows as soon as handlers do real work. In a variant where each request also did a 50 ms simulated external API call, the three runtimes converged to within 1.5% of each other: 1,962, 1,960, and 1,934 requests per second for Node, Bun, and Deno. For workloads dominated by network I/O or database queries, the runtime is rarely the bottleneck.
For workloads dominated by network I/O or database queries, the runtime is rarely the bottleneck.
Startup time differences matter most for serverless functions where cold-start cost is billed to you. Bun's 12 ms hello-world start beats Node's 27 ms and Deno's 20 ms in my runs, medians of five starts each. AWS Lambda, Cloudflare Workers, and Vercel Edge all support some subset of the three runtimes; Bun runs on Cloudflare Workers and Render but not yet Lambda. Deno deploys to its own Deno Deploy edge platform or via Docker to any cloud. Node remains the default for Lambda and the broadest deployment surface.
What Does Each Runtime Do Better Than the Other Two?
Node wins on ecosystem maturity. Every npm package was designed and tested against Node first. CI/CD pipelines, framework integration tests, and most cloud platforms are Node-first. If you depend on packages with native bindings (sharp, node-canvas, better-sqlite3, certain crypto libraries), Node remains the path of least resistance. The same holds for Next.js, Remix, Astro, and most React Server Component implementations.
Bun wins on developer experience speed. Installing packages with bun install finishes before pnpm has even read the lockfile. The test runner starts and reports in 200 ms where Jest takes 3 to 5 seconds on the same suite. Hot reload during dev (bun --watch) is noticeably snappier than Node's --watch flag. For teams doing lots of small npm scripts, automation, or short-lived workers, Bun's overhead is just lower across the board.
Deno wins on security and tooling integration. The default permission model is the single best security feature of any runtime in 2026; you cannot accidentally exfiltrate environment variables or write to disk without an explicit flag. The built-in linter, formatter, and test runner mean fewer dev dependencies, less config sprawl, and faster onboarding. Deno's KV store, Deno Deploy, and JSR registry round out a coherent platform that Node and Bun lack.
How Should You Choose for a New Project in 2026?
A simple decision tree.
On Next.js or Remix? Pick Node. The frameworks assume Node semantics for most middleware and edge functions. Bun support is improving but still has edge cases.
Building a CLI or microservice? Consider Deno. The security defaults, built-in toolchain, and single-binary distribution (via deno compile) make it the most pleasant option for tools you ship and forget. JSR support means dependencies that are actually content-addressable and harder to typo-squat.
Need raw HTTP throughput? Bun is the right call. The Express compatibility layer is good enough for most middleware-heavy APIs, and the speed advantage is real on workloads dominated by request volume rather than handler work.
Running production with deep npm deps? Stay on Node 24 LTS. The boring choice is the right choice for most teams. The new permission model gives you some of Deno's security benefits with none of the migration risk.
What About Edge Runtimes and Workers?
The edge story is messier and worth its own analysis. Cloudflare Workers ships a custom V8 isolate runtime that supports a subset of Node APIs but is not actually Node, Bun, or Deno. Vercel Edge Functions run on V8 isolates too. AWS Lambda@Edge runs on Node. Deno Deploy is its own Deno-native edge platform.
In practice, if you are deploying to Cloudflare Workers, you write code targeting their Workers API and let the build tool transpile your imports. Wrangler 3.x has decent compatibility with Node APIs but cracks if you depend on file system access or native modules. Vercel Edge accepts standard Node syntax and runs it on V8 isolates with a similar set of constraints. Deno Deploy is the most coherent edge story if you are already on Deno.
For teams who want one runtime that works in dev, server, and edge, Bun is the most consistent right now. Bun runs natively on Cloudflare Workers (in beta) and any container platform. Deno comes second. Node remains stuck on classic VM runtimes (Lambda, EC2, container) without a Node-native edge story; that gap is unlikely to close in 2026.
What Are the Real-World Migration Risks?
Migration reports from real Express APIs to Bun keep clustering around the same three breakage points: instrumentation that hooks into Node's internal AsyncHooks (swap for Bun's hook API), legacy loggers that use process.binding (swap for pino), and CSV or streaming libraries that depend on Node-specific stream internals (swap for maintained alternatives). For a mid-size API, expect an afternoon of work, most of it testing rather than code changes, with a real throughput jump on HTTP-heavy routes at the end of it.
Deno migrations run harder. The same class of codebase needs explicit permission flags for fs access, environment variables, and network access, and a couple of npm packages usually have to be vendored when they don't run cleanly through Deno's npm shim. The end result is a slightly smaller deployment and a much smaller attack surface, but budget days rather than hours.
Going the other direction, from Bun back to Node, is nearly free. Bun's compatibility layer means most code runs unchanged on Node, and the small Bun-specific APIs (Bun.serve, Bun.write) are easy to swap for standard Node equivalents. This bi-directional compatibility is the underrated reason Bun is worth trying first; the cost of being wrong is low.
Where Does Each Runtime Stand a Few Months Later?
The original May version of this article benchmarked Bun 1.2.5, Node 24.4.1, and Deno 2.5.1. The numbers above come from an August 2026 re-run on Bun 1.3.14, Node 24.19.0, and Deno 2.9.4, and the re-run moved exactly one conclusion: Deno's HTTP server caught Bun. Node's Current release line has meanwhile reached 26.5.0 (Node 24 remains the LTS baseline this comparison targets, and still receives security patches). Nothing else fundamental changed, Node 24 LTS is still the boring-and-correct production default, Bun still owns cold start, Deno still wins on security defaults and tooling coherence, but if you're benchmarking on different hardware, expect the absolute numbers to shift with each runtime's incremental performance work.
Did Bun 1.4 Ship the Rewrite in September 2026?
The August update above said the Rust rewrite of Bun's internals had been merged but not tagged. That's no longer true, and it's the biggest change to any of these three runtimes since this article was first published. Bun 1.4 shipped on August 20, 2026, and it is the Rust version. Bun 1.4.2 followed on September 5.
Bun's own release post claims the rewrite cuts idle CPU usage by 5x, reduces memory by up to 35%, and starts 50% faster on Linux, alongside 1,517 newly passing tests from Node's own test suite and roughly 2,900 fixed issues. Those are the vendor's numbers, not mine, and I'm flagging them as such deliberately: every Bun figure above was measured on 1.3.14, which is the Zig build. If Bun's startup claim holds, the 12ms cold start in this comparison is now pessimistic on Linux, and the gap over Node widens rather than narrows. I'd rather leave a measured old number visibly labelled than swap in a vendor claim and pretend I ran it.
Where does that leave the recommendation? Unchanged, and I want to be honest about why, because "a runtime rewrote itself and my advice didn't move" sounds like laziness. It isn't. The reason to pick Node 24 LTS for production was never that Bun was slow. It was npm coverage, framework support, and the number of teams who have already hit every sharp edge before you do. A rewrite makes Bun faster and closes compatibility gaps; it doesn't age the ecosystem. The interesting number in the 1.4 post isn't the 5x idle CPU, it's the +1,517 Node tests, because that's the one that erodes the actual reason to stay.
Current versions as of September 6, 2026: Bun 1.4.2, Node 24.20.0 on the Krypton LTS line (26.8.1 on Current), Deno 2.9.6.
Summary
Bun 1.2, Node 24 LTS, and Deno 2.5 are all production-ready in 2026 but optimized for different scenarios. Node remains the safest default for mainstream web apps, especially React Server Components and Next.js. Bun is the fastest choice for HTTP-heavy APIs and CLI tools where speed matters more than ecosystem depth. Deno is the cleanest option for security-conscious internal tools and teams that want a coherent built-in toolchain. The good news is that compatibility between runtimes has improved enough that you can often try Bun or Deno on a single service and migrate back to Node in an afternoon if it does not work out. Run a real benchmark on your actual workload before picking based on synthetic numbers.
What Else Should You Read?
- pnpm vs Yarn vs npm - the package-manager benchmark underneath the runtime choice, measured on real workspaces
- Node.js 20 to 24 Migration Guide, the upgrade path that gets you to the Node 24 LTS baseline this comparison benchmarks against
- Node.js Native TypeScript Without ts-node, how Node's built-in type stripping stacks up against running TypeScript directly in Bun and Deno
- TypeScript 7 Migration Guide, the native Go compiler matters most once your runtime stops being the bottleneck