Bun vs Deno vs Node.js: which JavaScript runtime actually wins in 2026? - Botmonster Tech
Bun vs Deno vs Node.js: which JavaScript runtime actually wins in 2026?<br>2026-07-08 16 minutes
Contents
Like what you read?<br>Get new posts on Linux, AI, and self-hosting delivered to your inbox weekly.
Enter your email
Subscribe<br>Short answer: Node.js<br>is still the safe default for production work that needs maximum ecosystem compatibility. Bun<br>has the fastest startup, installs, and test runner , and is the best fit for new projects that prioritize developer experience. Deno<br>is the most secure by default and the best TypeScript-first experience. Since the 2.9 release, it’s also the fastest at raw HTTP throughput on my test bench. All three are production-ready in 2026, so the decision should come down to your constraints rather than benchmark headlines.<br>Single-core HTTP throughput on my test bench. The bars match the measurements below.<br>If you want the longer version, read on. One thing before you do: I didn’t copy the benchmark numbers below from other posts. I ran all three runtimes on the same machine and caught my own load generator lying to me halfway through. Several numbers you’ve probably seen elsewhere didn’t survive the re-measurement.<br>Performance Benchmarks: I Ran Them Instead of Quoting Them<br>Benchmarks are where the runtime debates get loud. The numbers that circulate, including the table I almost published here, are usually stitched together from different people’s tests, on different hardware, from different years. The ratios between the rows were never measured on the same machine, so comparing them is meaningless. Instead of recycling them, I benchmarked all three runtimes myself on one box : a 12-core Linux desktop (kernel 6.17) running Node.js 24.18.0 (the newest LTS), Bun 1.3.14, and Deno 2.9.1, all current as I write this. The HTTP test is a minimal JSON endpoint with per-request JSON.stringify and no framework. The server is pinned to a single core and loaded over 200 keep-alive connections for 15 seconds after a warmup pass. Every number was measured twice and the passes agreed within 2%. Every script, server file, and raw result lives in a companion benchmarks repo<br>, so you can check my work or rerun it on your own hardware.<br>What I measuredBun 1.3.14Deno 2.9.1Node.js 24.18.0HTTP throughput (JSON endpoint, single core)122,170 req/s133,093 req/s47,734 req/sProcess cold start (median of 15 runs)11 ms14 ms21 msCold-cache install, 585 packages5.8 s6.0 s*11.8 s (npm)Warm-cache install, same project0.17 s0.12 s*2.0 s (npm)200 trivial tests across 20 files, native runner0.02 s1.04 s0.14 sJSON.parse on a 3.3 MB payload11.9 ms12.1 ms14.3 msJSON.stringify on the same payload5.5 ms6.5 ms13.6 msIdle memory, plain HTTP server36 MB51 MB49 MBGreen marks the best result in each row, red the worst. * Deno links packages from a global cache instead of materializing the full node_modules tree, so its install does less disk work than npm or bun.<br>The mistake I made first<br>My first throughput run put Bun at 65,600 requests per second and Deno at 65,500 . Two runtimes, two different engines, two completely different HTTP stacks, separated by 0.15%. Numbers that identical are not a result. They are a symptom.<br>The load generator I reached for first was autocannon, which is itself a Node.js program . It tops out around 65,000 requests per second on my machine, so every server faster than that got clamped to the same ceiling. I was benchmarking my benchmark tool. The tell came when I pointed two autocannon processes at the same single-core Bun server. Together they pulled 115,000 req/s out of a server that had just “measured” 65,000. After switching to oha<br>, a load generator written in Rust, both fast runtimes nearly doubled. Node barely moved, because Node really was the bottleneck in its own test. The run.sh in the companion repo<br>now performs this as an automatic sanity check: after measuring, it points two parallel clients at the same server and warns you if their combined total beats a single client by more than 15%.<br>I mention this because plenty of published runtime benchmarks are built exactly this way: a JavaScript load tester, client and server sharing a machine, no sanity check. Four smells worth checking before you trust anyone’s chart, including mine:<br>Two very different systems landing on nearly identical numbers. The harness is probably the ceiling.<br>A load generator written in the same language as the thing being benchmarked.<br>No runtime versions listed. Deno 1.x and Node 18 numbers still circulate as if they were current.<br>A table whose rows come from different sources and different hardware.<br>What holds up and what doesn’t<br>The ranking you see everywhere, Bun first, Deno second, Node third, did not even survive the measurement. On current versions, Deno took the throughput lead: 133,000 requests per second to Bun’s 122,000 . I can put a number on how fast...