In the realm of front-end development, maximizing efficiency and performance is paramount. Bun is a JavaScript runtime that offers faster development, testing, running, and bundling for your project. Moreover, it is also known because of its memory efficiency. Bun claims to offer significant improvements in their benchmarks.
It’s also worth paying attention to Bun’s bundler abilities: support for tree shaking, source maps, and minification. Bun was known for some time even though the v1.0 was released only on September 8, 2023, and caused much fuss among the front-end community.
So, after some preparation and research, we decided to use it in our project, and that’s what happened.
Initial data
At Beau, we have several front-end projects with the same architecture. Those projects were built using Nuxt.js, Vue2, and JavaScript. The Yarn was used as a package manager.
Also, our projects have a bunch of tests: unit, e2e, and regression. Those tests use Puppeteer, jest, playwright, and other handy vue libraries for testing.
Why did we decide to use Bun?
Who, as a developer, has never faced the issue of waiting for a project to build or tests to run? This obstacle is relatable to any developer. Moreover, for business, it means money. Our project isn’t an exception. The slower parts of our processes are package installation and running tests. We think that Bun might help us to speed up such processes.
Replacing yarn
First of all, we need to deal with package management. The first step was installing the Bun itself. We can find all the necessary commands in Bun documentation.
curl -fsSL https://bun.sh/install|bash #for macOS, Linux and WSL
Bun also provides a Docker image if it’s necessary.
Let’s check our local speed of package installation with yarn. To be precise about this, we need to clean the yarn cache by using the following command:
yarn cache clean
After this, the pure installation speed will be almost a minute.
Done in 57.33s
So, let’s try installing the packages with bun.
bun install
We can already see a significant difference.
With yarn using a cache, this difference isn’t that impressive.
Done in 23.71s
After installing the packages, Bun will also add the bun.lockb file as an analog of yarn.lock or package.lock. Bun will install dependencies, devDependencies, optionalDependencies, and peerDependecies by default, but because of security reasons, it will skip lifecycle scripts of installed dependencies.
And this might be a problem. These scripts, such as postinstall-scripts or node-gyp, might be an essential part of the package you use. Using Bun, you can see some errors like this:
error: could not determine executable to run for package
Bun has a solution for it. First of all, it already has a list of trusted dependencies. For them, Bun will execute all necessary scripts by default. Otherwise, you can add it to trustedDependecies in your package.json file. In Bun community usage of trustedDependencies is a hot topic. There are several suggestions on how to improve it.
Tests with Bun
After dealing with packages, we need to look at our tests. The first obstacle we faced here was the puppeteer. Puppeteer is a Node.js library that provides a high-level API to control Chrome/Chromium over the DevTools Protocol. It’s usually used for e2e testing or screenshot testing. This library has a script that installs Chromium by default, but we must find a solution as Bun skips it.
As was discussed before, it’s about trustedDependencies. Although Bun already added Puppeteer to the list of trusted dependencies, it still skips the part with chromium installation. Adding this library to trustedDependecies in package.json file doesn’t help. During the test run, no browser was installed. We found an open bug in the Bun repo with similar problems. It ended up with a separate script that installed the necessary browser for Puppeteer. Not a big deal.
The other thing was the collision of webpack package versions, so we had to fix one specific version via the overrides option in the package.json file.
So far, we used Bun for e2e end regression testing. But what about unit tests? Bun has the opportunity to get rid of any test runner because it has all the necessary instruments for it, similar to jest abilities. Unfortunately, it seems not to work with vue-test-utils, which is essential for our project, so we decided to keep it as it was, at least for now.
After running this test, we found that something was wrong with the installed testing libraries and bumped into the following messages:
- Test suite failed to run
Cannot find module '../build/Release/canvas.node'
This time, the solution with trusted dependencies helps us.
GitHub actions
Besides library installation and test running, running projects in dev and production mode didn’t cause any problems, so it is time to look at GitHub actions.
First, we needed to use the official setup-bun GitHub action to use Bun. Second, we needed to rewrite all commands with bun usage instead of npm or npx.
After that, there was a last question. Usually, we need to use some cache mechanism in GitHub actions for package installation. We dived into the documentation and GitHub issues, and according to this fantastic comment, there is no need for that.
Conclusion
Using Bun helped us reach our main goal with minimum effort from our team. We successfully implemented Bun in 2 of our projects, speeding up our pipeline time by 30%.
For me, as a developer, it means the ability to deliver some changes faster without much time for waiting. It allows business to see actual changes more quickly, ultimately saving time and cost. Imagine how Bun might speed up processes on larger projects!
We faced some problems, but all of them had solutions. It’s also worth mentioning that Bun creators and the community are aware of those problems and continue working on solutions.
The next steps for our project will be improvements in tests and their adaptations for our team to use Bun entirely.
It is also worth mentioning a few problems with Bun:
- Windows support is still experimental
- It came out AFTER ChatGPT:) So, no help from AI.
- Bun still cannot completely replace node.js
Top comments (1)
Thank you a lot!