Bun is not just a runtime. It is a runtime + package manager + bundler + test runner + transpiler — all in one binary, all faster than the alternatives.
Speed Comparison
| Task | Node.js + tools | Bun |
|---|---|---|
| Install deps (cold) | npm: 30s | bun: 3s |
| Install deps (cached) | npm: 8s | bun: 0.5s |
| Run TypeScript | tsc + node: 2s | bun: 0.1s |
| HTTP server (req/s) | ~50K | ~200K |
| Test runner | jest: 15s | bun test: 2s |
| Bundle | webpack: 20s | bun build: 1s |
Install
curl -fsSL https://bun.sh/install | bash
Runtime
// server.ts — runs directly, no build step
const server = Bun.serve({
port: 3000,
async fetch(req) {
const url = new URL(req.url);
if (url.pathname === "/api/users") {
return Response.json([{ id: 1, name: "Alice" }]);
}
return new Response("Not Found", { status: 404 });
},
});
console.log(`Listening on ${server.url}`);
bun run server.ts
# TypeScript runs directly — no tsc, no ts-node
Package Manager
# 10-25x faster than npm
bun install # Install all deps
bun add express # Add package
bun add -d vitest # Add dev dependency
bun remove express # Remove package
Bun uses a global cache and hardlinks — installs are nearly instant after the first time.
Bundler
bun build ./src/index.ts --outdir ./dist --target browser --minify
// Or programmatically
const result = await Bun.build({
entrypoints: ["./src/index.ts"],
outdir: "./dist",
target: "browser",
minify: true,
splitting: true,
sourcemap: "external",
});
Test Runner
// math.test.ts
import { test, expect, describe } from "bun:test";
describe("math", () => {
test("adds numbers", () => {
expect(1 + 2).toBe(3);
});
test("async operations", async () => {
const response = await fetch("http://localhost:3000/api/users");
expect(response.status).toBe(200);
const data = await response.json();
expect(data).toHaveLength(1);
});
});
bun test
Jest-compatible API. 10x faster execution.
Built-in SQLite
import { Database } from "bun:sqlite";
const db = new Database("app.db");
db.run(`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("Alice", "alice@test.com");
const users = db.query("SELECT * FROM users").all();
Embedded SQLite — no npm package needed.
File I/O
// Read
const content = await Bun.file("data.json").text();
const json = await Bun.file("data.json").json();
const buffer = await Bun.file("image.png").arrayBuffer();
// Write
await Bun.write("output.txt", "Hello World");
await Bun.write("data.json", JSON.stringify({ key: "value" }));
// Glob
const glob = new Bun.Glob("**/*.ts");
for await (const file of glob.scan("./src")) {
console.log(file);
}
npm Compatibility
Bun runs most npm packages. Express, React, Next.js, Prisma — all work.
bunx create-next-app@latest # Works!
bunx prisma generate # Works!
bunx vite # Works!
Need high-performance JavaScript solutions? I build web tools and data pipelines. Email spinov001@gmail.com or check my Apify tools.
Top comments (0)