Bun has joined Anthropic — and Anthropic is betting on Bun
Bun v1.4.4 bun fmt: a Prettier-compatible formatter built into Bun. →

Bun is a fast
JavaScript runtime
& toolkit. All in one.

Runtime, package manager, test runner, bundler, type checker and formatter in a single binary. Use bun install or bun test in an existing Node.js project, or run the whole thing on Bun.

curl -fsSL https://bun.sh/install | bash
View install script ↗

Installing a Next.js app

warm cache · seconds (lower is better)

bun
v1.4
0.21s
yarn
v1.22.22
1.76s
pnpm
v11.21.0
1.92s
npm
v12.0.2
4.45s
T3-stack app, 25 direct dependencies, ~220 packages in the lockfile · warm cache · lockfile present · node_modules removed · Linux x64, EPYC 9R14 · every package manager at defaults · medians of 3reproduce
Installing a Next.js app — T3-stack app, 25 direct dependencies, ~220 packages in the lockfile · warm cache · lockfile present · node_modules removed · Linux x64, EPYC 9R14 · every package manager at defaults · medians of 3
runtimeversioninstall timepeak RAM
bunv1.4210 s12 MB
yarnv1.22.221,760 s205 MB
pnpmv11.21.01,920 s1.4 GB
npmv12.0.24,450 s698 MB

Serving Express over HTTPS

hello-world app · requests per second (higher is better)

Bun
v1.4
48,243
105 MB
Node.js
v26.7.0
25,181
142 MB
Deno
v2.9.5
19,243
176 MB
hello-world app · express 5.2.1 · bombardier -c 50 -d 5s · TLS 1.3 · Linux x64, EPYC 9R14 · medians of 3reproduce
Serving Express over HTTPS — hello-world app · express 5.2.1 · bombardier -c 50 -d 5s · TLS 1.3 · Linux x64, EPYC 9R14 · medians of 3
runtimeversionrequests/secpeak RAM
Bunv1.448,243 req/s105 MB
Node.jsv26.7.025,181 req/s142 MB
Denov2.9.519,243 req/s176 MB

Querying Postgres

100 rows × 100 queries in flight · queries per second (higher is better)

Bun
v1.4
20,243
80 MB
Deno
v2.9.5
10,406
181 MB
Node.js
v26.7.0
10,000
168 MB
SELECT 100 rows · 100 queries in flight · 100k queries total · localhost PostgreSQL 18.3 · Bun.sql vs postgres.js 3.4.9 · Linux x64, EPYC 9R14 · medians of 3reproduce
Querying Postgres — SELECT 100 rows · 100 queries in flight · 100k queries total · localhost PostgreSQL 18.3 · Bun.sql vs postgres.js 3.4.9 · Linux x64, EPYC 9R14 · medians of 3
runtimeversionqueries/secpeak RAM
Bunv1.420,243 queries/s80 MB
Denov2.9.510,406 queries/s181 MB
Node.jsv26.7.010,000 queries/s168 MB

Running a WebSocket chat server

32 clients broadcasting · messages per second (higher is better)

Bun (publish)
v1.4
4.17M
51 MB
Bun (send)
v1.4
159K
37 MB
Deno
v2.9.5
124K
1.2 GB
ws (Node.js)
v26.7.0
123K
78 MB
32 closed-loop clients broadcasting, delivery confirmed per message · ws 8.21.3 on Node.js · Linux x64, EPYC 9R14 · medians of 3reproduce
Running a WebSocket chat server — 32 closed-loop clients broadcasting, delivery confirmed per message · ws 8.21.3 on Node.js · Linux x64, EPYC 9R14 · medians of 3
runtimeversionmessages/secpeak RAM
Bun (publish)v1.44,170,027 msgs/s51 MB
Bun (send)v1.4159,379 msgs/s37 MB
Denov2.9.5124,088 msgs/s1.2 GB
ws (Node.js)v26.7.0123,486 msgs/s78 MB

Used by

Six tools, one binary.
Adopt one, or all of them.

bun install and bun test drop into existing Node.js projects. No runtime switch required.

bun run

Runs JavaScript & TypeScript on JavaScriptCore. Node.js APIs, node_modules and your framework work as-is.

Replacesnodets-nodetsxnodemon

$ bun server.ts$ bun run dev$ bun --watch server.ts
Memory used by the same serversPeak memory while running the Express and WebSocket benchmarks above, lower is better
BunExpress105 MB
Node.jsExpress142 MB
DenoExpress176 MB
BunWebSockets51 MB
ws (Node.js)WebSockets78 MB
DenoWebSockets1.2 GB

Each group has its own scale. Linux x64, EPYC 9R14, medians of 3.

bun install

npm-compatible. Workspaces, catalogs, overrides, patches and a lockfile you can read.

Replacesnpmyarnpnpm

$ bun install$ bun add zod$ bunx prisma generate
Installing the same Next.js app in six situationsLower is better
Situationbunnpmpnpmyarn
First install, everFirst install1.41s18.12s13.49s20.51s
Fresh checkout, warm cacheWarm cache251ms7.61s2.38s1.83s
CI without a cacheCI, no cache951ms4.92s11.69s17.61s
CI with a warm cacheCI, warm cache210ms4.45s1.92s1.76s
node_modules there, cache goneCache cleared12ms384ms399ms212ms
Everything already up to dateNo changes12ms337ms400ms211ms

T3-stack Next.js app, 25 direct dependencies, ~220 packages in the lockfile. bun v1.4, npm v12.0.2, pnpm v11.21.0, yarn v1.22.22. Linux x64, medians of 3.

bun test

Has a Jest-compatible expect(), mocks, snapshots, DOM testing and coverage, and starts in milliseconds.

Replacesjestvitest

$ bun test$ bun test --watch$ bun test --coverage
Running the Zod test suiteSeconds, lower is better
bun test0.23s
Vitest1.91s
Jest + SWC3.07s
Jest + ts-jest6.71s
Jest + Babel7.43s

Same tests, same machine. Jest configured with each transformer's defaults.

bun build

TS, JSX, CSS & HTML for browsers and servers. Dev server with hot reloading. Single-file executables.

Replacesesbuildvitewebpack

$ bun ./index.html$ bun build ./index.html --production$ bun build --compile ./todo.ts
Bundling 10 copies of three.jsTime with sourcemaps and minification, lower is better
Bunv1.3.0269ms
Rolldownv1.0.0-beta.42495ms
esbuildv0.25.10572ms
Farmv1.0.51.61s
Rspackv1.5.82.14s

Linux x64, bench/bundle in oven-sh/bun.

bun check

Passes 100% of TypeScript 7.0.2's conformance test suite. Reads your tsconfig.json and reports the same errors as tsc.

Replacestsc

$ bun checkerror: TS2322: Type 'string' is not assignable to type 'number'.    at src/index.ts:3:25Found 1 error in 1 file, checked 2 files [14.00ms]
Type checking open-source projectsbun check in pink, tsc 7.0.2 in gray, lower is better
VS Code9,795 files1.24s5.98s
mikro-orm2,883 files1.20s5.97s
Next.js2,881 files0.28s1.82s
Nuxt839 files0.27s0.80s
Playwright706 files0.15s0.64s

Each project has its own scale. 16-core Apple silicon Mac, from the Bun v1.4.3 release.

bun fmt

Works with your Prettier or oxfmt config. In Prettier's own repo (2,616 files), bun fmt --check takes 60 ms and Prettier takes 17 seconds.

Replacesprettieroxfmt

$ bun fmtsrc/index.tssrc/styles.cssFormatted 2 files, 2 unchanged [5.59ms]
Formatting projects that already use oxfmtbun fmt in pink, oxfmt 0.74.0 in gray, lower is better
RSSHub7,121 files97ms299ms
redocly-cli3,397 files62ms218ms
vite2,537 files65ms407ms
fumadocs2,452 files45ms1.40s

Each project has its own scale. vite on an M4 Max, the rest on a Xeon 8488C. From the Bun v1.4.4 release.

The APIs you need, baked in.

Most servers need an HTTP stack, a database client, Redis, S3, hashing and a way to shell out. Bun ships all of them, so that is a stack of packages you never install or patch.

Bun.serve() with routes, params and static responses.

Docs

server.ts

import { serve, sql } from "bun";

const server = serve({
  port: 3000,
  routes: {
    "/": new Response("Welcome to Bun!"),
    "/api/users/:id": async req => {
      const [user] = await sql`SELECT * FROM users WHERE id = ${req.params.id}`;
      return Response.json(user);
    },
  },
});

console.log(`Listening on ${server.url}`);

Pub/sub WebSocket server, built into Bun.serve().

Docs

chat.ts

Bun.serve({
  fetch(req, server) {
    if (server.upgrade(req, { data: { room: "lobby" } })) return;
    return new Response("Expected a WebSocket", { status: 400 });
  },
  websocket: {
    open(ws) {
      ws.subscribe(ws.data.room);
    },
    message(ws, message) {
      // broadcast to everyone in the room
      ws.publish(ws.data.room, message);
    },
  },
});

Bun.sql — tagged templates, pipelining, transactions.

Docs

db.ts

import { sql } from "bun";

// Parameters are escaped automatically
const active = await sql`
  SELECT * FROM users
  WHERE active = ${true}
  LIMIT 10
`;

// Insert with object notation
const [user] = await sql`
  INSERT INTO users ${sql({ name: "Alice", email: "alice@example.com" })}
  RETURNING *
`;

A fast Redis client with Pub/Sub — no driver to install.

Docs

cache.ts

import { redis } from "bun";

await redis.set("greeting", "Hello from Bun!");
const greeting = await redis.get("greeting");

await redis.hset("user:1", { name: "Alice", plan: "pro" });
await redis.expire("user:1", 3600);

const subscriber = redis.duplicate();
await subscriber.subscribe("events", message => {
  console.log("event:", message);
});

Read, write and presign objects on any S3-compatible store.

Docs

storage.ts

import { s3 } from "bun";

const file = s3.file("uploads/avatar.png");

await file.write(await Bun.file("./avatar.png").bytes(), {
  type: "image/png",
});

const url = file.presign({ expiresIn: 3600 });
const exists = await file.exists();

Bun.$ — cross-platform bash-like scripting with JS interop.

Docs

deploy.ts

import { $ } from "bun";

// Works the same on macOS, Linux and Windows
const branch = await $`git rev-parse --abbrev-ref HEAD`.text();

await $`bun run build`;

// Pipe a fetch() Response straight through gzip
const res = await fetch("https://example.com/data.json");
await $`gzip -9 < ${res} > data.json.gz`;

console.log(`deployed ${branch.trim()}`);

bun test — Jest-compatible, concurrent, instant startup.

Docs

math.test.ts

import { describe, expect, mock, test } from "bun:test";

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

  test.concurrent("fetches a user", async () => {
    const res = await fetch("https://api.example.com/users/1");
    expect(res.status).toBe(200);
  });

  test("mocks", () => {
    const fn = mock(() => 42);
    fn();
    expect(fn).toHaveBeenCalledTimes(1);
  });
});

argon2 & bcrypt hashing without native addons.

Docs

auth.ts

const password = "super-secure-pa$$word";

const hash = await Bun.password.hash(password);
// => $argon2id$v=19$m=65536,t=2,p=1$tFq+9AVr1bf...

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

const legacy = await Bun.password.hash(password, {
  algorithm: "bcrypt",
  cost: 12,
});

Import an HTML file and you have a full-stack dev server.

Docs

app.ts

import { serve } from "bun";
import homepage from "./index.html";
import dashboard from "./dashboard.html";

serve({
  routes: {
    "/": homepage,
    "/dashboard": dashboard,
    "/api/health": () => Response.json({ ok: true }),
  },
  development: {
    hmr: true,      // hot module reloading
    console: true,  // stream browser logs to this terminal
  },
});

Call into C, Rust or Zig shared libraries.

Docs

sqlite-version.ts

import { dlopen, FFIType, suffix } from "bun:ffi";

// "dylib" on macOS, "so" on Linux, "dll" on Windows
const lib = dlopen(`libsqlite3.${suffix}`, {
  sqlite3_libversion: {
    args: [],
    returns: FFIType.cstring,
  },
});

console.log(`SQLite ${lib.symbols.sqlite3_libversion()}`);

In production

Already running the apps you use.

Claude Code ships to millions of developers as a Bun executable. Midjourney pushes every image notification through Bun's WebSocket server. Railway runs its serverless functions on it. Hear it from them:

Claude Code

Claude Code ships to every developer as a Bun single-file executable.

Claude Code is a single file with Bun inside it. Users download it and run it. There is no install step and no startup lag.

Midjourney

Every image notification Midjourney sends goes through Bun's WebSocket server.

Pub/sub, backpressure and per-message compression are built into Bun.serve(), so there is no WebSocket library to install.

Railway

Railway built its serverless Functions product on Bun.

A Railway Function is a TypeScript file. Bun runs it as-is, so a deploy skips the build and a cold start takes milliseconds.

Frameworks

Bun runs Next.js, Remix, Nuxt, Astro, SvelteKit, Hono, Elysia & friends.

Frameworks built for Node.js run on Bun. Swap npm run dev for bun --bun run dev and you can use Bun's SQL, S3 and shell APIs in your route handlers.

app/blog/[slug]/page.tsx
import { s3, $, sql } from "bun";
export default async function BlogPage({ params }) {
const [post] = await sql`SELECT * FROM posts WHERE slug = ${params.slug}`;
const img = s3.file(post.imageKey).presign();
const words = await $`wc -w < ${post.file}`.text();
return <Article post={post} img={img} words={words} />;
}

Bun is a complete toolkit.

Feature NodeDeno
Runtime
Node.js compatibility
Web Standard APIs
TypeScript
JSX
Native addons
Module loader plugins
Built-in APIs
PostgreSQL, MySQL & SQLite drivers
S3 client
Redis client
Tooling

Try it on the repo you have open right now.

Install Bun, open the project you were already working on, and run bun install. Your code, dependencies and scripts stay exactly as they are.

curl -fsSL https://bun.sh/install | bash
View install script ↗