Bun
Complete reference for Bun — the all-in-one JavaScript/TypeScript runtime, package manager, bundler, and test runner
Installation & Setup
Install Bun and configure your project
Install Bun and scaffold a new project
# Install Bun
curl -fsSL https://bun.sh/install | bash
# macOS with Homebrew
brew install oven-sh/bun/bun
# Create new project
bun init
# Upgrade Bun
bun upgradeConfigure Bun behavior with the bunfig.toml config file
# bunfig.toml — project-level Bun config
[install]
peer = false # Don't install peer deps
exact = true # Use exact versions
[test]
coverage = true # Enable code coverageRunning Scripts & Files
Execute files, scripts, and packages with bun run and bunx
Run files, package.json scripts, and remote packages
# Run a TypeScript/JavaScript file
bun run index.ts
bun index.ts # "run" is optional
# Run package.json scripts
bun run dev
bun run build
# Execute a package (like npx)
bunx cowsay "Hello!"
bunx --bun vite # Force Bun runtimePackage Manager
Install, manage, and publish packages with bun install
Install, add, remove, and update packages
# Install all dependencies
bun install
# Add a package
bun add express
# Dev dependency
bun add -d typescript
# Remove a package
bun remove expressHTTP Server
Build high-performance HTTP servers with Bun.serve()
Create an HTTP server with routes and request handling
Bun.serve({
port: 3000,
routes: {
"/": new Response("Hello!"),
"/api/users/:id": (req) => {
return Response.json({ id: req.params.id });
},
},
fetch(req) {
return new Response("Not Found", { status: 404 });
},
});Import .html into routes — Bun bundles JS/CSS automatically (Bun 1.2+)
// Import HTML files directly — Bun bundles their <script>/<link> deps
import index from './index.html'
import dashboard from './dashboard.html'
Bun.serve({
port: 3000,
routes: {
'/': index, // bundled, served, hot-reloaded
'/dashboard': dashboard,
// API mixed with HTML in the same server
'/api/posts': {
GET: () => Response.json([]),
POST: async (req) => Response.json(await req.json(), { status: 201 }),
},
'/api/posts/:id': (req) =>
Response.json({ id: req.params.id }),
},
development: true, // browser-side error overlay + HMR
})WebSockets
Built-in WebSocket server support with pub/sub messaging
Add WebSocket support to Bun.serve with handlers and pub/sub
Bun.serve({
fetch(req, server) {
if (server.upgrade(req)) return; // Upgrade to WS
return new Response("Not a WS request", { status: 400 });
},
websocket: {
open(ws) { ws.send("Welcome!"); },
message(ws, msg) { ws.send(`Echo: ${msg}`); },
close(ws) { console.log("Disconnected"); },
},
});File I/O
Read, write, and manipulate files with Bun.file() and Bun.write()
Fast file operations with Bun.file() and Bun.write()
// Read a file
const file = Bun.file("data.json");
const text = await file.text();
const json = await file.json();
// Write a file
await Bun.write("output.txt", "Hello World");
await Bun.write("data.json", JSON.stringify({ ok: true }));SQLite & Database
Built-in SQLite database with the bun:sqlite module
Use the built-in SQLite database for fast local storage
import { Database } from "bun:sqlite";
const db = new Database("app.db");
db.exec(`CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE
)`);
const insert = db.prepare("INSERT INTO users (name, email) VALUES (?, ?)");
insert.run("John", "john@test.com");
const users = db.query("SELECT * FROM users").all();Test Runner
Jest-compatible testing with bun test
Write Jest-compatible tests with describe, test, and expect
import { test, expect, describe } from "bun:test";
describe("math", () => {
test("addition", () => {
expect(2 + 2).toBe(4);
});
test("async", async () => {
const res = await fetch("https://api.example.com");
expect(res.ok).toBeTrue();
});
});Mock functions, spy on methods, and use snapshot testing
import { test, expect, mock, spyOn } from "bun:test";
// Mock function
const fn = mock(() => 42);
fn();
expect(fn).toHaveBeenCalledTimes(1);
// Snapshot
test("snapshot", () => {
expect({ foo: "bar" }).toMatchSnapshot();
});Bundler
Bundle JavaScript, TypeScript, and CSS with bun build
Bundle code for browsers and servers
# CLI bundling
bun build ./src/index.ts --outdir ./dist
bun build ./src/index.ts --outdir ./dist --minify
bun build ./src/index.ts --target browserUse Bun.build() in code with plugins and advanced options
const result = await Bun.build({
entrypoints: ["./src/index.ts"],
outdir: "./dist",
target: "browser",
minify: true,
});
if (!result.success) {
console.error(result.logs);
}Shell & Child Processes
Run shell commands with Bun.$ and spawn child processes
Run shell commands with tagged template literals
import { $ } from "bun";
// Run a command
await $`echo "Hello World"`;
// Capture output
const result = await $`ls -la`.text();
// Use variables safely (auto-escaped)
const dir = "/tmp";
await $`ls ${dir}`;Spawn child processes with fine-grained control
// Run a command
const proc = Bun.spawn(["echo", "Hello"]);
await proc.exited; // Wait for completion
// Capture stdout
const proc = Bun.spawn(["ls", "-la"], {
stdout: "pipe",
});
const output = await new Response(proc.stdout).text();Environment & Utilities
Environment variables, hashing, passwords, and built-in utilities
Access and manage environment variables with auto .env loading
// Access env vars (auto-loaded from .env)
const dbUrl = Bun.env.DATABASE_URL;
const port = Bun.env.PORT || "3000";
// Also available on process.env
const key = process.env.API_KEY;Built-in hashing and secure password operations
// Hash a string
const hash = Bun.hash("hello world");
// Hash a password (argon2id by default)
const hashed = await Bun.password.hash("secret123");
const valid = await Bun.password.verify("secret123", hashed);Workers & Concurrency
Run code in parallel with Web Workers and Bun-specific APIs
Run CPU-intensive tasks in parallel threads
// main.ts
const worker = new Worker("./worker.ts");
worker.postMessage({ data: [1, 2, 3] });
worker.onmessage = (e) => {
console.log("Result:", e.data);
};
// worker.ts
self.onmessage = (e) => {
const result = e.data.data.map((n) => n * 2);
self.postMessage(result);
};