What is Bun?
Bun is an all-in-one JavaScript runtime built on JavaScriptCore (Safari's engine). It ships a runtime, bundler, test runner, and package manager in one binary.
Installation and Migration
# Install Bun
curl -fsSL https://bun.sh/install | bash
# Run a Node.js app with Bun (most apps work as-is)
bun run src/index.ts # TypeScript natively!
# Replace npm scripts
bun install # ~25x faster than npm
bun run dev
bun run build
Bun's Built-in HTTP Server
// Much faster than Express/Fastify
const server = Bun.serve({
port: 3000,
async fetch(req) {
const url = new URL(req.url)
if (url.pathname === '/') {
return new Response('Hello from Bun!')
}
if (url.pathname === '/json') {
return Response.json({ message: 'Hello', timestamp: Date.now() })
}
return new Response('Not found', { status: 404 })
},
})
console.log(`Listening on port ${server.port}`)
Built-in SQLite
import { Database } from 'bun:sqlite'
const db = new Database('myapp.db')
// Create table
db.run(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL
)
`)
// Prepared statements (fast, safe)
const insertUser = db.prepare('INSERT INTO users (name, email) VALUES ($name, $email)')
const getUser = db.prepare('SELECT * FROM users WHERE id = $id')
const getAllUsers = db.prepare('SELECT * FROM users LIMIT $limit OFFSET $offset')
// Run
insertUser.run({ $name: 'Alice', $email: 'alice@example.com' })
const user = getUser.get({ $id: 1 })
const users = getAllUsers.all({ $limit: 20, $offset: 0 })
Bun Test Runner
import { describe, test, expect, beforeEach } from 'bun:test'
describe('UserService', () => {
let service: UserService
beforeEach(() => {
service = new UserService(mockDb)
})
test('creates a user', async () => {
const user = await service.create({ name: 'Bob', email: 'bob@test.com' })
expect(user.id).toBeDefined()
expect(user.name).toBe('Bob')
})
test('throws on duplicate email', async () => {
await service.create({ name: 'Bob', email: 'bob@test.com' })
expect(() =>
service.create({ name: 'Bob 2', email: 'bob@test.com' })
).toThrow('Email taken')
})
})
bun test # Run all tests
bun test --watch # Watch mode
bun test --coverage # Coverage report
Bun Bundler
// build.ts
await Bun.build({
entrypoints: ['./src/index.ts'],
outdir: './dist',
target: 'bun',
minify: true,
sourcemap: 'external',
splitting: true,
})
Performance Comparison
| Benchmark | Bun | Node.js 22 | Deno |
|---|---|---|---|
| HTTP req/s | ~120k | ~68k | ~72k |
| Install deps | 1.2s | 31s | N/A |
| Test run | 0.3s | 2.1s | 0.8s |
| Startup time | 2ms | 40ms | 50ms |
Migration Gotchas
__filenameand__dirnamework in Bun (not just ESM)- Most npm packages work; some native addons may not
node:prefix imports work:import fs from 'node:fs'process.envworks as expected