---
title: Bun 1.0
description: Bun is stable and ready for production.
date: "2023-09-08T01:40:20+00:00"
authors: [jarred, ashcon, colin]
draft: false
# bannerImage: https://github.com/oven-sh/bun/assets/3084745/379f2213-fd3e-4223-bb8e-25adfa1e61cc
---

{% raw %}

<iframe style="aspect-ratio:16/9;width:100%;" src="https://www.youtube.com/embed/BsnCpESUEqM?si=NMSMbbog3Gh17J4s" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
{% /raw %}

Bun 1.0 is finally here.

Bun is a fast, all-in-one toolkit for running, building, testing, and debugging JavaScript and TypeScript, from a single file to a full-stack application. Today, Bun is stable and production-ready.

**Install Bun**

{% codetabs %}

```sh#curl
$ curl -fsSL https://bun.sh/install | bash
```

```sh#npm
$ npm install -g bun
```

```sh#brew
$ brew tap oven-sh/bun
$ brew install bun
```

```sh#docker
$ docker pull oven/bun
$ docker run --rm --init --ulimit memlock=-1:-1 oven/bun
```

{% /codetabs %}

**Upgrade Bun**

```sh
$ bun upgrade
```

## Bun is an all-in-one toolkit

We love JavaScript. It's mature, it moves fast, and its developer community is vibrant and passionate. It's awesome.

However, since Node.js debuted 14 years ago, layers and layers of tooling have accumulated on top of each other. And like any system that grows and evolves without centralized planning, JavaScript tooling has become slow and complex.

### Why Bun exists

Bun's goal is simple: eliminate slowness and complexity _without_ throwing away everything that's great about JavaScript. Your favorite libraries and frameworks should still work, and you shouldn't need to unlearn the conventions you're familiar with.

You _will_ however need to unlearn the many tools that Bun makes unnecessary:

**Node.js** — Bun is a drop-in replacement for Node.js, so you don't need:

- `node`
- `npx` — `bunx` is 5x faster
- `dotenv`, `cross-env` — Bun reads `.env` files by default
- `nodemon`, `pm2` — built-in watch mode
- `ws` — built-in WebSocket server
- `node-fetch`, `isomorphic-fetch` — built-in `fetch`

**Transpilers** — Bun can run `.js`, `.ts`, `.cjs`, `.mjs`, `.jsx`, and `.tsx` files, which can replace:

- `tsc` — (but you can keep it for typechecking!)
- `babel`, `.babelrc`, `@babel/preset-*`
- `ts-node`, `ts-node-esm`
- `tsx`

**Bundlers** — Bun is a JavaScript bundler with best-in-class performance and an esbuild-compatible plugin API, so you don't need:

- `esbuild`
- `webpack`
- `parcel`, `.parcelrc`
- `rollup`, `rollup.config.js`

**Package managers** — Bun is an npm-compatible package manager with familiar commands. It reads your `package.json` and writes to `node_modules`, just like other package managers, so you can replace:

- `npm`, `.npmrc`, `package-lock.json`
- `yarn`, `yarn.lock`
- `pnpm`, `pnpm.lock`, `pnpm-workspace.yaml`
- `lerna`

**Testing libraries** — Bun is a Jest-compatible test runner with support for snapshot testing, mocking, and code coverage, so you no longer need:

- `jest`, `jest.config.js`
- `ts-jest`, `@swc/jest`, `babel-jest`
- `jest-extended`
- `vitest`, `vitest.config.ts`

While these tools are each good in their own right (mostly), using them all together inevitably creates fragility and a slow developer experience. They perform a lot of redundant work; when you run `jest`, your code will be parsed 3+ times by various tools! And the duct tape, plugins, and adapters required to stitch everything together always frays eventually.

Bun is a single integrated toolkit that avoids these integration problems. Each tool in this toolkit provides a best-in-class developer experience, from performance to API design.

## Bun is a JavaScript runtime

Bun is a fast JavaScript runtime. Its goal is to make the experience of building software faster, less frustrating, and more fun.

### Node.js compatibility

Bun is a drop-in replacement for Node.js. That means existing Node.js applications and npm packages _just work_ in Bun. Bun has built-in support for Node APIs, including:

- built-in modules like `fs`, `path`, and `net`,
- globals like `__dirname` and `process`,
- and the Node.js module resolution algorithm. (e.g. `node_modules`)

While _perfect_ compatibility with Node.js isn't possible — looking at you `node:v8` — Bun can run virtually any Node.js application in the wild.

Bun is tested against test suites of the most popular Node.js packages on npm. Server frameworks like Express, Koa, and Hono just work. As do applications built using the most popular full-stack frameworks. Collectively, these libraries and frameworks touch every part of Node.js's API surface that matters.

{% image src="https://github.com/oven-sh/bun/assets/3084745/e4c4ee5d-a859-4a7b-97f7-9fb477939fe6" caption="Full-stack applications built with Next.js, Remix, Nuxt, Astro, SvelteKit, Nest, SolidStart, and Vite work in Bun." /%}

{% callout %}
**Note** — For a detailed breakdown of Node.js compatibility, check out: [bun.sh/nodejs](https://bun.sh/nodejs).
{% /callout %}

### Speed

Bun is fast, starting up to 4x [faster](https://twitter.com/jarredsumner/status/1499225725492076544) than Node.js. This difference is only magnified when running a TypeScript file, which requires transpilation before it can be run by Node.js.

{% image src="https://github.com/oven-sh/bun/assets/3084745/e65fa63c-99c7-4bcf-950b-e2fe9408a942" caption="Bun runs a \"hello world\" TypeScript file 5x faster than esbuild with Node.js." /%}

Unlike Node.js and other runtimes that are built using Google's V8 engine, Bun is built using Apple's [WebKit](https://webkit.org/) engine. WebKit is the engine that powers Safari and is used by billions of devices every day. It's fast, efficient, and has been battle-tested for decades.

### TypeScript and JSX support

Bun has a JavaScript transpiler that's baked into the runtime. That means you can run JavaScript, TypeScript, and even JSX/TSX files, no dependencies needed.

```sh
$ bun index.ts
$ bun index.jsx
$ bun index.tsx
```

### ESM & CommonJS compatibility

The transition from CommonJS to ES modules has been slow and full of terrors. After ESM was introduced, Node.js took 5 years before supporting it without an `--experimental-modules` flag. Regardless, the ecosystem is still full of CommonJS.

Bun supports both module systems, all the time. No need to worry about file extensions, `.js` vs `.cjs` vs `.mjs`, or including `"type": "module"` in your `package.json`.

You can even use `import` and `require()`, _in the same file._ It just works.

```ts
import lodash from "lodash";
const _ = require("underscore");
```

### Web APIs

Bun has built-in support for the Web standard APIs that are available in browsers, such as `fetch`, `Request`, `Response`, `WebSocket`, and `ReadableStream`.

```js
const response = await fetch("https://example.com/");
const text = await response.text();
```

You no longer need to install packages like `node-fetch` and `ws`. Bun's built-in Web APIs are implemented in native code, and are faster and more reliable than the third-party alternatives.

### Hot reloading

Bun makes it easier for you to be productive as a developer. You can run Bun with `--hot` to enable hot reloading, which reloads your application when files change.

```sh
$ bun --hot server.ts
```

Unlike tools that hard-restart the entire process, like `nodemon`, Bun reloads your code without terminating the old process. That means HTTP and WebSocket connections don't disconnect and state isn't lost.

{% image src="/hot.gif" /%}

### Plugins

Bun is designed to be highly-customizable.

You can define plugins to intercept imports and perform custom loading logic. A plugin can add support for additional file types, like `.yaml` or `.png`. The [Plugin API](/docs/runtime/plugins) is inspired by esbuild, which means that most esbuild plugins will just work in Bun.

```ts
import { plugin } from "bun";

plugin({
  name: "YAML",
  async setup(build) {
    const { load } = await import("js-yaml");
    const { readFileSync } = await import("fs");
    build.onLoad({ filter: /\.(yaml|yml)$/ }, (args) => {
      const text = readFileSync(args.path, "utf8");
      const exports = load(text) as Record<string, any>;
      return { exports, loader: "object" };
    });
  },
});
```

## Bun APIs

Bun ships with highly-optimized, standard-library APIs for the things you need most as a developer.

In contrast to Node.js APIs, which exist for backwards compatibility, these _Bun-native_ APIs are designed to be fast and easy-to-use.

### `Bun.file()`

Use `Bun.file()` to lazily load a `File` at a particular path.

```js
const file = Bun.file("package.json");
const contents = await file.text();
```

It returns a `BunFile`, which extends the Web standard [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File). The file contents can be lazily loaded in various formats.

```ts
const file = Bun.file("package.json");

await file.text(); // string
await file.arrayBuffer(); // ArrayBuffer
await file.blob(); // Blob
await file.json(); // {...}
```

{% callout %}
Bun reads files up to 10x times [faster](https://twitter.com/jarredsumner/status/1513878964531519494) than Node.js.
{% /callout %}

### `Bun.write()`

Use `Bun.write()` is a single, flexible API for writing almost anything to disk — string, binary data, `Blobs`, even a `Response` object.

```js
await Bun.write("index.html", "<html/>");
await Bun.write("index.html", Buffer.from("<html/>"));
await Bun.write("index.html", Bun.file("home.html"));
await Bun.write("index.html", await fetch("https://example.com/"));
```

{% callout %}
Bun writes files up to 3x [faster](https://twitter.com/jarredsumner/status/1551003252920946688) than Node.js.
{% /callout %}

### `Bun.serve()`

Use `Bun.serve()` to spin up an HTTP server, WebSocket server, or both. It's based on familiar Web-standard APIs like `Request` and `Response`.

```js
Bun.serve({
  port: 3000,
  fetch(request) {
    return new Response("Hello from Bun!");
  },
});
```

{% callout %}
Bun can serve 4x [more](https://github.com/oven-sh/bun/tree/main/bench/react-hello-world) requests per second than Node.js.
{% /callout %}

You can also configure TLS using the `tls` option.

```ts-diff
Bun.serve({
  port: 3000,
  fetch(request) {
    return new Response("Hello from Bun!");
  },
+ tls: {
+   key: Bun.file("/path/to/key.pem"),
+   cert: Bun.file("/path/to/cert.pem"),
+ }
});
```

To support WebSockets alongside HTTP, simply define an event handler inside `websocket`. Compare this with Node.js, which doesn't provide a built-in WebSocket API and requires a third-party dependency like `ws`.

```js
Bun.serve({
  fetch() { ... },
  websocket: {
    open(ws) { ... },
    message(ws, data) { ... },
    close(ws, code, reason) { ... },
  },
});
```

{% callout %}
Bun can serve 5x [more](https://github.com/oven-sh/bun/tree/main/bench/websocket-server) messages per second than `ws` on Node.js.
{% /callout %}

### `bun:sqlite`

Bun has built-in support for SQLite. It has an API that's inspired by `better-sqlite3`, but is written in native code to be faster.

```js
import { Database } from "bun:sqlite";

const db = new Database(":memory:");
const query = db.query("select 'Bun' as runtime;");
query.get(); // => { runtime: "Bun" }
```

{% callout %}
Bun can query SQLite up to 4x [faster](https://github.com/oven-sh/bun/tree/main/bench/sqlite) than `better-sqlite3` on Node.js.
{% /callout %}

### `Bun.password`

Bun also supports APIs for common, but complex things you wouldn't want to implement yourself.

You can use `Bun.password` to hash and verify passwords using bcrypt or argon2, no external dependencies required.

```ts
const password = "super-secure-pa$$word";
const hash = await Bun.password.hash(password);
// => $argon2id$v=19$m=65536,t=2,p=1$tFq+9AVr1bfPxQdh...

const isMatch = await Bun.password.verify(password, hash);
// => true
```

## Bun is a package manager

Even if you don't use Bun as a runtime, Bun's built-in package manager can speed up your development workflow. Gone are the days of staring at that `npm` spinner as your dependencies install.

Bun may _look_ like the package managers you're used to —

```sh
$ bun install
$ bun add <package> [--dev|--production|--peer]
$ bun remove <package>
$ bun update <package>
```

— but it doesn't _feel_ like them.

{% raw %}

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Wow, `bun install` is *ridiculously* fast<br><br>So fast I didn&#39;t believe it worked. I had to stare at the console for a while to fully believe that the package install actually happened<br><br>Feels really nice to use, huge kudos to <a href="https://twitter.com/jarredsumner?ref_src=twsrc%5Etfw">@jarredsumner</a></p>&mdash; Steve (Builder.io) (@Steve8708) <a href="https://twitter.com/Steve8708/status/1561412958722306049?ref_src=twsrc%5Etfw">August 21, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
{% /raw %}

### Install speeds

Bun is orders of magnitude faster than `npm`, `yarn`, and `pnpm`. It uses a global module cache to avoid redundant downloads from the npm registry and uses the fastest system calls available on each operating system.

{% image src="https://github.com/oven-sh/bun/assets/3084745/23cbde35-b859-41b5-9480-98b88bf40c44"  caption="Installing dependencies for a starter Remix project from cache." /%}

### Running scripts

Chances are, you haven't ran a script directly with `node` in a while. Instead, we often use our package managers to interface with the frameworks and CLIs to build our apps.

```sh
$ npm run dev
```

You can replace `npm run` with `bun run` to save 150ms milliseconds _every time_ you run a command.

These numbers may all seem small, but when running CLIs, the perceptual difference is huge. Running `npm run` is noticably laggy—

{% image src="https://github-production-user-asset-6210df.s3.amazonaws.com/3084745/265893417-fbfb4172-5a91-4158-904f-55f2dbb0acde.gif" width="500" /%}

—whereas `bun run` feels instantaneous.

{% image src="https://github-production-user-asset-6210df.s3.amazonaws.com/3084745/265893406-6d7e0e3f-cd70-409c-8c1e-9b5493d18e51.gif" width="500" /%}

And we're not just picking on npm. In fact, `bun run <command>` is [faster](https://gist.github.com/colinhacks/436b6836cd13291a79dd50dcde2d45bf) than the equivalent in `yarn` and `pnpm`.

{% table %}

- Script runner
- Avg. time

---

- `npm run`
- `176ms`

---

- `yarn run`
- `131ms`

---

- `pnpm run`
- `259ms`

---

- `bun run`
- `7ms` 🚀

{% /table %}

## Bun is a test runner

If you’ve written tests in JavaScript before, you’re probably familiar with Jest, which pioneered the "expect"-style APIs.

Bun has a built-in testing module `bun:test` that is fully Jest-compatible.

```js
import { test, expect } from "bun:test";

test("2 + 2", () => {
  expect(2 + 2).toBe(4);
});
```

You can run your tests with the `bun test` command.

```sh
$ bun test
```

You also get all the benefits of the Bun runtime, including TypeScript and JSX support.

Migration from Jest or Vitest is easy. Any imports from `@jest/globals` or `vitest` will be internally re-mapped to `bun:test`, so everything works, even without code changes.

```ts#index.test.ts
import { test } from "@jest/globals";

describe("test suite", () => {
  // ...
});
```

In a benchmark against the test suite for [`zod`](https://github.com/colinhacks/zod), Bun was 13x faster than Jest and 8x faster than than Vitest.

{% image src="https://github.com/oven-sh/bun/assets/3084745/05148dc1-eb42-419b-8c92-8c1b574447e4" caption="Running the test suite for Zod" /%}

Bun's matchers are implemented in fast native code — `expect().toEqual()` in Bun is 100x [faster](https://twitter.com/jarredsumner/status/1595681235606585346) than Jest and 10x faster than Vitest.

To get started, you can speed up your CI using `bun test`. In Github Actions, use the official [`oven-sh/setup-bun`](https://github.com/oven-sh/setup-bun) action.

```yaml-diff#.github/workflows/ci.yml
name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
+     - uses: oven-sh/setup-bun@v1
+     - run: bun test
```

And to make things that even nicer, Bun automatically adds annotations to your test failures, so your CI logs are easy to read.

![](https://github.com/oven-sh/bun/assets/3238291/cb8c6070-4f9c-423c-88bc-6f392adaf66d)

## Bun is a bundler

Bun is a JavaScript and TypeScript bundler and minifier that can be used to bundle code for the browser, Node.js, and other platforms.

```sh#CLI
$ bun build ./index.tsx --outdir ./build
```

It's heavily inspired by [esbuild](https://esbuild.github.io/api/) and provides a compatible plugin API.

```js
import mdx from "@mdx-js/esbuild";

Bun.build({
  entrypoints: ["index.tsx"],
  outdir: "build",
  plugins: [mdx()],
});
```

Bun's plugin API is universal, meaning it works for both the bundler _and_ the runtime. So that `.yaml` plugin from earlier can be used here to support `.yaml` imports during bundling.

Using esbuild's own benchmarks, Bun is 1.75x faster than esbuild, 150x faster than Parcel 2, 180x times faster than Rollup + Terser, and 220x times faster than Webpack.

{% image src="https://github.com/oven-sh/bun/assets/3084745/49fe1da7-b3d7-4b7c-9c9b-26d532c6a57b" caption="Bundling 10 copies of three.js from scratch, with sourcemaps and minification." /%}

Since Bun's runtime and bundler are integrated, it means that Bun can do things that no other bundler can do.

Bun introduces JavaScript macros, a mechanism for running JavaScript functions at _bundle_-time. The value returned from these functions are directly inlined into your bundle.

{% codetabs %}

```js#index.ts
import { getRelease } from "./release.ts" with { type: "macro" };

// The value of `release` is evaluated at bundle-time,
// and inlined into the bundle, not run-time.
const release = await getRelease();
```

```js#release.ts
export async function getRelease(): Promise<string> {
  const response = await fetch(
    "https://api.github.com/repos/oven-sh/bun/releases/latest"
  );
  const { tag_name } = await response.json();
  return tag_name;
}
```

{% /codetabs %}

{% raw %}
<br>
{% /raw %}

```sh#CLI
$ bun build index.ts
// index.ts
var release = await "bun-v1.0.0";
```

This is a new paradigm for bundling JavaScript, and we're excited to see what you build with it.

## Bun more thing...

Bun provides native builds for macOS and Linux, but there's been one notable absence: Windows. Previously, to run Bun on Windows, you would need to install Windows Subsystem for Linux... but not anymore.

For the first time, we're excited to release an experimental, native build of Bun for Windows.

{% image src="https://github.com/oven-sh/bun/assets/3084745/42e0657e-4421-42de-88bc-61a9ec9fa8a7" /%}

While the macOS and Linux builds of Bun are production-ready, **the Windows build is highly experimental**. At the moment, only the JavaScript runtime is supported; the package manager, test runner, and bundler have been disabled until they are more stable. The performance has also not been optimized — yet.

We'll be rapidly improving support for Windows over the coming weeks. If you're excited about Bun for Windows, we'd encourage you to join the `#windows` channel on our [Discord](https://bun.sh/discord) for updates.

## Thank you

Bun's journey to 1.0 would have not been possible without Bun's amazing team of engineers and the growing community of contributors.

We'd like to thank those who helped us get here.

- Node.js & its contributors: Software is built on the shoulder of giants.
- WebKit & its contributors, especially [Constellation](https://twitter.com/Constellation): Thank you for making WebKit faster, you're amazing.
- The [nearly 300 contributors](https://github.com/oven-sh/bun/graphs/contributors) who have helped build Bun over the past two years!

## What's next?

Bun 1.0 is just the beginning.

We’re developing a new way to deploy JavaScript and TypeScript to production. And we’re [hiring](/careers) low-level systems engineers if you want to help us build the future of JavaScript.

You can also:

- [Join](https://bun.sh/discord) our Discord server to hear the latest about Bun.
- [Follow](https://twitter.com/bunjavascript) us on X/Twitter for JavaScript memes and daily updates from Jarred and the team.
- [Star](https://github.com/oven-sh/bun) us on Github — it pays the bills! (/s)

---

**Install Bun**

{% codetabs %}

```sh#curl
$ curl -fsSL https://bun.sh/install | bash
```

```sh#npm
$ npm install -g bun
```

```sh#brew
$ brew tap oven-sh/bun
$ brew install bun
```

```sh#docker
$ docker pull oven/bun
$ docker run --rm --init --ulimit memlock=-1:-1 oven/bun
```

{% /codetabs %}

**Upgrade Bun**

```sh
$ bun upgrade
```

---

### Changelog since v0.8

If you were using Bun _before_ 1.0, there are a few changes since Bun 0.8.

- Next.js, Astro, and Nest.js are now supported!
- The deprecated `bun dev` command has been removed. Running `bun dev` will now run the `"dev"` script in your package.json.

Bun now supports the following Node.js APIs:

- [`child_process.fork()`](https://nodejs.org/api/child_process.html#child_processforkmodulepath-args-options) and IPC.
- [`fs.cp()`](https://nodejs.org/api/fs.html#fscpsrc-dest-options-callback) and [`fs.cpSync()`](https://nodejs.org/api/fs.html#fscpsyncsrc-dest-options).
- [`fs.watchFile()`](https://nodejs.org/api/fs.html#fswatchfilefilename-options-listener) and [`fs.unwatchFile()`](https://nodejs.org/api/fs.html#fsunwatchfilefilename-listener).
- Unix sockets in `node:http`.

Hot reloading now supports `Bun.serve()`. Previously, this was only possible if the server was defined as a `default export`.

```ts#server.ts
Bun.serve({
  fetch(request) {
    return new Response("Reload!");
  },
})
```

{% raw %}
<br>
{% /raw %}

```sh#CLI
$ bun --hot server.ts
```
