Bun:把 JavaScript 运行时、包管理器、测试和打包合在一起

Bun 是 oven-sh 开源的 JavaScript / TypeScript 一体化工具链,把运行时、包管理器、脚本运行器、测试运行器和打包器整合到一个 bun 命令里,目标是在尽量兼容 Node.js 生态的同时提升启动速度、安装速度和开发体验。

Bun 是 oven-sh 开源的 JavaScript / TypeScript 一体化工具链。

它不是只想做一个更快的 Node.js 替代品,而是把运行时、包管理器、脚本运行器、测试运行器和打包器都塞进同一个 bun 命令里。对前端和 Node.js 开发者来说,Bun 的吸引力在于:少装一堆工具,少等一堆安装和构建过程,很多常见任务可以直接用一个命令完成。

项目地址:https://github.com/oven-sh/bun

先说结论

Bun 最适合想简化 JavaScript 工具链的人。

它能做这些事:

  • 运行 JavaScript、TypeScript、JSX 和 TSX。
  • 作为 Node.js 兼容运行时。
  • 替代 npm / yarn / pnpm 做包管理。
  • 运行 package.json 里的 scripts。
  • 执行测试。
  • 打包前端或后端代码。
  • bunx 执行 npm 包里的命令。
  • 提供 Bun.servebun:sqliteBun.sqlBun.redisBun.s3 等内建 API。

它最明显的价值是开发体验:安装依赖快、启动快、命令统一、TypeScript 和 JSX 开箱即用。

但 Bun 也不是所有项目都该立刻切换。大型 Node.js 项目、依赖大量原生扩展的项目、生产稳定性要求极高的服务,仍然需要逐项验证兼容性、构建行为、测试行为和部署方式。

Bun 是什么

按照官方 README 的描述,Bun 是一个面向 JavaScript 和 TypeScript 应用的一体化工具包。它以单个可执行文件 bun 发布。

它的核心是 Bun runtime:一个快速 JavaScript 运行时,目标是作为 Node.js 的 drop-in replacement。Bun 使用 Zig 编写,底层基于 JavaScriptCore,重点优化启动时间和内存占用。

这意味着你可以直接运行:

1
bun run index.tsx

TypeScript 和 JSX 不需要额外配置就能跑。

同一个 bun 命令还包含:

  • test runner
  • script runner
  • Node.js 兼容包管理器
  • bundler
  • package runner

常见命令包括:

1
2
3
4
bun test
bun run start
bun install <pkg>
bunx cowsay 'Hello, world!'

过去一个项目里可能同时出现 nodenpmpnpmtsxjestvitestwebpackesbuildts-node 等工具。Bun 的路线是尽量把高频路径收进一个工具里。

安装方式

Bun 支持 Linux、macOS 和 Windows,覆盖 x64 与 arm64。

官方推荐安装脚本:

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

Windows:

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

也可以通过 npm 安装:

1
npm install -g bun

macOS Homebrew:

1
2
brew tap oven-sh/bun
brew install bun

Docker:

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

Linux 用户要注意内核版本。README 提到强烈建议 Linux kernel 5.6 或更高,最低要求是 5.1

升级到最新版:

1
bun upgrade

升级到 canary:

1
bun upgrade --canary

生产环境一般不建议直接用 canary,除非你是在验证新特性或排查特定 bug。

为什么 Bun 会快

Bun 的“快”主要来自几个层面。

第一,运行时启动快。

很多 CLI 工具和开发脚本的瓶颈不是长期 CPU 运算,而是进程启动、模块加载、TypeScript 转译和依赖解析。Bun 针对这些路径做了很多优化。

第二,包管理快。

bun install 的目标是替代 npm / yarn / pnpm 的依赖安装流程。它使用全局缓存和自己的 lockfile,安装大量依赖时通常能明显减少等待。

第三,TypeScript / JSX 开箱即用。

很多项目只是想运行一个 .ts.tsx 脚本,传统 Node.js 工具链需要额外加 tsxts-node、Babel 或构建步骤。Bun 可以直接跑,减少了胶水工具。

第四,内置工具减少进程和配置切换。

测试、脚本、打包、运行都在同一个工具里,很多场景不用再在多个 CLI 之间切换。

但要注意,“Bun 很快”不等于每个项目都一定更快。真实效果取决于依赖类型、脚本逻辑、测试框架、构建配置、Node.js API 使用情况和 CI 缓存策略。

包管理:替代 npm / yarn / pnpm

Bun 可以直接安装依赖:

1
bun install

添加依赖:

1
bun add react

添加开发依赖:

1
bun add -d typescript

移除依赖:

1
bun remove react

查看依赖原因:

1
bun why react

安全检查:

1
bun audit

如果你从 npm 或 pnpm 迁移,重点要看:

  • bun.lock 是否进入版本控制。
  • CI 是否使用 bun install --frozen-lockfile
  • 私有 registry 和 .npmrc 是否兼容。
  • workspace 行为是否符合预期。
  • lifecycle scripts 是否会带来安全风险。
  • 原本依赖 pnpm 特性的 monorepo 是否能平滑迁移。

小项目可以直接试。大型 monorepo 不建议一次性全切,可以先在单个 package 或 CI 的非关键任务里试。

运行脚本和 TypeScript

Bun 可以运行 package.json 里的脚本:

1
bun run start

也可以直接运行文件:

1
2
bun run index.ts
bun run index.tsx

这对工具脚本很方便。比如以前项目里有一堆:

  • scripts/build.ts
  • scripts/seed.ts
  • scripts/migrate.ts
  • scripts/check.ts

如果用 Node.js,通常要解决 TypeScript loader 或预编译问题。Bun 的直接运行能力可以让这些脚本更轻。

不过,如果脚本依赖 Node.js 特定行为,尤其是 loader、ESM/CJS 边界、原生模块、child process、文件监听和某些边缘 API,仍然要测试。

测试运行器

Bun 内置测试运行器:

1
bun test

它适合想减少 Jest / Vitest 配置的小项目,也适合把一些单元测试、工具测试、库测试迁移到更轻的运行方式。

迁移测试时重点关注:

  • expect 行为差异。
  • mock API 差异。
  • snapshot 行为。
  • DOM 测试环境。
  • 测试发现规则。
  • 覆盖率输出。
  • CI reporter 支持。

如果项目已经深度依赖 Jest 生态,比如大量自定义 matcher、复杂 mock、jsdom、babel-jest、ts-jest,迁移就不要太急。可以先让新模块用 bun test,旧测试继续保留原框架。

打包和构建

Bun 也提供 bundler,常见用法是:

1
bun build ./src/index.ts --outdir ./dist

它可以用于前端包、后端脚本、CLI 工具和库构建。Bun 文档里还覆盖了 loaders、plugins、macros、CSS、HTML、HMR、minifier、single-file executable 等方向。

适合优先尝试的场景:

  • 小型前端工具。
  • Node.js CLI。
  • 内部脚本。
  • 单文件服务。
  • 不依赖复杂 webpack loader 的项目。

谨慎迁移的场景:

  • 复杂 webpack 插件链。
  • 大量 Vite 插件。
  • 深度依赖 Babel 转换。
  • 特殊 CSS / asset pipeline。
  • 微前端和模块联邦。
  • 对构建产物 hash、chunk、兼容性要求很细的项目。

Bun bundler 很有吸引力,但构建工具迁移的风险通常比包管理更高,最好单独验证。

运行 HTTP 服务

Bun 提供 Bun.serve 来写 HTTP 服务:

1
2
3
4
5
6
Bun.serve({
  port: 3000,
  fetch(req) {
    return new Response("Hello from Bun")
  },
})

这对小型 API、内部服务、Webhook receiver、边缘风格服务很方便。Bun 还提供 WebSockets、Workers、Streams、SQLite、PostgreSQL、Redis、S3、TCP/UDP sockets 等 API。

但如果你已有 Express、Fastify、NestJS、Next.js、Hono、Elysia 等框架,也可以先看它们在 Bun 上的兼容程度,不必为了用 Bun 就重写服务。

更现实的路径是:

  1. 先用 Bun 做开发脚本和包管理。
  2. 再用 Bun 跑测试。
  3. 最后评估是否把运行时切到 Bun。

运行时迁移最需要谨慎,因为它直接影响生产服务行为。

和 Node.js 的关系

Bun 的目标之一是作为 Node.js 的 drop-in replacement,但“兼容”不是“完全等同”。

Node.js 生态已经积累了很多年,很多包依赖细微行为:

  • CJS / ESM 互操作。
  • Node 内置模块。
  • 原生扩展。
  • npm lifecycle scripts。
  • 文件系统边缘行为。
  • stream 和 Buffer 细节。
  • worker / child_process。
  • 调试和 profiling。

Bun 在兼容性上进步很快,但生产迁移仍要以测试结果为准。

比较稳妥的判断方式:

  • 你的测试能否在 Bun 下通过。
  • 关键依赖是否支持 Bun。
  • 构建产物是否一致。
  • CI 和本地表现是否一致。
  • 线上运行是否有监控和回滚。
  • Docker 镜像和部署脚本是否稳定。

如果只是替换包管理器,风险较低;如果替换生产运行时,风险高很多。

适合哪些项目

Bun 很适合这些场景:

  • 新的 JavaScript / TypeScript 小项目。
  • 内部工具和脚本。
  • CLI 项目。
  • 需要快速安装依赖的 CI。
  • 希望减少工具链复杂度的前端项目。
  • 对启动速度敏感的脚本和服务。
  • 想用 TypeScript 开箱即跑的开发者。

暂时要谨慎的场景:

  • 超大型 monorepo。
  • 深度绑定 pnpm workspace 行为的项目。
  • 依赖大量 Node.js 原生扩展的服务。
  • 构建链路高度定制的前端工程。
  • 对生产运行时一致性要求极高的后端。
  • 依赖 Jest 复杂生态的测试套件。

一个保守但实用的策略是:先把 Bun 当作开发工具,而不是马上替代全部生产运行时。

迁移建议

如果想在现有项目试 Bun,可以按这个顺序:

  1. 在本地安装 Bun。
  2. 运行 bun install,观察依赖安装结果。
  3. 提交或暂存 bun.lock,避免和原 lockfile 混用造成混乱。
  4. 尝试 bun run <script> 跑常用脚本。
  5. bun test 迁移少量测试。
  6. 在 CI 加一个非阻塞 Bun job。
  7. 确认没有兼容问题后,再考虑替换主安装流程。
  8. 最后再评估生产运行时是否切换。

对于团队项目,最好保留回滚路径:

  • 迁移前保留原 npm / pnpm / yarn 流程。
  • CI 里同时跑一段时间。
  • 不要在同一次改动里同时换运行时、包管理器、测试框架和打包器。
  • 把迁移拆成小步骤,每一步都有可验证收益。

这样做虽然慢一点,但不容易把问题混在一起。

常见命令速查

安装:

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

升级:

1
bun upgrade

安装依赖:

1
bun install

添加依赖:

1
bun add lodash

运行脚本:

1
bun run dev

直接运行 TypeScript:

1
bun run scripts/build.ts

测试:

1
bun test

打包:

1
bun build ./src/index.ts --outdir ./dist

执行包命令:

1
bunx cowsay 'Hello, world!'

总结

Bun 的价值不只是“比 Node.js 快”。更重要的是,它把 JavaScript / TypeScript 开发里一堆分散工具收进了一个 bun 命令:运行时、包管理器、脚本运行器、测试运行器和打包器。

对新项目和内部工具来说,这种一体化体验很舒服:安装快、启动快、配置少,TypeScript 和 JSX 也能直接跑。对已有大型项目来说,Bun 更适合先从低风险环节切入,比如包安装、脚本和部分测试,再逐步验证构建和运行时。

如果你经常被 Node.js 工具链里的安装速度、配置碎片和测试启动时间折磨,Bun 值得认真试一下。但真正迁移生产服务时,还是要回到最朴素的工程判断:测试能不能过、依赖是否兼容、CI 是否稳定、线上有没有回滚。

参考链接:

记录并分享
使用 Hugo 构建
主题 StackJimmy 设计