DEV Community

myougaTheAxo
myougaTheAxo

Posted on

Bun Runtime Setup Guide: Migrating from Node.js and Practical Patterns

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
Enter fullscreen mode Exit fullscreen mode

bunfig.toml (Bun-specific configuration):

[install]
lockfile = "bun.lockb"

[test]
timeout = 10000
coverage = true
Enter fullscreen mode Exit fullscreen mode

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 });
  },
});
Enter fullscreen mode Exit fullscreen mode

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!");
Enter fullscreen mode Exit fullscreen mode

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();
});
Enter fullscreen mode Exit fullscreen mode

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" },
]);
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)