05/03/2024 8 Minutes read

The Bun logo

Recently, Bun has been making headlines! It’s a new, speedy, and user-friendly JavaScript runtime built on the JavaScriptCore engine, the powerhouse behind Safari. Created with the ambitious goal of replacing Node.js, Bun aims to revolutionize server development by simplifying the process with modern approaches and a visionary perspective. It offers a lot of new native tools that ease development, such as:

Native TypeScript Support

Bun natively supports TypeScript, allowing any developer to use it on the fly without the need to implement any configuration rules. It is intended to be an all-in-one tool, so providing this feature is a natural part of its design. By simply running “bun init”, you will get a recommended TypeScript configuration, free for modification.

Hot Reload

During development phases, hot reloading is quite vital when making repeated changes, as manually restarting the server or code can quickly become exhausting. Bun understands this and has implemented a hot reloading system — one dedicated to HTTP servers that is automatic, and another dedicated to stand-alone code (scripts, etc.) that is activated using the “ — hot” option.

Automatic Installation/Import

Bun has its own module resolution system. If no specifications have been found at startup related to NPM or Node, Bun will automatically use its in-house system, which involves a “global” folder containing all dependencies installed automatically if they are found in imports.

So, it will be possible, from the dependency imports in your files, to import a package by specifying the version (or not) and to have an installation without going through the step of specifying it in a JSON file. Here are some examples:

Example of automatic installation definitions from Bun documentation

The interest one could find in such a feature would be to no longer need to define dependencies in advance in a file all at once, to provide functional and ready-to-use code without the need to go through the usually dedicated dependency file (such as package.json). Furthermore, each dependency is saved in the same location on the disk, allowing multiple Bun projects installed on the same machine (for local development) to benefit from a shared cache.

However, there are things to be aware of. For dependencies targeting the latest version, they will only be updated every 24 hours (if the cached version is older than 24 hours, and if a new version is released in the meantime, the automatic installation won’t fetch it). Additionally, no form of auto-completion can be provided since packages are installed/evaluated at runtime, not beforehand.

In the presence of another resolution model, Bun will respect its presence and maintain exemplary backward compatibility by prioritizing it, leaving automatic installation aside.

A Very Fast Package Manager

Bun has implemented a package system similar to what we know but aims to be much more efficient, serving as a replacement for NPM, Yarn, etc. The official documentation, for example, mentions that dependency installation could be up to 25 times faster!

An available benchmark on the Bun documentation

Thus, for those not interested in automatic installation, accustomed to using NPM, Yarn, or PNPM, this tool will ensure backward compatibility while increasing installation speed. However, access to the lifecycle for scripts will not be guaranteed by default by Bun Install because, according to them, it poses a security risk. Nevertheless, there will be a way to activate this feature by adding a dependency on trusted packages.

Bun Install, of course, supports installations from Git, GitHub, and locally or remotely-hosted tarballs.

Example of dependencies definitions from Bun documentation

One thing to note is that Bun’s installer does not generate a JSON file (or any other readable format) when installing dependencies, but rather a binary file. This format was deliberately chosen because, according to Bun’s documentation, using a binary allows for much faster storage and reading of data compared to the traditional way. As a result, to read the dedicated data for dependency management, the lockfile, you’ll need to use the -y option to obtain a yarn.lock (V1) to read its contents.

Bun Shell, the universal shell commander

Bun has introduced Bun Shell, a unique solution that allows — directly in JavaScript — the execution of cross-platform terminal commands. This feature is embedded in the core of Bun and requires nothing special to be activated. Furthermore, libraries like rimraf (a rm -rf that works on both Windows and Linux) and many others will no longer be necessary, as Bun itself will allow the execution of commands that work seamlessly on both Windows and Linux, without the need to manually handle these different platforms. Moreover, we will no longer have to wait for the terminal to load when a command is executed, allowing us to save a few precious milliseconds.

Zig, the core of Bun

Bun has been developed in Zig. This language offers a compelling combination of simplicity, safety, power, and compatibility, making it a promising choice for developers seeking a modern and reliable language for various programming tasks. Its focus on memory safety, expressiveness, and efficiency has attracted a growing community of enthusiasts and potential adopters. All these features provide an extension of functionality beyond JavascriptCore, offering Bun significant performance benefits.

What Else?

It even won the JS Rising Star of 2022 and ended #2 on the 2023 edition.

A proud developer commenting on the first Bun commit: 025fe36

Even though it’s still a relatively new project (development began in April 2021 and its first stable version was released on September 8, 2023), Bun has already won over numerous developers, wondering if they should use it over other runtimes. Its Github repository has already garnered 67K stars — at the time of writing this article.

And its goal for 2024 is quite clear:

Bun, declaring the war to Node.js on X

With every new proposition from the Open-Source community, developers have turned their interest toward this fresh, attractive, and intriguing option. Some are cautious, while others are enthusiastically embracing it. Many questions have arisen, and here, we’ll try to answer one of them.

Bun, faster than Node?

The most recurring point about Bun is speed. The runtime boasts being much faster than Node.js or Deno:

Available benchmarks on the Bun homepage. The sources can be found on the Bun repo.

Also, based on tests we conducted at ekino, we can assert that Bun is drastically faster when it comes to both asynchronous and synchronous file reading. Our test reports demonstrate that Bun can be 2.5 times more efficient than Deno or Node in these use cases:

Performance is measured using Hyperfine, excluding the first 3 warm-up runs for each test to avoid cases where files are not cached on the disk. Conducted on Apple M1 Pro / 16 GB RAM.
And for those who are more visual, here’s a chart summarizing the statistics presented earlier. Conducted on Apple M1 Pro / 16 GB RAM.

Many articles on the internet can be found comparing Bun’s speed to Node’s, showing Bun as the winner. However, there are also use cases where Bun might not be the optimal solution or, at least, is not necessarily faster.

An issue opened to find how and why the evaluated code is slower.

An extremely interesting example is this GitHub issue. The author explains that since migrating to Bun, the code seems to lose performance, which is entirely contrary to their initial intention, perhaps to leverage Bun’s speed advantage. Because many people might overlook a crucial piece of information: Bun doesn’t use the same engine as Node, meaning your code isn’t evaluated in the same way.

Another use case, QRCode generation, has also been questioned in terms of performance in this Medium article which I’d encourage you to explore if you’re interested):

To our astonishment, Bun’s performance lags behind that of Node.js. It’s not 5 times, 2 times, 50%, or even 10% faster than Node.js; instead, it is marginally slower

A dedicated team has been formed on the Node.js side to address any performance gaps compared to competitors. Its role involves taking necessary steps to optimize Node and currently has over 20 developers.

And what about the compatibility?

An important aspect when considering a different server-side JavaScript runtime from NodeJS is ensuring compatibility with the tools we intend to use or those already in our technical stack. Realizing too late in our implementation that a crucial part of our application can’t be handled as expected is something we’d want to avoid.

Even though Bun has recently announced compatibility with most existing frameworks, numerous issues are still open or regularly being created. This is because Bun doesn’t guarantee complete compatibility with libraries designed specifically for Node.

Some of the incomplete APIs.

Additionally, many Node.js APIs that we’re accustomed to are unavailable on Bun. This is an important consideration when assessing the requirements for the tools we intend to implement or modify.

It’s also noteworthy that Bun’s support for Windows is still in its early stages. The Bun project team has released a limited, experimental native build for Windows, but it is not yet recommended for production use. The experimental build is missing some features, and it is not as stable as the macOS and Linux builds. For development phases, they recommend using the Linux subsystem available on Windows (WSL) rather than interacting with Windows directly.

As mentioned previously, code optimized for V8 may not perform well on JavaScriptCore, Bun’s engine. Developers should carefully evaluate performance when transitioning to JavaScriptCore.

Conclusion

Bun is new, recent, and brings a breath of fresh air to the backend world. Unlike Node, Bun comes with a comprehensive developer tooling ecosystem, enhancing the overall development experience. Creations like these are appreciated and encouraged in the Open-Source community, fostering healthy competition that often benefits all parties involved. This new tool is undeniably fast in certain use cases and lays new foundations. Its long-term evolution will be worth monitoring as Open-Source projects often have a cycle of thriving and fading.

Current reports suggest that Bun grapples with issues such as incomplete feature sets, distorted performances based on the context, and occasional compatibility issues with established industry standards. The current state of Bun raises questions about the long-term sustainability and viability of Bun as it doesn’t have a clear and robust business model. With limited resources and numerous issues occasionally raised through GitHub, the future trajectory of Bun remains uncertain.

These factors collectively contribute to an environment of uncertainty, making it unsuitable for deployment in mission-critical scenarios where reliability is important.

Bun attempted to surpass Node.js, and as in any competitive cycle, Node will draw inspiration from what works and undertake efforts to catch up with any potential lag.


Bun: New, fast, but is it stable and complete enough? was originally published in ekino-france on Medium, where people are continuing the conversation by highlighting and responding to this story.