JavaScript is the most commonly used language in the world. Node.js has helped it spread more widely. Could a new JavaScript runtime shake things up?
What is Bun, exactly? Is it a framework? A build tool, or a new runtime environment? How will it impact on the average developer’s day-to-day experience?
Bun 1.0 was released to great fanfare on September 8th 2023.
The Bun runtime had been in development by Jared Sumner for 2 years and had picked up a decent amount of buzz from within the JavaScript developer ecosystem.
The new Bun runtime is an audacious attempt to redefine a lot about what we know and understand about current JavaScript tooling and techniques.
It promises blazing-fast performance and a fresh approach to common development tasks.
Some are even claiming it’ll topple the almighty Node.js, a behemoth of the JS ecosystem.
(In this article I’ll be focusing on Node.js as the main Bun competitor, but other runtimes like Deno exist too)
So what exactly is Node.js?
What does it do that the Bun runtime is claiming to improve on?
Node.js acts as the backbone of countless web servers, APIs and powers real time apps and CLI tools across the internet.
Even desktop applications such as Electron use Node.js
Electron powers extremely widely-used developer tools like VS Code and Slack.
So, having the new Bun runtime show up out of the blue to challenge the crown of Node.js – that’s a big deal!
Bun is a new JavaScript runtime designed to make development and processing for JavaScript quicker and easier.
The goal of Bun is to run most of the world’s server-side JavaScript and provide tools to improve performance, reduce complexity, and multiply developer productivity
The Bun runtime is designed as a drop-in replacement for Node.js, claiming to replace a lot of the tasks that Node.js currently carries out.
Bun has nothing to do with the JavaScript that runs inside the browser you’re looking at right now, its target is the computers that run behind the scenes, powering international-scale operations like Netflix, Walmart amongst many others.
The goal is for Bun to be able to seamlessly integrate with the current JavaScript ecosystem and make developer’s lives more straightforward
Bun isn’t here to introduce new problems and challenges – though as with any new developer tool, exactly how seamless the transition will be remains to be seen!
In terms of what makes the Bun runtime different to Node.js, there’s a few standout facts:
Let’s dig into these in more detail…
Unlike Node.js which runs on the Chrome browser’s V8 engine, the Bun runtime makes use of JavaScriptCore, the engine behind Apple’s Safari browser.
Google Chrome’s V8, powering Node.js is the most widely used JavaScript engine.
Most people won’t even be aware of it, running behind the scenes to power nearly all interactive elements in Chrome and Chrome-based browsers such as Brave, Opera and Microsoft Edge.
V8 isn’t an ancient relic though, not by any means.
V8 is fast and efficient and has good reason to be at the cutting edge of web technology.
V8 is known for its speedy performance, also incorporating a non-blocking I/O model that lets it run multiple tasks in parallel – a cornerstone of Node.js’s success and one reason why it has become so widely adopted.
The Bun runtime, on the other hand, running on JavaScriptCore, offers a different set of advantages.
It’s not currently optimized for operation on Microsoft Windows, however, developers on Windows can make use of Windows Subsystem for Linux (WSL) to run it seamlessly within the native Windows OS.
Node.js was created in 2009 by Ryan Dahl using the C/C++ programming language. C/C++ is an industry staple, with the C language existing in one form or another since 1972.
The Bun runtime, on the other hand, has been written in the Zig programming language, a far newer coding toolkit.
Created in 2016 by Andrew Kelley, Zig is renowned for its efficiency and safety and low-level memory control, giving far more leverage over system memory.
Zig has given the Bun runtime’s creators the freedom to explore far more efficient and performant processes. This has delivered benchmarks which have wowed JavaScript developers and helped create a lot of hype around Bun.
Conversely, Node’s languages, C and C++ being much older languages than Zig carry with them a lot of historical baggage that makes memory management more challenging.
V8 was also designed with JavaScript in mind, and garbage collection was introduced as a way of making JavaScript developer’s lives easier, which further slowed Node.js
So one thing that helped Bun gain an advantage was the use of Zig’s more modern approach to avoiding garbage collection.
Avoiding the garbage collector means Bun is spared the unpredictability which comes from automated memory optimisation and can it can rely on a much more streamlined execution pipeline.
This is clearly something that’s given it a huge boost.
To get an idea of just how much of a boost Bun may have been given by the use of Zig, we can run performance benchmark tests.
For example, in a recent comparison test, James Konik noted the following:
For another comparison test, Mayank Choubey noted:
Impressive results! Bun comes out at least 2x faster than its nearest rivals in these tests. That’s a significant difference.
But why hasn’t Node.js made use of similar techniques to streamline its execution processes?
Node.js, running on the V8 engine, has to cope with the drawbacks that come from garbage collection.
The garbage collector works by determining which objects in memory are no longer accessible and then reclaiming that unused memory.
This makes a developer’s job much easier – but the tradeoff is that garbage collection often impacts on performance, delaying execution of time-sensitive functionality in order to keep the memory optimised.
The first modern JavaScript engine, V8 was created in 2008 using C/C++, languages which allow low-level manual control over memory management.
But at the time, many other languages (Java, C#, Python, Ruby) made use of garbage collection and those that didn’t still struggled with giving developers an easy route to clearing out unused objects from memory.
Fast forward to the modern day and we’re seeing more and more languages that avoid garbage collection such as Rust becoming mainstream.
This is partly because developers have access to better development and debugging tools, letting them see in realtime what’s happening to a system’s memory.
So the time seems right for a new player such as Bun to appear on the scene, given the improvements in development toolkits, and bring with it a faster, more efficient approach to JavaScript engine development.
What’s stopping Node.js from taking lessons from Bun and implementing similar performance gains?
The weight of Node.js’ existing ecosystem would make this a formidable task. Since it’s strongly coupled to V8 – an engine designed to make development easier through garbage collection – it would require major architectural changes or a shift to an entirely new engine.
There are community and personal reasons too – many Node.js developers will still value the stability and reliability which Node.js offers, despite a small loss in performance. For them, the upheaval required would be a tradeoff too far.
We’ll need to see how things pan out in the future – perhaps the growth of Bun would prompt Node.js developers to push for more optimisations and performance updates.
If you’re a JavaScript developer, you’ll know all about Node.js and its infamous node_modules folder. node_modules is where Node.js stores all of its dependencies (individual libraries and functions) after running `npm install`.
npm is Node.js’s package manager. It manages dependencies and external files, making sure that whatever your application needs is installed on the local machine, after fetching them from remote repositories.
However, Node.js is not a bundler.
The job of a bundler in a JavaScript runtime would be to optimise and compress all of these distributed packages into a single file, ready for deployment.
So Node.js has historically relied on external tools such as Webpack, Rollup or Parcel to add that functionality.
The size of node_modules has long been a running joke amongst developers too. It’s often enormous and bulky, and a big overhead when it comes to development.
Bun is both a runtime and a bundler. It offers the full package, allowing for both the execution of JavaScript code as well as the management and optimisation of all the third-party dependencies required to run that code.
The Bun runtime also boasts much more streamlined package management. It claims to install packages in a much more granular fashion, including only the portions of packages which are actually needed.
It also installs packages in parallel, meaning faster install times when compared to Node.js
There’s a very specific complaint which developers have about the Node.js ecosystem…
The modern JavaScript environment relies on external code. A lot of this code comes from third-party repositories in the form of modules.
Modules in JavaScript are chunks of code with specific purposes.
Creating a modern JavaScript application involves mixing a large number of these modules together in a single compiled file.
The route to achieving this has historically been a bit of a mess, with developers initially coming up with their own way of achieving this (CommonJS) and later, JavaScript implementing an official way to manage modules, called ESM.
Node.js has tried to balance both worlds. This has unfortunately led to a messy implementation where both formats (.mjs and .cjs files) are supported, but in a way which often leads to conflicts and confusion, with developers having to write code to bridge the two.
Bun tries to fix this by embracing ESM wholeheartedly while also providing an easier route towards importing CommonJS modules.
This has long been a massive headache for developers. If Bun can unite CommonJS and ESM seamlessly, that’s a massive win.
But wait, hold up a second….
Let’s pause for a moment and consider exactly what Node.js is and why it’s earned the position it currently holds.
Node.js is a bridge which lets JavaScript run outside the browser.
Historically, JavaScript has always been a browser-based language. It started out in 1995 as a Netscape project, designed to bring interactivity to the browser experience.
Initially called Mocha, then LiveScript and finally JavaScript (no relation to Java except in name only) it brought a little bit of dynamism to the web, letting users do slightly more useful things.
And that was about it, for a while.
Eventually, JavaScript became much more powerful, allowing the creation of the apps and interactive experiences you find on the web today.
Modern JavaScript is really powerful, controlling data flows, communicating with remote servers, rendering powerful 3D graphics.
Node.js was created in a way to let JavaScript and its power to essentially escape the confines of the browser and take the same functionality to databases, back-end scripts, command line tools – giving it the power than many other languages had enjoyed for decades.
This had a significant impact on the developer ecosystem. Almost overnight, Node.js became a sought-after skill.
This allowed a language previously confined to front-end web experiences to be put to good use powering server-side tools:
You can see now why something like Bun is A Pretty Big Deal.
Anything that could threaten to upset the dominance which Node.js enjoys would be something with a great deal of potential to angle in on a lot of technology.
The potential for Bun to replace much of what Node.js currently does is huge.
I personally don’t think it’ll completely replace it, but it’ll certainly challenge the #1 position which Node.js enjoys in job listings, technology stacks and more.
One significant area where Bun could see gains is in simply making developer’s lives easier.
The daily routine of a JavaScript developer often involves waiting for server-side or command-line JavaScript tasks to finish running.
These are often repetitive scheduled tasks such as:
Even if Bun only shaves off a couple of seconds from each task, it’s a big timesaver in the long run and would be a welcome efficiency gain for the average developer.
That alone would give Bun a large advantage over Node.js.
Even though Bun is a strong contender, Node.js still enjoys the advantage that it’s an extremely battle-hardened system, with countless system-years of operation within some of the most extreme and demanding software environments.
Large companies are going to be slow to move away from tried-and-tested solutions which have worked well for them for years.
Developer convenience will always come second to profits and stability.
So what does it mean exactly when we say that Bun will run on Apple’s JSC engine?
What are the real-world implications of this?
For starters, it could give Safari a much needed boost in the browser rankings.
Though the Bun runtime won’t directly impact on the front-end browser experience, its use of Safari’s JSC engine would help raise Apple’s profile amongst developers as a serious player in the browser world.
Safari is currently trailing behind Chrome by a large margin, but it’s catching up and this could give Chrome some strong (and much-needed) competition.
It’s been a while since there was significant competition in the browser sphere, and this could lead to a welcome shift in the dynamics of front-end web development.
Some are concerned that Chrome’s current dominance is leading to stagnation in web standards and lighting a fire under Google’s tail could be just what’s needed to revitalise this vitally important area of web research and development.
We’d also be likely to see a shift away from Node.js as the de-facto runtime of choice for server-side JavaScript developers, leading to a more diverse range of potential employment opportunties.
On the flipside, this could mean more tech news for the average web developer to keep on top of when applying for positions.
The life of the modern web dev is one of constant learning! Not a week goes by without some new technology rearing its head.
But, whatever the outcome, it’s great to see a new contender on the scene like the Bun runtime, offering an exciting new era of JavaScript development with the potential benefits that increased performance will bring.
With all the hype surrounding any new technology, it’s easy to get caught up and forget that this is still a tool hoping to deliver real results in production environments. We need to keep a level head.
We still need to see how Bun performs in scalable, high-pressure real-world environments, under stress and in the hands of a larger crowd of developers.
Time will tell if the early performance metrics hold up or if the real-world gains are more modest.
Though even a small boost in performance will be welcome, especially if it comes as part of a bundle that reduces overall development complexity.
Ultimately, when it comes down to it, a decision needs to be made – do you stick with tried-and-tested Node.js or move to a newcomer like Bun?
Bun and Node.js are both tools for running JavaScript, but they offer different features.Bun is all about speed and efficiency. It starts up quickly, runs code efficiently, and is designed to be lightweight. It comes with built-in tools like a bundler and transpiler to make development smoother. It uses the JavaScriptCore engine, which is known for its speed.Node.js, on the other hand, has a larger community and supports various programming languages, making it versatile. It uses the V8 engine and has a vast library of third-party tools and resources.
The modern JavaScript ecosystem relies overwhelmingly on external packages and toolkits, almost all of which have been built to work with Node.js.
The Bun runtime has a mammoth task infront of it to ensure that it will be interoperable with them, or at least offer a clear on-ramp process for developers, already weary of “the 149th thing promising to solve all our problems”
Bun definitely has the potential to become the next big thing in the world of JavaScript.
But there’s also the chance it becomes nothing more than another tool to add to the ever-growing compendium of knowledge that the modern web developer is expected to keep on top of.
If it wants to stand up as a challenger to Node.js, it’s going to have to pack a real punch.
Robin is the dedicated developer behind Solarise.dev. With years of experience in web development, he's committed to delivering high-quality solutions and ensuring websites run smoothly. Always eager to learn and adapt to the ever-changing digital landscape, Robin believes in the power of collaboration and sharing knowledge. Outside of coding, he enjoys diving into tech news and exploring new tools in the industry.
If you'd like to get in touch to discuss a project, or if you'd just like to ask a question, fill in the form below.
Send me a message and I'll get back to you as soon as possible. Ask me about anything - web development, project proposals or just say hi!