Bun.js — Node.js Killer? Complete Guide
Advertisement
Bun is a new JavaScript runtime claiming to be a Node.js killer. It's significantly faster, includes batteries (testing, bundling), and has first-class TypeScript support.
What is Bun?
Bun is a complete runtime written in Zig:
- 4x faster startup than Node.js
- 3x faster than Node in most benchmarks
- Built-in: Testing, bundling, package management
- TypeScript: Native support, no compilation needed
# Install Bun
curl -fsSL https://bun.sh/install | bash
# Create project
bun create hono my-app
cd my-app
bun dev
Running JavaScript with Bun
# Direct execution
bun run script.ts
# TypeScript out of the box
bun run app.ts
# REPL
bun repl
# Watch mode
bun --watch run app.ts
- What is Bun?
- Running JavaScript with Bun
- HTTP Server with Bun
- Bunfig Configuration
- Package Management
- Built-in Testing
- Working with Files
- Database with Bun
- HTTP Requests
- Environment Variables
- Bundling
- Performance Comparison
- Express-like Server with Bun
- Node.js vs Bun
- FAQ
HTTP Server with Bun
import { serve } from "bun";
serve({
fetch(request) {
const url = new URL(request.url);
if (url.pathname === "/") {
return new Response("Hello, Bun!");
}
if (url.pathname === "/api/users") {
return Response.json([{ id: 1, name: "Alice" }]);
}
return new Response("404 Not Found", { status: 404 });
},
port: 3000,
});
console.log("Server running on http://localhost:3000");
Bunfig Configuration
// bunfig.toml
[package]
name = "my-app"
version = "1.0.0"
[dev]
port = 3000
[build]
minify = true
target = "node"
[define]
"process.env.NODE_ENV" = "\"production\""
Package Management
# Install dependencies
bun install
# Add package
bun add express
# Remove package
bun remove express
# Run scripts
bun run dev
bun run build
Built-in Testing
// tests/user.test.ts
import { describe, it, expect } from "bun:test";
describe("User API", () => {
it("should create a user", () => {
const user = { id: 1, name: "Alice" };
expect(user.name).toBe("Alice");
});
it("should update a user", () => {
const user = { id: 1, name: "Alice" };
user.name = "Bob";
expect(user.name).toBe("Bob");
});
});
# Run tests
bun test
bun test --watch
bun test --coverage
Working with Files
// Read file
const content = await Bun.file("config.json").text();
const config = JSON.parse(content);
// Write file
await Bun.write("output.json", JSON.stringify(data));
// Stream file
Bun.serve({
fetch(req) {
return new Response(Bun.file("large-file.bin"));
},
});
// Watch files
const watcher = Bun.watch("/path/to/files");
watcher.on("change", (path) => {
console.log(`File changed: ${path}`);
});
Database with Bun
import Database from "bun:sqlite";
const db = new Database("app.db");
// Create table
db.exec(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT,
email TEXT
)
`);
// Insert
db.prepare("INSERT INTO users (name, email) VALUES (?, ?)").run("Alice", "alice@example.com");
// Query
const users = db.prepare("SELECT * FROM users").all();
console.log(users);
// Single row
const user = db.prepare("SELECT * FROM users WHERE id = ?").get(1);
console.log(user);
HTTP Requests
// Fetch API (standard)
const response = await fetch("https://api.example.com/users");
const data = await response.json();
// Bun-specific optimization
const response2 = await fetch("https://api.example.com/posts", {
headers: {
"Authorization": "Bearer token",
},
});
const text = await response2.text();
Environment Variables
# .env
DATABASE_URL=sqlite:app.db
API_KEY=secret123
NODE_ENV=development
import { env } from "bun";
const databaseUrl = env.DATABASE_URL;
const apiKey = env.API_KEY;
const isDev = env.NODE_ENV === "development";
console.log({ databaseUrl, apiKey, isDev });
Bundling
# Bundle for browser
bun build ./index.ts --outdir ./dist
# Target Node.js
bun build ./index.ts --target node
# With minification
bun build ./index.ts --minify
Performance Comparison
| Task | Node.js | Bun |
|---|---|---|
| Cold start | 200ms | 50ms |
| First request | ~50ms | ~2ms |
| Throughput | 10k req/s | 30k req/s |
| Memory | Similar | Similar |
Express-like Server with Bun
// Works with Express!
import express from "express";
const app = express();
app.use(express.json());
app.get("/users", (req, res) => {
res.json([{ id: 1, name: "Alice" }]);
});
export default {
fetch: app,
port: 3000,
};
Node.js vs Bun
| Feature | Node.js | Bun |
|---|---|---|
| Maturity | Stable | Newer |
| Ecosystem | Huge | Growing |
| Performance | Good | Excellent |
| TypeScript | Via setup | Native |
| Bundling | Via webpack | Built-in |
| Testing | Via Jest | Built-in |
FAQ
Q: Should I use Bun for production? A: Bun is production-ready but newer. Use Node.js if stability is critical. Use Bun for new projects or performance-sensitive workloads.
Q: Is Bun a drop-in Node.js replacement? A: Almost. Most npm packages work. Some Node.js-specific APIs differ. Check compatibility before migrating.
Q: Can I use Bun with TypeScript? A: Yes! TypeScript runs natively without compilation.
Bun is genuinely faster and more convenient than Node.js. For new projects, Bun is worth serious consideration. For existing Node.js applications, stability might outweigh the performance gains. But the future looks bright for Bun.
Advertisement