Node.js vs. Deno vs. Bun: Performance & JavaScript Runtime Comparison
September 5, 2023
0 mins readWhy choosing the right JavaScript runtime matters
JavaScript runtimes let you run application code outside the browser. This means you can deliver sites as hosted applications. You can also choose to use JavaScript runtimes for general-purpose scripting.
The runtime you choose will significantly impact the performance of your applications, with request handling and database access speeds varying considerably. It also affects the ease of development and scalability.
Node.js vs Deno vs Bun
Node.js
Node.js is the reigning champion of JavaScript runtimes and was ranked the #1 most popular web technology in 2023 by Stack Overflow developers. It was created by Ryan Dahl and launched in 2009. It's fair to say it revolutionized what you could do with JavaScript when it entered the market. With it, developers can create advanced backend-driven applications using JavaScript.
Today, a vast ecosystem is centered on Node.js, with resources and libraries galore.
Deno
Deno is a Rust-based JavaScript runtime. Like Node.js, it was created and launched by Ryan Dahl
One of its main focuses is to improve Node.js security. In Deno, file, network, and environment access must be explicitly enabled so that security issues typically arise from these areas are less likely. It's also designed to better support JSX and TypeScript and be more oriented toward web standards. To ease deployment, it ships applications as a single-contained executable.
Deno also has a tooling ecosystem around it to enable developers to jumpstart their projects. Fresh is a web framework built for Deno and Lume is their static site generator.
Bun
Bun is the latest runtime competing for your attention. Powered by Zig, it aims to be an all-in-one runtime and toolkit focusing on speed, bundling, testing, and compatibility with Node.js packages. One of its biggest draws is its performance, which is demonstrably faster than that of both Node.js and Deno. This makes it a very attractive proposition if it can deliver on everything.
Regarding its performance, the Bun maintainers provide an example benchmark running an HTTP handler that renders a server-side page with React. This resulted in Bun handling about 68,000 requests per second compared to about 29,000 and 14,000 for Deno and Node.js, respectively. That's quite a difference. Jarred Sumner regularly provides updates on the development of Bun along with recent benchmarks on Twitter, so be sure to follow him to keep up to date with everything.
Bun also includes bundling and task-running features for JavaScript- and TypeScript-based projects. Like Deno, it ships single binaries and has Web API support. It also supports some Node.js libraries with npm compatibility.
Comparing JavaScript Runtimes
Let's examine the differences more closely, focusing on performance, support and community, stability, security, and additional features.
Performance and Speed
Let’s get right to the point: Bun wins. We learned earlier about its performance capabilities and how many requests per second it can handle, which is quite impressive. It's a similar story when it comes to database operations. Average queries per second when loading the Northwind database for SQLite using Bun’s benchmark sample are as follows:
Runtime | Average queries/second |
---|---|
Node.js | 21.29 |
Deno | 43.50 |
Bun | 81.37 |
In another comparison between Node.js, Deno, and Bun, Bun is the fastest at handling concurrent connections. Its requests per second are quite higher, too. For instance, with 10 concurrent connections, Bun achieves 110,000 requests per second, while Node.js achieves 60,000 and 67,000 for Deno. This trend continues with increased concurrent connections and how each runtime performs.
Why is Bun so much faster than Node?
While some contention exists on the effectiveness of the scenarios used for the performance tests, Bun remains the winner. Node.js is last in all of the comparisons, doing particularly poorly when it comes to database speed. Deno and Node.js aren't generally too far apart, and Bun far surpasses them. While Node.js is behind in this regard, Yagiz Nizipli is leading efforts to improve performance in several aspects of Node.js, such as improving URL parsing speeds by ~80-90%.
You can also run the Bun performance tests in your own environment to see how they perform in the following scenarios:
Bun's speed has been a major focus for its developers, and it uses JavaScriptCore, which can be found in Safari. On the other hand, Deno and Node.js use the same V8 JavaScript engine as Chrome.
As well as running fast, Bun is also designed to start quickly — the aim being to remain performant as you spin multiple instances. That makes it a good choice for dynamically scaling applications. If you get a sudden traffic spike and need to create instances quickly, Bun is designed with this in mind to make your services available as fast as possible.
Support and community
All three projects are open source, but not all are supported entirely by the community. The OpenJS Foundation backs Node.js and is strictly community and volunteer-based. For-profit organizations and VC-backed projects support Deno and Bun.
Node.js has an established ecosystem and vast community with online guidance available for every use case. In contrast, Deno and Bun are much newer, so you won't find as much support material. Still, there's no shortage of enthusiastic developers willing to share their knowledge. Also, Deno 1.28 introduced better compatibility with npm packages to make it easier to adopt for developers migrating from Node.js.
Here's a table showing how many questions are tagged for each runtime on Stack Overflow (as of December 2024):
Runtime | Questions tagged |
Node.js | 475028 |
Deno | 1105 |
Bun | 264 |
Every year, there’s a developer survey called the State of JavaScript. In it, there’s a question about which runtimes participants use regularly, for which there were nearly 30k respondents. The results from the survey in 2022 also paint Node.js as the clear leader, with Deno trailing at about 5.3k votes and Bun getting about 1.2k votes.
The 2024 State of JavaScript survey results demonstrate how Bun progressed rapidly to surpass Deno and is clearly now the #2 preference to the Node.js runtime:
The official Node.js docs include various guides, a large API reference, and information on getting started. They also provide information on its dependencies.
Deno's site includes a detailed manual to help you get acquainted with the runtime and use it in your projects. There's also some information on the standard library that developers can use right out of the box.
Stability
As the established player, Node.js offers proven performance, powering 2.1 percent of the world's websites. Since its 1.0 release in May 2020, Node.js has made strides in improving the developer experience while maintaining stability throughout each release so that developers can upgrade with little to no impact.
Bun is currently at version 1.1.42, with new releases as fast as weeks between them, gaining more features, fixes, and Node.js core runtime compatibility.
Security
Security can be weak regarding dependency management with npm and extends to general application security pitfalls when building on top of Node.js. Creating a more secure runtime is one of the driving factors in Deno's creation, which revolved around fine-grained access controls to sensitive APIs such as network requests, file system operations, and other core capabilities. Node.js isn’t far behind on this front. Node.js 20 introduced a permissions model allowing security aspects similar to Deno's.
Making developers aware of common Node.js mistakes and best practices can help you build a secure Node.js application.
Deno closes some of the security concerns inherent in Node.js by requiring explicit permissions for certain actions within the running application. For instance, to enable your application to access reading from the file system, you must initiate it with the --allow-read
flag at startup. You can see a full list of these in their permissions documentation. You can also interact with this permission system at runtime, which enables you to request and revoke permissions programmatically. Be careful of its subprocesses when using the --allow-
flag, as the spawned subprocesses do not have the same security restrictions as the Deno process and can invalidate Deno's security sandbox, leading to privilege escalation.
Additional features
Node.js has introduced some features to align it more with Deno's and Bun's capabilities. It now has a built-in test runner and includes experimental built-in TypeScript support.
Deno includes a dependency inspector and code formatter. Its ability to deploy to a single executable is also a plus. When setting up a server with Deno, the basic method described in its documentation involves pulling code from other places. The code doesn't look much more complicated than with Node.js, but it can feel slightly different as dependencies are loaded via URL.
Here's a cut-down example of the code:
1import { serve } from "https://deno.land/std@0.198.0/http/server.ts";
2
3const handler = async (_request: Request): Promise<Response> => {
4 const resp = await fetch("https://api.github.com/users/denoland", {
5 // The init object here has an headers object containing a
6 // header that indicates what type of response we accept.
7 // We're not specifying the method field since by default
8 // fetch makes a GET request.
9 headers: {
10 accept: "application/json",
11 },
12 });
13
14 return new Response(resp.body, {
15 status: resp.status,
16 headers: {
17 "content-type": "application/json",
18 },
19 });
20};
21
22serve(handler);
Additional features for Bun include a transpiler and package manager. As hinted at in the name, it also includes bundling features, giving you the functionality that would otherwise require another tool, such as Snowpack or rollup.js. It also has a dead code elimination feature through its JavaScript minifier.
If using Bun as a task runner, its speed can be a big advantage. It claims to take ~5 milliseconds to start vs. ~25 milliseconds for Node.js. It may not seem like a significant difference but when you combine this with several tasks you need to run over time it can be impactful to speeding up your development workflow.
Should you use Bun, Deno or Node.js?
Bun is clearly the winner in terms of speed, but as it is still receiving updates for Node.js compatibility, there are risks to using it in production. Will it develop the stability of the other two? Perhaps. Either way, if you're a disrupter looking to make waves by outperforming the competition on speed, Bun offers that opportunity (in most scenarios).
The big advantage of Node.js is its maturity and the size of its ecosystem. You'll find plenty of developers who understand it. However, Deno and Bun have the appeal of being newer, which always excites developers.
Deno also has plenty of advantages over Node.js. Its feature set makes for smoother development and makes it easy to build complex projects at a high quality. It's secure, but while faster than Node.js, it’s a bit slower compared to Bun.
In general, Node.js is still the safest option, with a proven record of success. Deno has much to recommend, with its modern features making it a good choice for developers looking to build something new. And Bun is the tool of choice if you care the most about speed or just want to ride the bleeding edge of new technology.
Snyk Prioritizes Developer Experience
Find out why developer experience is so critical and how Snyk enables a more streamlined developer experience with our newest features.