What is Bun: Differences from Node.js
Bun is a tool that integrates JavaScript runtime, bundler, and package manager into one, officially released in 2023. Built with Zig on the JavaScriptCore engine (Safari's JS engine), it operates 2-3x faster than Node.js.
Why Bun is fast comes down to architecture. Startup time is about 1/3 of Node.js, native HTTP server throughput is about 4x Express, and bun install is about 25x faster than npm.
Best use cases: Script execution, internal tools, microservices, TypeScript projects
Installation and Initial Setup
curl -fsSL https://bun.sh/install | bash
bun --version # 1.1.x
bun init
bunfig.toml (Bun-specific configuration):
[install]
lockfile = "bun.lockb"
[test]
timeout = 10000
coverage = true
Bun HTTP Server: High-Speed Web Server
const server = Bun.serve({
port: parseInt(process.env.PORT ?? "3000"),
async fetch(req: Request): Promise<Response> {
const url = new URL(req.url);
if (url.pathname === "/health") {
return Response.json({ status: "ok", uptime: process.uptime() });
}
if (url.pathname.startsWith("/api/")) {
return handleApi(req, url);
}
return new Response("Not Found", { status: 404 });
},
error(error: Error): Response {
return Response.json({ error: "Internal Server Error" }, { status: 500 });
},
});
Native File Operations
// Bun's file API is simpler than Node.js
async function readJsonFile<T>(path: string): Promise<T> {
return Bun.file(path).json<T>();
}
async function writeJsonFile(path: string, data: unknown): Promise<void> {
await Bun.write(path, JSON.stringify(data, null, 2));
}
const content = await Bun.file("./config.txt").text();
await Bun.write("./output.txt", "Hello, Bun!");
Bun Test Runner
import { describe, it, expect, mock } from "bun:test";
describe("Users API", () => {
it("GET /api/users returns user list", async () => {
const req = new Request("http://localhost/api/users");
const res = await handleApi(req, new URL(req.url));
const body = await res.json();
expect(res.status).toBe(200);
expect(body).toHaveLength(1);
});
});
// Snapshot testing
it("generates correct HTML", () => {
const html = renderComponent({ title: "Test" });
expect(html).toMatchSnapshot();
});
Native SQLite Integration
import { Database } from "bun:sqlite";
const db = new Database("myapp.db", { create: true });
db.run("PRAGMA journal_mode = WAL");
db.run(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL
)
`);
const insertUser = db.prepare("INSERT INTO users (name, email) VALUES ($name, $email)");
// Transaction
const createUsers = db.transaction((users: Array<{name: string; email: string}>) => {
for (const user of users) {
insertUser.run({ $name: user.name, $email: user.email });
}
});
createUsers([
{ name: "Alice", email: "alice@example.com" },
{ name: "Bob", email: "bob@example.com" },
]);
Migration from Node.js
# Delete package-lock.json and reinstall with bun
rm -f package-lock.json yarn.lock
bun install # generates node_modules and bun.lockb
Bun is particularly powerful for "scripts that need speed, internal tools, and TypeScript projects." Since it's not fully compatible with Node.js, migrating large existing projects needs care, but it's a solid choice for new projects.
This article is from the Claude Code Complete Guide (7 chapters) on note.com.
myouga (@myougatheaxo) - VTuber axolotl. Sharing practical AI development tips.
Top comments (0)