DevToolBox免费
博客

Bun 完全指南:全能 JavaScript 运行时

20 min read作者 DevToolBox Team

Bun 是一个从头构建的全能 JavaScript 运行时、包管理器、打包器和测试运行器,专注于速度。它用 Zig 编写,由 JavaScriptCore 引擎(Safari 使用的同一引擎)驱动,与 Node.js 相比,Bun 提供了显著更快的启动时间、包安装和 HTTP 吞吐量。本指南涵盖 2026 年 Bun 的每个主要功能。

TL;DR

Bun 是一个用 Zig 编写的快速、全能 JavaScript 和 TypeScript 运行时。它用单一工具替代了 Node.js、npm、webpack 和 Jest。它使用 JavaScriptCore 而非 V8,安装包比 npm 快 25 倍,内置打包器、测试运行器、SQLite 客户端和 HTTP 服务器。

Key Takeaways
  • Bun 使用 JavaScriptCore(WebKit 引擎)和 Zig 实现最高性能,启动速度比 Node.js 快 4 倍。
  • bun install 通过二进制锁文件、全局缓存和原生代码,比 npm 快多达 25 倍。
  • Bun.serve() 提供开箱即用的高性能 HTTP 服务器,可处理每秒 10 万以上请求。
  • 内置 SQLite、测试运行器、打包器和 .env 加载消除了对外部依赖的需求。
  • 近乎完整的 Node.js API 兼容性意味着大多数 npm 包无需修改即可工作。

为什么 Bun 很快:Zig 和 JavaScriptCore

Bun 通过两个关键架构决策实现速度。首先,它用 Zig 编写,一种为性能关键软件设计的低级系统语言。其次,Bun 使用 WebKit 的 JavaScriptCore 而非 V8,JSC 启动时间更快,因为它在 JIT 编译之前使用轻量级解释器层。

AspectBun (JavaScriptCore)Node.js / Deno (V8)
Startup StrategyInterpreter first, then JITEager compilation
Implementation LanguageZig (no GC, no hidden control flow)C++ (Node) / Rust (Deno)
Startup Time~5ms for hello world~20ms for hello world
I/O LayerCustom event loop (io_uring on Linux)libuv

安装和入门

Bun 作为单个二进制文件安装,无外部依赖。支持 macOS、Linux 和 Windows。

# Install Bun (macOS / Linux)
curl -fsSL https://bun.sh/install | bash

# Install via npm (alternative)
npm install -g bun

# Install via Homebrew (macOS)
brew install oven-sh/bun/bun

# Windows (native support)
powershell -c "irm bun.sh/install.ps1 | iex"

# Verify installation
bun --version  # 1.x.x

# Create a new project
bun init
# Creates: package.json, tsconfig.json, index.ts, README.md

# Run a TypeScript file directly (no config needed)
bun run index.ts

# Run with watch mode (auto-restart on changes)
bun --watch run index.ts

包管理器:bun install

Bun 包含最快的 JavaScript 包管理器。速度优势来自二进制锁文件、并行 HTTP 请求、全局包缓存和基于符号链接的 node_modules。

# Install all dependencies from package.json
bun install

# Add a dependency
bun add express
bun add zod @types/node

# Add dev dependency
bun add -d typescript prettier eslint

# Add global package
bun add -g serve

# Remove a package
bun remove lodash

# Update all packages
bun update

# Run a script from package.json
bun run build
bun run dev

# CI mode: fail if lockfile is out of date
bun install --frozen-lockfile

# View lockfile as human-readable text
bun bun.lockb

# Execute a package binary (like npx)
bunx create-next-app@latest my-app
bunx prettier --write .

Install Speed Benchmarks

Package ManagerWarm CacheCold CacheLockfile Format
bun install1.2s4.1sBinary (bun.lockb)
pnpm install9.4s15.2sYAML
yarn install14.1s22.8sCustom text
npm install28.3s38.7sJSON

打包器:bun build

Bun 包含生产就绪的打包器,支持 tree shaking、代码分割、压缩、source maps 和多种输出目标。

# Bundle for the browser
bun build ./src/index.ts --outdir ./dist --target browser

# Bundle for Node.js
bun build ./src/server.ts --outdir ./dist --target node

# Bundle for Bun runtime
bun build ./src/app.ts --outdir ./dist --target bun

# With minification and code splitting
bun build ./src/index.ts \
  --outdir ./dist \
  --target browser \
  --minify \
  --splitting \
  --sourcemap=external

# Programmatic API (build.ts)
const result = await Bun.build({
  entrypoints: ["./src/index.ts", "./src/worker.ts"],
  outdir: "./dist",
  target: "browser",
  minify: true,
  splitting: true,
  sourcemap: "external",
  naming: "[dir]/[name]-[hash].[ext]",
  define: {
    "process.env.NODE_ENV": JSON.stringify("production"),
  },
});

if (!result.success) {
  for (const msg of result.logs) {
    console.error(msg);
  }
}

测试运行器:bun test

Bun 有一个内置的 Jest 兼容 API 测试运行器,支持 describe、test、expect、mock 和代码覆盖率。

// math.test.ts
import { describe, test, expect, beforeAll, mock } from "bun:test";

describe("math utilities", () => {
  test("adds two numbers", () => {
    expect(2 + 3).toBe(5);
  });

  test("array contains value", () => {
    const fruits = ["apple", "banana", "cherry"];
    expect(fruits).toContain("banana");
    expect(fruits).toHaveLength(3);
  });

  test("object matching", () => {
    const user = { name: "Alice", age: 30, role: "admin" };
    expect(user).toMatchObject({ name: "Alice", role: "admin" });
  });

  test("async operations", async () => {
    const data = await Promise.resolve({ status: "ok" });
    expect(data.status).toBe("ok");
  });

  test("error throwing", () => {
    expect(() => { throw new Error("fail"); }).toThrow("fail");
  });
});

// Mocking example
const mockFetch = mock(() => Promise.resolve({ ok: true }));
test("mock function", () => {
  mockFetch();
  expect(mockFetch).toHaveBeenCalledTimes(1);
});

Test Runner CLI Options

# Run all tests
bun test

# Run specific test file
bun test src/utils.test.ts

# Watch mode
bun test --watch

# With code coverage
bun test --coverage

# Filter tests by name
bun test --test-name-pattern "math"

# Set timeout (default 5000ms)
bun test --timeout 10000

HTTP 服务器:Bun.serve()

Bun.serve() 是内置的高性能 HTTP 服务器,使用 Web 标准的 Request 和 Response API。

// server.ts — High-performance HTTP server
const server = Bun.serve({
  port: 3000,
  fetch(req) {
    const url = new URL(req.url);

    if (url.pathname === "/") {
      return new Response("Hello from Bun!");
    }

    if (url.pathname === "/api/users") {
      const users = [
        { id: 1, name: "Alice" },
        { id: 2, name: "Bob" },
      ];
      return Response.json(users);
    }

    if (url.pathname === "/api/stream") {
      const stream = new ReadableStream({
        start(controller) {
          controller.enqueue("chunk 1\n");
          controller.enqueue("chunk 2\n");
          controller.close();
        },
      });
      return new Response(stream);
    }

    return new Response("Not Found", { status: 404 });
  },
});

console.log("Server running at http://localhost:" + server.port);

WebSocket Server

// WebSocket server with Bun.serve()
Bun.serve({
  port: 3000,
  fetch(req, server) {
    // Upgrade HTTP request to WebSocket
    if (server.upgrade(req)) {
      return; // Return nothing if upgraded
    }
    return new Response("Upgrade failed", { status: 500 });
  },
  websocket: {
    open(ws) {
      console.log("Client connected");
      ws.send("Welcome!");
    },
    message(ws, message) {
      console.log("Received:", message);
      ws.send("Echo: " + message);
    },
    close(ws) {
      console.log("Client disconnected");
    },
  },
});

文件 I/O:Bun.file() 和 Bun.write()

Bun 提供优化的文件 I/O API,比 Node.js 等效方法显著更快。

// Reading files
const file = Bun.file("./data.json");
console.log(file.size);       // File size in bytes
console.log(file.type);       // MIME type

const text = await file.text();       // Read as string
const json = await file.json();       // Parse as JSON
const buffer = await file.arrayBuffer(); // Read as ArrayBuffer
const bytes = await file.bytes();     // Read as Uint8Array

// Writing files
await Bun.write("output.txt", "Hello, Bun!");
await Bun.write("data.json", JSON.stringify({ key: "value" }));
await Bun.write("copy.txt", Bun.file("original.txt"));

// Write Response body to file
const response = await fetch("https://example.com/data.json");
await Bun.write("downloaded.json", response);

// Streaming large files
const writer = Bun.file("large-output.txt").writer();
writer.write("line 1\n");
writer.write("line 2\n");
writer.flush();
writer.end();

内置 SQLite:bun:sqlite

Bun 通过 bun:sqlite 模块包含原生 SQLite 客户端,无需安装任何 npm 包。

// Built-in SQLite — no npm install needed
import { Database } from "bun:sqlite";

// Open or create a database
const db = new Database("myapp.db");

// Enable WAL mode for better concurrent performance
db.exec("PRAGMA journal_mode = WAL");

// Create a table
db.exec(`
  CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT UNIQUE NOT NULL,
    created_at TEXT DEFAULT CURRENT_TIMESTAMP
  )
`);

// Prepared statements (safe from SQL injection)
const insertUser = db.prepare(
  "INSERT INTO users (name, email) VALUES (?, ?)"
);
insertUser.run("Alice", "alice@example.com");
insertUser.run("Bob", "bob@example.com");

// Query with typed results
const allUsers = db.prepare("SELECT * FROM users").all();
console.log(allUsers);
// [{ id: 1, name: "Alice", ... }, { id: 2, name: "Bob", ... }]

// Transactions for batch operations
const insertMany = db.transaction((users) => {
  for (const user of users) {
    insertUser.run(user.name, user.email);
  }
});

insertMany([
  { name: "Charlie", email: "charlie@example.com" },
  { name: "Diana", email: "diana@example.com" },
]);

Shell 脚本:Bun Shell

Bun 包含跨平台 shell(Bun.$),可直接从 JavaScript 或 TypeScript 运行 shell 命令。

// Bun Shell — cross-platform shell scripting
import { $ } from "bun";

// Run a command and get output
const result = await $`ls -la`.text();
console.log(result);

// Pipe commands
const count = await $`cat package.json | wc -l`.text();
console.log("Lines:", count.trim());

// Use variables safely (auto-escaped)
const filename = "my file.txt";
await $`touch ${filename}`;
await $`echo "hello" > ${filename}`;

// Redirect output to a file
await $`echo "build log" > build.log`;

// Check exit code
const proc = await $`grep -r "TODO" src/`.nothrow();
if (proc.exitCode === 0) {
  console.log("Found TODOs:", proc.text());
} else {
  console.log("No TODOs found");
}

// Run in background
const server = $`bun run server.ts`.spawn();
// ... do other work ...
server.kill();

宏:编译时代码执行

Bun 宏允许在打包时运行 JavaScript 函数并将结果内联到输出中。

// macros.ts — runs at compile time, NOT runtime
export function getBuildTime() {
  return new Date().toISOString();
}

export function getGitCommit() {
  const proc = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"]);
  return proc.stdout.toString().trim();
}

// app.ts — import with { type: "macro" }
import { getBuildTime, getGitCommit } from "./macros" with { type: "macro" };

// These calls are evaluated at bundle time
// and replaced with their return values
console.log("Built at:", getBuildTime());
console.log("Commit:", getGitCommit());

// After bundling, the output becomes:
// console.log("Built at:", "2026-02-28T10:30:00.000Z");
// console.log("Commit:", "a1b2c3d");

Bun vs Node.js vs Deno:功能对比

以下是 2026 年三大 JavaScript 运行时的详细对比。

FeatureBunNode.jsDeno
EngineJavaScriptCoreV8V8
Written InZig + C++C++Rust
TypeScriptNative (transpile)Via --strip-types (22+)Native (type-check)
Package ManagerBuilt-in (bun install)npm / yarn / pnpmBuilt-in (deno add)
BundlerBuilt-in (bun build)External (webpack/vite)Built-in
Test RunnerBuilt-in (Jest API)Built-in (node --test)Built-in (deno test)
HTTP ServerBun.serve()http.createServer()Deno.serve()
SQLiteBuilt-in (bun:sqlite)Via npm (better-sqlite3)Via npm
Security ModelUnrestrictedUnrestrictedPermission-based
npm Compatibility~99%100%~95%+
.env LoadingAutomaticVia dotenvVia --env flag
Startup Speed~4x fasterBaseline~1.5x faster

在生产环境使用 Bun 的最佳实践

  • Lockfile management: 将 bun.lockb 提交到版本控制。在 CI 中使用 --frozen-lockfile。
  • HTTP services: 新 HTTP 服务使用 Bun.serve(),它在原始吞吐量上优于 Express 和 Fastify。
  • SQLite usage: 利用内置 SQLite 做本地数据库、缓存层和会话存储。
  • Bundling: 使用 bun build 配合 --minify 和 --splitting 进行生产前端打包。
  • Environment variables: 利用自动 .env 加载,无需 dotenv 包。
  • Testing: 使用 bun test 及内置 Jest 兼容 API 编写测试。

从 Node.js 迁移到 Bun

将现有 Node.js 项目迁移到 Bun 非常简单,因为 Bun 实现了绝大多数 Node.js API。

// Step 1: Replace npm/yarn/pnpm with bun
# Delete old lockfiles and node_modules
rm -rf node_modules package-lock.json yarn.lock pnpm-lock.yaml

# Install with Bun
bun install

// Step 2: Update package.json scripts
// Before:
// "dev": "nodemon src/server.ts"
// "test": "jest --coverage"
// "build": "tsc && webpack"

// After:
// "dev": "bun --watch src/server.ts"
// "test": "bun test --coverage"
// "build": "bun build src/index.ts --outdir dist"

// Step 3: Remove unnecessary devDependencies
bun remove ts-node nodemon dotenv jest ts-jest
# Bun handles TypeScript, watching, .env, and testing natively

// Step 4: Update imports (most work as-is)
// Node.js built-in modules work without changes:
import fs from "node:fs";
import path from "node:path";
import crypto from "node:crypto";
// These all work identically in Bun
Migration Tips
  • Start by using Bun only as a package manager (bun install) while keeping Node.js as the runtime. This is the lowest-risk migration path.
  • Gradually switch scripts from node to bun. Test each one in isolation before moving to the next.
  • If a native Node.js addon does not work, check the Bun compatibility tracker or use a pure-JS alternative.
  • Docker images: use oven/bun as the base image for production containers. It is significantly smaller than node images.
  • For CI pipelines, use bun install --frozen-lockfile and bun test to ensure consistency.

When to Choose Bun Over Node.js or Deno

Use CaseBest RuntimeReason
CLI tools and scriptsBunFastest startup time, built-in TypeScript, shell scripting
Serverless functionsBunCold start under 5ms vs 20ms+ for Node.js
High-throughput APIsBunBun.serve() handles 100K+ req/s with Web standard APIs
Enterprise with strict securityDenoPermission-based security model, auditable access
Large legacy Node.js codebaseNode.js100% compatibility, largest ecosystem, most battle-tested
Monorepo with many packagesBun or pnpmBun install speed wins; pnpm has more mature workspace tooling

常见问题

2026 年 Bun 是否可以用于生产?

是的。Bun 1.0 于 2023 年 9 月达到稳定,后续 1.x 版本实现了近乎完整的 Node.js API 兼容性。

Bun 与所有 npm 包兼容吗?

几乎所有 npm 包都可以在 Bun 中工作。使用原生 C++ 插件的包可能存在边缘情况。

Bun 可以与 Next.js、Remix 或 Astro 一起使用吗?

可以用于包管理器和脚本运行器。运行时方面,Next.js 和 Astro 有实验性支持。

Bun 与 Deno 相比如何?

Bun 专注于速度和 Node.js 兼容性,Deno 专注于安全性和 Web 标准。

为什么 Bun 使用 JavaScriptCore 而非 V8?

JSC 启动时间更快,因为它在 JIT 编译之前使用轻量级解释器层,适合 CLI 工具和 Serverless。

Bun 原生支持 TypeScript 吗?

是的。Bun 即时转译 TypeScript 文件,无需配置。可以直接运行 .ts 和 .tsx 文件。

Bun 二进制锁文件(bun.lockb)是什么?

bun.lockb 是二进制格式的锁文件,比 JSON 锁文件解析快得多。

Bun 可以用于生产前端打包吗?

可以。bun build 支持 tree shaking、代码分割、压缩和 CSS 打包。

𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

获取每周开发技巧和新工具通知。

无垃圾邮件,随时退订。

试试这些相关工具

{ }JSON FormatterJSON Validator

相关文章

Deno 完全指南:安全的 JavaScript 运行时

掌握 Deno 运行时,包括安全权限、TypeScript 支持、标准库、HTTP 服务器、测试与 Deno Deploy。

esbuild 完全指南:最快的 JavaScript 打包工具

掌握 esbuild 超快打包,包括 CLI、JavaScript API、插件、加载器、压缩与生产优化。

SWC 完全指南:Rust 驱动的超快 JavaScript 编译器

掌握 SWC 超快编译,包括配置、转换、压缩、框架集成与从 Babel 迁移。