Bun 实战:更快的 JavaScript 运行时与工具链

Bun 是近年来成长最快的 JavaScript 运行时 之一。它用 Zig 语言编写、底层基于 Apple 的 JavaScriptCore 引擎,从一开始就瞄准「更快的 Node.js 替代」这一目标——不仅运行时本身快,还把包管理、测试、打包、HTTP 服务全部内置,试图用一个二进制替代 npm、jest、esbuild、nodemon 等一整套工具链。本文带你从安装到生产落地把 Bun 真正跑起来。

一、为什么还需要一个新的运行时

Node.js 统治服务端 JavaScript 已十余年,但在启动速度、冷启动内存、内置 API 完整度上存在明显短板:原生没有内置测试框架,需要引 jest;没有内置打包,需要引 esbuild 或 webpack;TypeScript 必须过一层编译;就连最基础的 HTTP 服务也得依赖 Express、Koa 这类第三方库。当 Serverless、边缘函数把「冷启动」变成核心指标时,Node 的短板被进一步放大。

Bun 的出现正是想把这些「标配能力」直接塞进运行时本身。它不是又一个跑在 V8 上的兼容层,而是用 Zig 重写了运行时内核,并选择启动极快的 JavaScriptCore 作为引擎。结果是:安装即用、运行即快、工具链自带。

二、Bun 到底是什么

Bun 的核心是一体化的工具链:运行时(兼容 Node.js 大部分 API)、包管理器(bun install 比 npm 快数倍)、测试运行器(bun test)、打包器(bun build),以及 Bun.serve 提供的高性能 HTTP 服务。它默认支持 TypeScript、JSX,无需额外配置即可直接运行 .ts 文件,对前端开发者极其友好。

2.1 一个二进制替代一整套工具

过去一个标准前端/Node 工程至少要装 node、npm/yarn、jest、esbuild、ts-node;换成 Bun 之后,这些角色都被一个 bun 命令覆盖。CI 镜像体积、依赖安装时间、本地环境不一致导致的「在我机器上能跑」问题,都能明显缓解。

2.2 与 Node.js 的兼容性边界

Bun 实现了 Node 的绝大部分 API(fs、path、process、Buffer、stream 等),绝大多数纯 JS 库可以直接跑。但部分用 C++ 编写的 .node 原生插件仍可能不兼容,迁移存量大型项目时需重点验证这一类依赖。

三、安装与版本管理

官方推荐通过 curl 一键安装,也可以用 npm 或 Homebrew。Bun 是单文件二进制,升级本质上就是覆盖二进制,因此非常适合在容器里固定版本。

# 官方一键安装
curl -fsSL https://bun.sh/install | bash

# 或用 Homebrew
brew install oven-sh/bun/bun

# 验证
bun --version

四、直接运行 TypeScript(无需编译)

Bun 内置了 TypeScript 转译器,直接 bun run 即可执行 .ts 文件,不需要 tsc 或 ts-node。下面是一段用内置 fetch(遵循 Web 标准)请求接口的例子:

// hello.ts
const res = await fetch("https://api.example.com/health");
const data = await res.json();
console.log("status", data);

// 直接运行,无需任何编译步骤
bun run hello.ts

五、内置测试:bun test

不再需要 jest。Bun 自带测试运行器,语法与 expect 风格一致,启动是毫秒级,且自带覆盖率统计。对一个工具库做单元验证,体验比传统方案顺滑很多。

// sum.test.ts
import { expect, test } from "bun";

test("adds numbers", () => {
  expect(1 + 1).toBe(2);
});

// 运行全部测试
bun test

# 带覆盖率
bun test --coverage

六、包管理:bun install

bun install 采用全局缓存 + 硬链接的方式,首次安装可能受网络影响,但二次安装几乎瞬间完成。生产环境强烈建议用 –frozen-lockfile 锁定依赖树,保证构建可复现。

# 安装依赖(远快于 npm install)
bun install

# CI 中锁定版本,保证可复现
bun install --frozen-lockfile

七、内置打包:bun build

生产构建可以直接用 bun build,API 风格类似 esbuild,能够把 TS/JSX 打包成单文件或目录,也能在代码里以 API 方式调用。

# 命令行打包
bun build ./src/index.ts --outfile=dist/app.js --target=node

# 或在代码里调用打包 API
import { build } from "bun";
await build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist",
});

八、用 Bun.serve 写 HTTP 服务

Bun 内置的高性能 HTTP 服务基于 uWS 风格的实现,无需 Express 也能直接起服务,并天然支持 WebSocket,非常适合写轻量级 API 与实时网关。

Bun.serve({
  port: 3000,
  fetch(req) {
    const url = new URL(req.url);
    if (url.pathname === "/health") {
      return Response.json({ ok: true });
    }
    return new Response("Hello from Bun!");
  },
});

console.log("listening on :3000");

九、Bun 与 Node.js、Deno 怎么选

三者定位并不完全重叠,下面这张表帮你快速判断该把 Bun 放在什么位置:

维度BunNode.jsDeno
底层引擎JavaScriptCoreV8V8
启动速度最快一般较快
内置工具链包管理/测试/打包/HTTP无(依赖生态)测试/格式化/权限
TS 支持原生需编译原生
Node 兼容较高原生逐步兼容

十、生产落地检查清单

如果你打算在服务器上用 Bun 跑线上服务,建议逐项核对,避免踩到环境不一致的坑:

检查项建议
版本固定用 bunfig.toml 或 CI 锁定版本,避免自动升级引发副作用
进程守护配合 systemd 或容器,进程崩了能自动拉起
依赖安装CI 用 bun install –frozen-lockfile 保证可复现
健康检查暴露 /health 端点,供反向代理探活
反向代理前面挂 Nginx/Caddy 做 TLS 终止与静态资源
可观测用 Prometheus 抓取指标,配 Grafana 看板监控

十一、常见报错与排查

迁移期最容易遇到的是原生模块兼容问题。若某个 npm 包依赖 C++ addon,可先尝试用 npm 安装该包后让 Bun 复用 node_modules;其次是 ESM/CJS 混用导致的 import 报错,Bun 默认优先 ESM,老项目的 require 语法建议加 “type”:”module” 或在文件里改用 import;最后,生产环境尽量用 bun build 产出独立 bundle,避免运行时再去解析 TS,从而降低冷启动与内存占用。

# 依赖安装失败时用 npm 兜底
npm install
# 然后用 Bun 运行,复用 node_modules
bun run start

# 产出独立可执行 bundle
bun build ./src/index.ts --compile --outfile=server

十二、局限与适用场景

Bun 并非银弹。它对 Node 生态的兼容虽高,但部分重度依赖 Node 内部行为的老库仍可能踩坑;一些云厂商 SDK 的原生插件也需要实测。对于新项目、CLI 工具、高频冷启动的 Serverless/边缘函数,Bun 的收益最明显;存量大型单体服务迁移则需充分测试与灰度。

如果你已经用 Vite 构建前端,或打算用 Web Components 封装 UI,Bun 在本地开发与构建环节都能顺滑衔接;把它作为 前端数据请求 的后端 API 服务也相当轻量。部署时配合 Caddy 自动 HTTPS 或 Nginx 反向代理,再加上 GitHub Actions 做持续集成,即可组成一条现代前端全栈流水线。

十三、从零跑通一个最小服务

把上面的能力串起来,一个最小可上线的 Bun 服务其实只需要几十行:用 Bun.serve 提供接口,用 bun build 产出 bundle,前面挂一层反向代理做 TLS。比起传统 Node + 一堆依赖的栈,Bun 让「写一个小而快的服务」这件事重新变得轻巧。

上一篇 Redpanda 实战:Kafka 兼容的高性能流数据平台
下一篇 LlamaIndex 实战:用索引与检索器构建生产级 RAG 应用
最新评论
Docker 网络模式详解:bridge/host 生产选型 - FSData
Docker 网络模式详解:bridge/host 生产选型 - FSData
8月20日
[…] 注意最后那条:把端口绑定到 127.0.0.1,再由宿主机上的 Nginx 反代进来,比直接 -p 80:80 暴露安全得多,也方便统一做
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
8月20日
[…] Pinia 的工程化用法,可以参考我们之前的实战文章 《Vue3 组合式 API + Pinia:状态管理从入门到实战》,那里覆盖了 Sto
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
8月19日
[…] 状态,点一下就能起停容器,配合我们讲过的 Docker Compose 编排 […]
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
8月19日
[…] 缓存三大坑的本质都是”缓存失效导致请求穿透到数据库”。记住口诀:穿透用布隆、击穿用锁、雪崩用错峰。配合合理的过期策略
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
8月19日
[…] Docker 镜像部署。结合我们之前写的 Docker Compose 一键编排实战,可以在 CI […]