What is Bun: A High-Performance JavaScript Runtime?

Foroutan Aghdasi
code crafters
Published in
8 min readNov 16, 2023
What is Bun

Bun, a JavaScript runtime, boasts a remarkable speed that is claimed to be 4x faster than NodeJS. It serves as an all-in-one JavaScript runtime and toolkit, allowing you to replace NodeJS in your projects with Bun. This article explores the key features and benefits of using Bun, which ships as a single executable that can be easily installed on your computer.

Moreover, Bun directly runs TypeScript and utilizes the JavaScriptCore engine.

Bun vs. NodeJS Performance:

Run this snippet code on both runtime (Bun and Node) :

console.log("Hello world") // Bun : 8ms.    NodeJs : 32ms

Bun is developed using Zig, which is a low-level, general-purpose programming language. Zig is an imperative, statically typed, and compiled system programming language with the aim of replacing C and C++.

Zig is designed to be both smaller and easier to work with while also providing modern features. As a result, you can expect applications developed in Zig to exhibit impressive speed, a characteristic that naturally extends to Bun.

Bun and Node.js architecture

Why Bun Excels in Speed?

  • Lightweight Design: Bun boasts a lightweight design that translates to a smaller codebase and reduced resource demands. This streamlined architecture empowers Bun to outperform other runtimes, excelling in terms of both speed and memory efficiency.
  • Low-Level Implementation: The Bun runtime is crafted using Zig, a relatively recent low-level programming language. Zig’s attributes grant developers precise control over memory management and execution, enhancing the runtime’s overall efficiency.
  • Performance Optimization: Rather than relying on the V8 engine, Bun harnesses the power of JavaScriptCore from WebKit, renowned for its exceptional performance. This core engine optimizes the execution of JavaScript code, leading to a notable boost in Bun’s runtime speed.
  • Integrated Functionality: Bun offers an array of native tools and features that streamline the development process. These include an in-built bundler, negating the need for external tools like Webpack, native transpiler support for direct TypeScript coding, and a test runner akin to Jest. Moreover, Bun automatically loads environment variables without requiring additional package installations, such as dotenv.

Why Bun Excels in File Read and Write Operations

Bun’s file handling capabilities are nothing short of remarkable, with speeds that outshine NodeJS significantly. It reads files at a staggering 10x faster rate and writes files 3x faster compared to NodeJS.

  • Firstly, Bun compiles source code directly into optimized native machine code using Zig, in stark contrast to Node’s approach of interpreting JavaScript in a virtual machine. This sharp contrast eliminates overhead and unpredictability associated with VM-based execution.
  • Secondly, Bun’s I/O model, built on smol, carries minimal overhead per operation when compared to Node’s event loop and callback-based approach. The integration of async/await syntax further enhances performance, offering developers a streamlined and efficient experience.
  • Thirdly, Bun introduces simple synchronous-style file APIs, such as readFile() and writeFile(), which prove to be faster and more efficient than Node’s asynchronous fs module.
  • Fourthly, Bun takes full advantage of worker threads, allowing intensive I/O operations to be parallelized across all CPU cores, a marked improvement over Node’s single-core approach.
  • Finally, the Bun runtime itself is tailored for blazingly fast developer workflows that involve frequent file operations, particularly tasks like bundling. This optimization ensures a seamless and high-speed development experience.
const file = Bun.file(“package.json”)


await file.text()
await file.json // 10X faster than NodeJs


await Bun.write(“index.html”, ‘Text’) // 3X Faster than NodeJs

A Speedy JavaScript Runtime with Bun PM Package Manager

Bun, the innovative JavaScript runtime, comes complete with an in-house package manager known as Bun PM, setting a new standard in package installation speed. Recent benchmarks reveal that Bun PM surpasses both npm and pnpm with impressive margins:

  • Bun installs a remarkable 29x faster than npm.
  • Bun outpaces pnpm by a notable 17x.

These exceptional performance achievements are made possible through a series of optimizations, each contributing to Bun’s remarkable speed:

  • Parallel Installation: Bun adopts a parallel installation strategy, allowing the concurrent installation of packages across multiple CPU cores instead of a sequential process. This parallelization results in a substantial speed boost.
  • Granular Dependency Tracking: Bun PM distinguishes itself by selectively reinstalling only those packages that have undergone changes, avoiding redundant work in the process.
  • Disk Cache: To further enhance efficiency, Bun caches installed packages globally on disk, enabling the reuse of packages without the need for repeated, scratch-level installations.
  • Native Bindings: In contrast to npm’s child process spawning, Bun PM employs native code bindings, offering a more efficient and streamlined approach.
  • Tree Shaking: During installation, Bun PM has the capability to shake out unused code, unlike npm, which installs entire packages even when only parts are needed.

By harnessing these optimizations, particularly parallelization, Bun PM significantly outperforms npm and pnpm in package installation speed. In one benchmark, it successfully installed the Create React App dependencies in just 3.8 seconds, a stark contrast to npm’s 65 seconds.

This rapid installation capability directly translates to a more efficient developer workflow. Bun eradicates the frustration of extended dependency installation times, empowering developers to construct applications more swiftly.

$ npm create react-app my-app
# 65 seconds later…

$ cd my-app
$ npm start
$ bun create react my-app 
# 3.8 seconds later...

$ cd my-app
$ bun dev

Bun’s Remarkable Speed in Testing

Bun, the cutting-edge JavaScript runtime, features an exceptionally swift test runner, setting new standards in test execution speed. Recent benchmarks confirm the astounding performance of Bun’s test runner:

  • Bun executes tests a remarkable 8x faster than Vitest.
  • Bun surpasses Jest by a remarkable 13x in test execution speed.

Several optimizations contribute to Bun’s exceptional testing speed:

  • Instant Startup: With Bun, tests initiate instantly, eliminating the need to wait for a runtime initialization process.
  • Native ESM Support: Bun directly accommodates ESM syntax without the requirement for code transpilation.
  • Parallel Testing: Tests are executed concurrently across all available CPU cores, maximizing efficiency.
  • Minimal Environment: Only essential components are loaded for the execution of each test file, reducing unnecessary overhead.
  • Rust Core: The runtime is engineered with Rust, prioritizing both speed and efficiency.
  • No Bundling: Tests run directly against native ES modules, bypassing the need for bundling.

By employing these techniques, particularly the rapid startup and parallelization, Bun outperforms existing solutions like Vitest and Jest by a substantial margin. For instance, a test suite that took 13 seconds to complete in Jest might conclude in just 1 second when using Bun. This significantly shortens the test-code-debug cycle, enhancing developer productivity.

Bun’s built-in test runner is just one of the many optimizations that position Bun as a compelling choice for JavaScript development and tooling.

Bun’s Exceptional Performance in WebSockets and APIs

Bun Websocket

Bun excels in processing WebSocket connections, boasting significantly higher throughput compared to Node.js. In benchmark tests, Bun demonstrated the capability to handle over 1 million WebSocket messages per second, while Node.js maxed out at approximately 179,000 messages per second.

Several factors contribute to Bun’s superior WebSocket performance:

Advanced Asynchronous Networking: Bun’s networking architecture is optimized for asynchronous I/O, in sharp contrast to Node.js, which relies on callback-based networking.

Efficient Event Loop: Bun’s scheduler and event loop minimize overhead for each I/O operation, enhancing performance.

Optimized Memory Usage: Bun’s runtime and standard library are meticulously designed to keep memory consumption to a minimum.

These optimizations are particularly crucial for real-time applications such as chat servers. For example, in the case of a chat server sending one message per user per second:

Node.js can handle around 179,000 concurrent users.

In contrast, Bun can effortlessly support over 1 million concurrent users.

Bun’s ability to handle 5x more real-time WebSocket connections than Node.js enables the development of more potent and scalable real-time systems. Combining its raw speed with a modern async/await-focused API, Bun emerges as an attractive runtime for network-intensive applications.

Understanding Bun’s FFI API

Bun offers an FFI (Foreign Function Interface) API that allows for the invocation of code written in languages supporting the C ABI, such as Zig, Rust, C/C++, C#, Nim, Kotlin, and others, directly from JavaScript.

Bun’s FFI simplifies the process of calling code from other languages, like Rust, from within JavaScript. It automatically compiles Rust code into WebAssembly, enabling developers to import Rust files directly into their JavaScript projects. Bun seamlessly handles the compilation of Rust to WebAssembly modules behind the scenes. This provides a straightforward means of accessing high-performance Rust functions from JavaScript without the need for complex setup.

The FFI integration in Bun is designed to be user-friendly, empowering developers to create high-performance web applications that leverage Rust’s speed while preserving JavaScript’s flexibility. By abstracting the complexities of WebAssembly compilation, Bun’s FFI enables developers to concentrate on writing code, rather than dealing with build tools. In summary, Bun’s FFI offers a streamlined approach to harness the advantages of Rust within JavaScript projects. For example:

import {add} from './add.rs' 

console.log(add(1, 2)) // Calls Rust function

Bun’s Built-In Bundler

Bun comes equipped with a versatile, integrated bundler for JavaScript, eliminating the need for additional tools like webpack or Rollup. Below is a comprehensive overview along with practical examples:

By running the ` bun build ` command, you can bundle your code effectively for production. Simply specify an entry point, such as ` src/index.js `, and let Bun take care of the rest. It will diligently analyze imports and bundle all pertinent code into an optimized output file. For example:

// src/index.js
import {add} from './math.js';
console.log(add(1, 2));
// src/math.js
export function add(a, b) {
return a + b;
}

Running bun build src/index.js — out dist/app.js will analyze the imports, bundle all three files optimizing and minifying the output into dist/app.js.

For development, bun run starts a dev server that bundles on demand, enabling rapid iteration as you edit files. Only changed modules are rebundle so builds are extremely fast.

You can configure builds in a bun.config.js file — set input, output directory, plugins and other options. Bun’s built-in bundling provides comparable functionality to tools like webpack but is purpose-built for modern JavaScript bundling needs. And because it is written in Zig, it bundles far faster than JavaScript bundlers.

Compatible

You can install Bun on Linux and Mac But unfortunately can’t install directly on Windows. You can use Linux subsystem on Windows to install Bun.

Bun compatible with commonJS and Esm. It means that you can import and require packages in the same file.

Bun not just a runtime, Bun is NodeJs compatible package manager and Implements around 40 of node’s built-in modules. (except : V8 — Repl — Dgram — HTTP2 — Inspector).

Set Up Bun and Create first project

$ curl -fsSL htps://bun.sh/install | bash 
$ bun -v
$ bun init // (npm): npm init

Bun Create Project from github repo

$ bun create usernameGithub/repo ./directory 

Bun Create React Project

$ bun create react [appName] // (npm): npx create-react-app my-app
$ bun run start // (npm) : npm run start

Bun Create NextJs Project

$ bun create next [appName]  // (npm) : npx create-next-app@latest nextjs-blog
$ bun run dev // (npm) : npm run dev

Bun install package

$ bun install [package-name] // (npm) : npm install [package-name]

--

--