What is Bun JS, and why it's here to stay
Bun is an all-in-one toolkit for JavaScript and TypeScript applications. The toolkit includes runtime, package manager, bundler, and test runner.
Bun v1.0 was released only a few days ago, on September 8, 2023, exactly 874 days or two years and four months after its initial commit.
It's a drop-in replacement for Node.js.
Bun is a drop-in replacement for Node.js. Its goal is to eliminate complexity and improve performance.
You can check my post comparing Bun vs Node.js.
It does so by having most of the tooling you'll need baked in, so you don't have to use third-party tools like:
- npx - Bun has
bunx
, which is also 5x faster - nodemon - Bun has a built-in watch mode
- tsc, babel, ts-node, tsx - Bun can run .js, .ts, .cjs, .mjs, .jsx, and .tsx
- esbuilt, webpack, parcel, rollup - Bun has a JavaScript bundler with
esbuilt
compatible plugin API - npm, yarn, .npmrc, yarn.lock, package-lock.json - Bun has a npm compatible package manager that reads your
package.json
and writes tonode_modules
, just like any other js package manager - jest, ts-jest, vitest, jest-extended - Bun is a Jest-compatible test runner with support for mocking, snapshot testing, and code coverage
I always felt overwhelmed by all the modules in the JavaScript space. There is a separate package for everything, and you must know these packages; otherwise, your efficiency will suffer. The JavaScript world desperately needs some package consolidation.
I clearly remember back in the day when I started learning Angular 1, I felt overwhelmed by these modules. There was bower and grunt, which were just a few of the hundreds of packages that were needed to build an app. And now they are not popular anymore. Things are moving fast in the JS world.
Using a tool that consolidates and simplifies development is a breath of fresh air. So, if you use Bun, you don't have to worry or learn the packages mentioned above.
Having these tools built-in feels like the right path forward.
Compatibility with Node.js
Bun is a drop-in replacement for Node.js, which means that Node.js applications and npm modules will work. Node.js modules like fs
, path
and net
are supported. Keep in mind that not everything is supported. You can read more about it - Bun Node.js APIs support.
Bun claims that they have tested the most popular Node.js npm packages, and they should all work.
Performance
Bun starts up to 4 times faster than Node.js. This difference is magnified when running a TypeScript file because in Node.js, running TS requires transpilation, whereas in Bun, it's baked into the runtime. You can run JavaScript, TypeScript, and even JSX/TSX files, without any dependencies needed.
The runtime is built using the Apple WebKit engine, whereas Node.js uses Chrome V8 engine. Apple WebKit engine is used by Safari, Mail, App Store, and many more applications on MacOS.
From my experience, I can say that Safari is pretty fast. On my Mac, I use Chrome, but on my iPhone, I always use Safari since I find it faster than Chrome.
ESM (ECMAScript modules) and CommonJS compatibility
Bun supports both module systems, including using import
and require()
in the same file.
import lodash from "lodash";
const _ = require("underscore");
Web APIs are built-in
There is no need to use ws or node-fetch anymore. Bun comes with standard web APIs that are available in browsers like fetch, Request, Response, and WebSocket. You can directly use
const response = await fetch("https://example.com/");
const text = await response.text();
Built-in SQLite
Bun has built-in full support of SQLite.
import { Database } from "bun:sqlite";
const db = new Database(":memory:");
const query = db.query("select 'Bun' as runtime;");
query.get(); // => { runtime: "Bun" }
Fast native APIs
Bun ships with fast APIs.
Bun.serve()
Bun.serve({
port: 3000,
fetch(request) {
return new Response("Hello from Bun!");
},
});
Bun.serve()
is up to 4 times faster than Node.js
It comes with built-in support for WebSockets.
Bun.serve({
fetch() { ... },
websocket: {
open(ws) { ... },
message(ws, data) { ... },
close(ws, code, reason) { ... },
},
});
Bun's package manager
bun install
is equivalent to npm install
, and it's faster. Bun claims it's up to 30 times faster than npm and yarn (when using cache).
Small but notable features
Hot reloading
Bun has hot reloading, which will watch for file changes and reload your application
bun --hot server.ts
Unlike nodemon
, Bun reloads without terminating the old process, which means HTTP and WebSocket connections won't disconnect.
Plugins
The Plugin API is inspired by esbuild
and most of the esbuild
plugins will work out of the box.
Running scripts
bun run
is a replacement for npm run
and it saves 150ms on each run.
Test runner
As mentioned above, Bun includes Jest compatible test runner in the binary itself.
import { test, expect } from "bun:test";
test("2 + 2", () => {
expect(2 + 2).toBe(4);
});
Bundler
Bun has esbuild compatible bundler.
Windows support is experimental
Currently, only the JavaScript runtime is supported in Windows, and it is in an experimental state due to windows specific constraints.
However, there is active development going on to support Windows better.
Is Bun JS production ready?
Bun is version v1.0, so you can consider it production-ready, but I would not recommend using it in production just yet.
Keep in mind that this is the first stable release, and some significant bugs may be discovered. I would recommend downloading it, playing with it, and maybe deploying something simple on production, but wait a few months before using it for big projects.
Conclusion
Node.js initially made a boom. It was accepted very well, but it started moving slowly and became cumbersome after some time.
Bun, as well as Deno, are welcome to the JavaScript world because they scramble things up and put new energy into the community.
From my initial impressions, I think Bun is here to stay. I quite like the approach they took, and I'm eager to see how it will develop further.