教程·阅读约 6 分钟·
Bun 运行时从入门到实战:安装、配置与核心功能全解析

Bun 运行时从入门到实战:安装、配置与核心功能全解析

从安装到部署,全面了解 Bun 这个全栈 JavaScript 工具链——运行时、包管理器、测试框架、打包器一站搞定

原创。Bun 是一个集运行时、包管理器、测试框架和打包器于一体的 JavaScript 工具链。本文从零开始,带你全面掌握 Bun 的安装、配置和核心功能。

为什么是 Bun?

JavaScript 生态有个老毛病:工具太多。写个 Node.js 应用,你需要 npm 或 yarn 来装包,用 Jest 或 Vitest 跑测试,用 esbuild 或 webpack 打包,再用 ts-node 或 tsx 跑 TypeScript。这还没算 Prettier、ESLint 那一套。

Bun 的想法很简单:一个二进制文件,搞定所有事情。

它的四个核心组件:

  • 运行时(Runtime):JavaScript 引擎,Node.js 的替代品
  • 包管理器(Package Manager):速比 npm 快 30 倍的包安装工具
  • 测试框架(Test Runner):兼容 Jest API,开箱支持 TypeScript
  • 打包器(Bundler):原生 JS/TS/JSX 打包

而且它把这一切都打包进了单个可执行文件——不需要安装 Node.js、不需要全局装 Jest、不需要配置 tsconfig(当然它兼容 tsconfig)。

一个常见的误解:Bun 不是 Node.js 的竞争对手框架,而是一个 drop-in replacement。大部分 Node.js 项目可以直接用 bun run 替代 node 而不需要改代码。

—— 广告 ——

安装 Bun

macOS / Linux

最推荐的安装方式(一条命令):

code
curl -fsSL https://bun.com/install | bash

安装完成后验证:

code
bun --version
# 输出类似: 1.2.5

注意 Linux 需要先安装 unzip

code
sudo apt install unzip

Windows

code
powershell -c "irm bun.sh/install.ps1|iex"

需要 Windows 10 1809 或更新版本。

其他方式

用 npm 安装

code
npm install -g bun

用 Homebrew 安装

code
brew install oven-sh/bun/bun

Docker

code
docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun

升级 Bun

code
bun upgrade

如果你想试试最新的开发版(可能有 bug):

code
bun upgrade --canary

回到稳定版:

code
bun upgrade --stable

运行时:从 Hello World 到生产服务

直接跑 TypeScript

Bun 最大的卖点之一:开箱支持 TypeScript,不需要 ts-nodetsx

创建一个 hello.ts

code
interface User {
  name: string;
  age: number;
}
 
const greet = (user: User): string => {
  return `Hello, ${user.name}! You are ${user.age} years old.`;
};
 
console.log(greet({ name: "四月", age: 18 }));

直接运行:

code
bun run hello.ts
# 输出: Hello, 四月! You are 18 years old.

不需要 tsconfig.json,不需要 ts-node --transpile-only。Bun 内置的 TypeScript 转译器自动处理。

快速启动一个 HTTP 服务器

Bun 内置了高性能的 HTTP 服务器 API:

code
// server.ts
Bun.serve({
  port: 3000,
  fetch(request) {
    const url = new URL(request.url);
    
    if (url.pathname === "/api/hello") {
      return Response.json({ message: "Hello from Bun!" });
    }
    
    if (url.pathname === "/api/users") {
      return Response.json([
        { id: 1, name: "Alice" },
        { id: 2, name: "Bob" }
      ]);
    }
    
    return new Response("Not Found", { status: 404 });
  },
});
 
console.log("Server running on http://localhost:3000");

启动:

code
bun run server.ts

这个服务器底层基于 WebKit 的 JavaScriptCore 引擎和自研的 HTTP 解析器,性能上比 Node.js 的 http 模块大约快 4 倍。

热重载开发

code
bun --hot run server.ts

--hot 模式会在文件变更时自动重新加载模块,不需要手动重启。和 nodemon 不同,Bun 的热重载不会重启整个进程,而是只重新加载变更的模块,速度更快。

文件操作

Bun 实现了 Web 标准的 File API:

code
const file = Bun.file("data.json");
const json = await file.json();
console.log(json);
 
// 写入文件
await Bun.write("output.txt", "Hello from Bun!");

Bun 的 Bun.file() 针对大文件做了流式读取优化,比 Node.js 的 fs.readFile 在内存使用上更高效。

环境变量

Bun 自动加载 .env 文件:

code
# .env
DATABASE_URL=postgresql://localhost:5432/mydb
API_KEY=sk-123456

在代码中通过 process.env 访问:

code
const dbUrl = process.env.DATABASE_URL;
const apiKey = process.env.API_KEY;

不需要 dotenv 包。Bun 在启动时自动读取 .env.env.local.env.production 等文件。如果同时存在多个,优先级是 .env.local > .env.production > .env

包管理器:快 30 倍的 npm 替代

这是大部分人第一次接触 Bun 的入口。bun install 比 npm install 平均快 30 倍。

基本用法

code
# 安装 package.json 中的所有依赖
bun install
 
# 安装一个包
bun add express
 
# 安装开发依赖
bun add -D typescript
 
# 安装全局包
bun add -g eslint
 
# 卸载包
bun remove express

为什么这么快?

Bun 的包管理器有这三个优化:

  1. 全局解析缓存:第一次安装后,包的解析结果缓存在 ~/.bun/install/cache/。第二个项目安装同一个包时,直接从缓存读,不需要重新请求 npm registry。
  2. 并发下载:Bun 用 Rust 写的 HTTP 客户端并行下载包,比 Node.js 的单线程下载快得多。
  3. 无 node_modules 解压:Bun 将包存储在全局缓存中,在 node_modules 里创建硬链接或符号链接,而不是每个项目都解压一份副本。

workspace(单体仓库)支持

Bun 原生支持 npm/yarn 风格的 workspace:

code
{
  "name": "my-monorepo",
  "workspaces": ["packages/*"],
  "dependencies": {
    "typescript": "^5.0.0"
  }
}
code
bun install

Bun 会正确解析 workspace 中的交叉依赖,比 npm workspace 快 20-30 倍。

锁文件

Bun 使用自己的二进制锁文件格式 bun.lock(v1.x)或 bun.lockb(旧版)。和 package-lock.json 不一样,它是二进制格式,解析速度比 JSON 快几个数量级。不兼容 npm 的 package-lock.json,所以如果你在 CI 中同时使用 npm 和 Bun,需要注意。

测试框架:开箱即用的测试环境

Bun 内置了测试运行器,兼容 Jest API:

code
// math.test.ts
import { describe, expect, test } from "bun:test";
 
function add(a: number, b: number): number {
  return a + b;
}
 
describe("add function", () => {
  test("adds positive numbers", () => {
    expect(add(1, 2)).toBe(3);
  });
 
  test("adds negative numbers", () => {
    expect(add(-1, -2)).toBe(-3);
  });
});

运行测试:

code
bun test

Jest 迁移

如果你有现有的 Jest 测试,迁移成本很低。Bun 实现了大部分 Jest API:

  • describe / it / test
  • expect / toBe / toEqual / toMatchSnapshot
  • beforeEach / afterEach / beforeAll / afterAll
  • jest.fn() / jest.mock() / jest.spyOn()

Bun 也支持 mock:

code
import { mock, spyOn } from "bun:test";
 
const mockFn = mock(() => 42);
mockFn(); // returns 42
expect(mockFn).toHaveBeenCalledTimes(1);

Snapshot 测试

code
bun test --update-snapshots  # 更新 snapshot
bun test                     # 运行并对比 snapshot

Bun 的测试运行器性能非常出色——一个包含 500 个测试用例的项目,Bun 测试可以在 3 秒内完成,而 Jest 需要 15 秒以上。

打包器:从零配置到生产构建

Bun 内置的打包器支持 JS、TS、JSX、CSS 和 HTML:

code
# 打包 TypeScript 到单个 JS 文件
bun build ./src/index.tsx --outdir ./dist
 
# 打包到浏览器兼容的 ESM
bun build ./src/index.tsx --outdir ./dist --target browser
 
# 压缩输出
bun build ./src/index.tsx --outdir ./dist --minify

高级打包配置

bunfig.toml 配置打包行为:

code
[build]
outdir = "./dist"
target = "browser"
minify = true
sourcemap = "external"
splitting = true
 
[build.loader]
.svg = "file"
.png = "file"
.css = "text"

CSS 支持

Bun 的打包器原生支持 CSS 导入:

code
// styles.css
.button {
  background: blue;
  color: white;
}
code
// component.ts
import "./styles.css";  // Bun 会自动处理 CSS

Bun 也支持 CSS Modules、CSS 压缩和 PostCSS 插件。

实际项目:用 Bun 搭建一个完整的 API 服务

来一个实际的项目创建流程:

code
# 创建项目目录
mkdir bun-api-demo && cd bun-api-demo
 
# 初始化项目(创建 package.json)
bun init -y
 
# 安装依赖
bun add express
bun add -D @types/express typescript
 
# 创建入口文件
mkdir src

src/index.ts 中:

code
import express from "express";
 
const app = express();
const port = process.env.PORT || 3000;
 
app.use(express.json());
 
// 路由
app.get("/api/health", (_req, res) => {
  res.json({ status: "ok", runtime: "bun" });
});
 
app.get("/api/items", (_req, res) => {
  res.json([
    { id: 1, name: "Item 1" },
    { id: 2, name: "Item 2" },
  ]);
});
 
app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

package.json 中配置脚本:

code
{
  "scripts": {
    "dev": "bun --hot run src/index.ts",
    "start": "bun run src/index.ts",
    "test": "bun test",
    "build": "bun build ./src/index.ts --outdir ./dist --target bun"
  }
}

运行:

code
bun run dev

与 Node.js 的兼容性

Bun 在 API 层面高度兼容 Node.js:

特性状态说明
fs / path / http✅ 完整最常用的内置模块
child_process✅ 完整exec / spawn / fork
crypto✅ 完整包括 randomUUIDcreateHash
stream✅ 大部分Web Streams 优先
worker_threads✅ 基础建议用 Bun.Worker
cluster⚠️ 部分建议用 PM2 或反向代理
node-gyp 原生模块⚠️ 部分纯 JS 模块没问题,C++ addon 视情况支持

迁移建议:从一个现有的 Node.js 项目迁移到 Bun,可以先试试 bun run dev(开发模式),如果一切正常再切换到 bun run start(生产模式)。大多数 Express/Fastify/Next.js 项目可以直接在 Bun 下运行。

常用的 Bun 配置

bunfig.toml

Bun 的行为通过项目根目录的 bunfig.toml 配置:

code
# 配置安装行为
[install]
registry = "https://registry.npmjs.org"
optional = true
frozenLockfile = false
 
# 配置测试
[test]
timeout = 10000  # 10 秒超时
coverage = true  # 启用覆盖率报告
 
# 配置运行时
[run]
smol = true  # 减少内存占用

什么时候该用 Bun?

适合的场景

  • 新项目启动:零配置体验,从 bun initbun runbun test 都在同一个命令下
  • Node.js 项目加速:直接替换 nodebun,大部分项目无感迁移
  • CLI 工具开发:Bun 的启动速度快于 Node.js(4x),适合 CLI 场景
  • 前端工具链:用 Bun 替代 webpack/esbuild 做打包
  • Monorepo:Bun workspace + 全局缓存极大减少 install 时间

需要谨慎的场景

  • 重度依赖 C++ 原生模块的项目:node-gyp 兼容性还在演进中
  • 对 Node.js 版本兼容性要求极高的生产环境:虽然兼容性很好,但有些极端 edge case 需要测试
  • 已经深度绑定 V8 特定行为的项目:Bun 用的是 JavaScriptCore,不是 V8

总结

Bun 不是又一个 JavaScript 工具——它是 JavaScript 工具链的重新思考。一个二进制文件做四件事(运行时、包管理器、测试、打包),意味着开发环境从一个复杂的工具矩阵简化为一条命令。

对独立开发者来说,这种简化非常有价值。减少「xxx 配置错了」的调试时间,把精力放在真正重要的业务逻辑上。

如果你还没试过,今天就可以:

code
curl -fsSL https://bun.com/install | bash
mkdir my-first-bun-project && cd my-first-bun-project
bun init
bun run index.ts

从一行命令到跑起来,整个过程应该在 30 秒内完成。

参考来源:Bun 官方文档Bun GitHub

分享到
微博Twitter

© 2026 四月

原文链接:https://www.aprilzz.com/tutorials/bun-runtime-guide