JavaScript’s Newest Framework: Bun. Will It Take Node’s Crown?

What is Bun?

Bun is the newest addition to the JavaScript family. It has been making waves that rival those made by Deno when it came out in 2018. Bun sits in the space between Node and Deno. Bun, like Deno, supports TypeScript out of the box and offers developer-friendly features such as top-level awaits and built-in Web APIs. But, unlike Deno, Bun is intended to be a drop-in replacement for Node, Webpack, Babel, Yarn, and PostCSS — all in one neat package.

How does bun compare to Deno and Node?

While Bun is inspired by Node and Deno, it is also clearly attempting to improve development experience and productivity by providing a batteries-included toolset.

  • Documentation is limited, but Bun’s Discord is very active and a great source of knowledge.
  • No native Windows support (works with WSL, though).
  • Bun can get stuck while installing packages, fetch is not reliable, and, although it never happened to me, Bun can occasionally segfault.
  • Bun is not 100% compatible with Node yet. Not every npm package works. Express, for instance, is not yet functional.
  • Publishing to the npm registry does not work.
  • Various breaking changes will occur before the APIs and the CLI are stable.
  • Fast built-in sqlite3 module (MySQL and PostgreSQL are also planned).
  • Out-of-the-box .env, .toml, and CSS support (no extra loaders required).
  • Built-in framework support and optimizations for React and Next.js
  • Built-in Foreign Functions Interface (FFI) for low-level calls to ABI-supporting languages such as C, Rust, or Kotlin.
  • Option to copy errors as Markdown (for rapid sharing).

Is it really that fast?

Bun was born out of Jarred Sumner’s frustration with the speed, or lack thereof, of a language: “I’ve been so frustrated by how slow everything in JavaScript is. I know JavaScript can be a lot faster”. As a former frontend developer at Stripe, Jarred knows how a fast iteration cycle is essential for productivity.

Benchmarking Bun

Bun’s homepage reports 3 and 4 times improved performance when compared against Deno and Node. Those are impressive numbers that I want to check for myself, so let’s run a few benchmarks across different categories:

  • Bun vs. npm as a package manager.
  • Bun vs. npm as a script runner.
  • Bun vs. npm for CI/CD workflows.
  • Bun vs. Node vs. Deno for copying large files.
  • Bun vs. Node vs. Deno for serving HTTP requests.

Managing packages with Bun

In this first test, we’ll compare how Bun JavaScript fares against npm for creating new projects. As you can see below, npm takes 49 seconds to create an empty React App.

$ time npx create-react-app myapp​Creating a new React app in /code/myapp.​Installing packages. This might take a couple of minutes.Installing react, react-dom, and react-scripts with cra-template...​added 1392 packages in 38s​16.50s user 6.33s system 46% cpu 49.016 total
$ time bun create react myapp
[package.json] Detected React - added "react-refresh"

bun install v0.1.4
🔍 Resolving [1/4]
[29.00ms] git
+ react-refresh@0.10.0
+ typescript@4.7.4
+ react@18.2.0
+ react-dom@18.2.0
+ web-vitals@2.1.4

8 packages installed [2.39s]

2.48s user 0.30s system 66% cpu 4.160 total
  • npm installed 1,392 packages and the node_modules size is 250 MB.
  • Bun only installed 8 packages, with a total size of 72 MB.
$ bun add react-scripts -d
Bun is 6 times faster than npm for creating a complete React project.

Adding and removing packages with Bun and npm

Next, let’s test how long it takes npm and Bun to add and remove packages. I’ll use an npm-created React App as the testing ground.

Bun is 20 times faster than npm.
  • Bun uses a binary lockfile instead of package-lock.json. But it can print out a Yarn-compatible JSON lockfile with bun install -y.
  • Bun does not install peer dependencies by default like npm. So you might end up with a different set of packages than expected in your node_modules folder.

Bun as a task runner

Unfortunately, Bun’s runtime component has not implemented enough Node APIs to do complex things such as building React projects or running end-to-end tests. Still, there is one area in which Bun can help us right now: as a replacement for npm run.

The difference is due to npm start-up time. The tests themselves are executed with Node on both cases.

Copying large files

In this test, I want to compare how each runtime handles copying large files, which is one area in which a lot of optimization effort was spent.

Bun and Deno take the lead when copying large files.

HTTP Showdown: Bun vs Deno vs Node

Bun’s JavaScriptruntime does include a working HTTP server, which presents a benchmarking opportunity to compare with Node and Deno. For the test, I’ll use Bun’s example scripts to drive the tests. I’ll generate and measure traffic with oha.

Bun is twice as fast as Node and 1.7 times faster than Deno for serving HTTP requests on my dev machine.

Speeding up CI/CD with Bun

We’ve confirmed that Bun can give you an edge on your development machine, but does it make sense to use it to accelerate CI/CD? This is a crucial aspect because the speed of your continuous integration pipeline is a deciding factor for a fast development cycle.

  • master runs all scripts with npm as originally designed.
  • The bun branch replaces npm with Bun. To be clear, we’re only using Bun as a task runner, not as a runtime. The test and build steps are still being executed by Node in both cases.
Replacing npm with Bun speeds up my pipeline by 20%.
  • Instead of caching the node_modules folder, it’s faster to save and restore Bun’s global cache located at $HOME/.bun/install/cache.
  • Bun ships with an experimental test runner, which is supposed to be much faster than Jest. Unfortunately, I wasn’t able to make it work. We’ll have to wait until the bun is out of the oven to try it (pun intended).
  • There’s a lot of potential for improvement. Once Bun runtime can replace Node, CI/CD speed might increase dramatically.

Conclusion

Not only is Bun fast, it feels fast. It feels like you can do anything in under a second.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Semaphore

Semaphore

Supporting developers with insights and tutorials on delivering good software. · https://semaphoreci.com