首页 / Bun 入门教程 / Bun 与 Node.js 的关系

Bun 入门教程

Bun 与 Node.js 的关系

本教程共 34 篇 · 第 4 篇 · 更新于 2026-08-06

BunNode.js兼容性迁移运行时对比JavaScriptCore

本节目标:

  • 厘清 Bun 与 Node.js 是「兼容」而非「fork」的关系
  • 了解 Bun 对 Node.js API 的兼容性目标与当前进展
  • 知道在什么场景下适合引入 Bun,什么场景应谨慎
  • 建立从 Node.js 项目迁移到 Bun 的基本思路,不盲从、不焦虑

很多初学者会把 Bun 理解成「另一个 Node.js」,或者担心「用 Bun 是不是就要抛弃 Node.js 生态」。这一节我们把它讲清楚:Bun 的设计初衷是与 Node.js 高度兼容,让绝大多数 npm 包、框架和既有代码能直接在 Bun 上跑,而不是另起炉灶。

4.1 Bun 不是 Node.js 的 fork

Node.js 是用 C++ 写的运行时,底层使用 V8 引擎。Bun 则是一个独立的运行时实现,最初用 Zig 编写,底层使用 JavaScriptCore(Apple 的 JavaScript 引擎,Safari 同款)。

Note

Oven 官方已宣布把 Bun 的实现语言从 Zig 迁移到 Rust。但截至本教程基线 v1.3.14,稳定版仍是 Zig 实现。这属于项目演进方向,不是你现在能用上的功能,具体见第 34 章。

所以它们的关系是:

  • 不是分支(fork):Bun 没有从 Node.js 源码派生,而是重新实现了一套运行时。
  • 是兼容实现:Bun 主动实现 Node.js 的 API、全局对象和内置模块,目标是让为 Node.js 写的代码能「原样」在 Bun 上运行。
  • 共享生态:Bun 直接复用 npm registry 上的包、package.json 约定、node: 内置模块等,你的大部分依赖不需要改动。
Note

判断一个包是否能在 Bun 上工作,最直接的标准是「它在 Node.js 上能跑吗」。官方态度很明确:如果一个包在 Node.js 里能用、在 Bun 里却不行,这会被视为 Bun 的 bug,官方会修复。这从侧面说明 Bun 把「兼容 Node.js」当作一等目标。

4.2 兼容性目标与现状

Bun 官网首页写得很直白:Bun aims for 100% Node.js compatibility——注意是 aims(目标),不是 achieved。官方文档维护了一张兼容性对照表,逐项标注内置模块与全局对象的实现状态(🟢 完全实现、🟡 部分实现),并给出各模块在 Node.js 测试套件上的通过率。

从对照表看,大量常用模块已是 🟢 完全实现,例如:

  • node:assertnode:buffernode:consolenode:events
  • node:fsnode:pathnode:urlnode:osnode:netnode:stream
  • node:eventsnode:osnode:pathnode:url 等模块的测试套件通过率已达 100%
Note

通过率数字随版本变动很快,对照表本身也在持续更新。要看你手上这个版本的准确状态,直接查官方 Node.js 兼容性页面,别依赖任何教程里抄下来的百分比。

也有一部分属于 🟡 部分实现,例如:

  • node:crypto:缺少 setEnginesetFips 等少数接口
  • node:worker_threads:部分选项与少量方法未实现
  • node:child_process:少数属性(如 proc.gid / proc.uid)与部分 IPC 能力缺失
  • node:cluster:跨进程传递句柄仅在特定平台(Linux 通过 SO_REUSEPORT)支持
  • node:test:仅部分实现,官方建议直接用 bun test 而非 node:test
  • node:inspector:仅 Profiler 相关 API 实现
Warning

「100% 兼容」是目标,不是已达成状态。在重度依赖上述 🟡 模块(尤其是 worker_threadschild_process、原生插件、性能剖析)的项目里,迁移前务必先在 Bun 上实测,不要想当然认为一切照旧。官方兼容表会随版本更新,请以你所用的 Bun 版本对应文档为准。

4.3 Bun 提供的三类 API

在 Bun 运行时里,你能用到三类 API,理解它们的层次有助于写对代码:

  1. Web 标准 APIfetchWebSocketResponseRequestHeadersReadableStream 等。这些是浏览器与 Deno、Bun 共享的标准,写前端的人会很熟悉。
  2. Node.js 兼容 APInode:fsnode:httpnode:pathrequire()__dirname 等。这些让既有的 Node.js 生态能直接复用。
  3. Bun 原生 API:以 Bun.* 命名空间暴露,例如 Bun.serve()(HTTP 服务器)、Bun.file()Bun.write()Bun.spawn()Bun.$(Shell)等;内置模块则用 bun: 前缀导入,例如 bun:sqlite。这些是 Bun 的「增值能力」,提供比 Node.js 更简洁的封装。
// Web 标准
const res = await fetch("https://example.com");

// Node.js 兼容
import { readFileSync } from "node:fs";
const text = readFileSync("data.txt", "utf8");

// Bun 原生
const server = Bun.serve({ port: 3000, fetch: () => new Response("hi") });
Tip

写新项目时,优先用 Web 标准与 Bun 原生 API,往往代码更短;维护老项目或引入第三方库时,则依赖 Node.js 兼容 API。三者可以混用,不必二选一。

4.4 什么时候适合用 Bun

下面这些场景,引入 Bun 的收益通常比较明显:

  • 想用 TypeScript / JSX 但讨厌配置构建链bun run 免编译直跑,省掉 ts-nodetsx、esbuild 配置。
  • 脚本与工具类程序:CLI、构建脚本、数据处理,看重启动速度与简单性。
  • HTTP 服务与全栈应用Bun.serve 内置路由与静态资源,配合热重载开发体验好。
  • 测试bun test 开箱即用,无需额外装 Jest / Vitest。
  • 希望「一体化」工具链:运行时、包管理器、测试、打包器统一由 Bun 提供,减少工具碎片。

Bun 在性能上确实有不少亮点:内置转译与运行时层面的优化使启动更快、安装依赖更快。但请理性看待——性能优势主要体现在「工具链开销」(安装、启动、转译、测试)上,业务代码本身的运行速度差异,取决于具体负载,并不一定总是 Bun 胜出。

4.5 什么时候要谨慎

  • 强依赖特定原生模块 / Node.js 私有接口:用到 worker_threads 高级选项、child_process 完整能力、特定 C++ 插件或 node:inspector 深度功能时,先验证。
  • 生产环境对运行时有严格合规要求:若团队已对 Node.js 的长期支持(LTS)与漏洞响应有成熟流程,切换运行时需要相应的评估与回归测试。
  • 依赖某款仅适配 Node.js 的工具:例如某些通过 node 二进制做进程注入、符号链接或特殊 shebang 的工具,需确认 Bun 的 node 兼容模式是否满足。
  • 团队学习成本:新工具意味着新踩坑点,评估时要算上团队熟悉度。
Note

Bun 提供了 bun --bun / node 兼容模式:在 bun run 时可以把 node 透明替换成 bun,很多原本调用 node 的脚本无需改动即可在 Bun 上运行。这是降低迁移阻力的实用特性,但遇到真正依赖 Node.js 独有行为的场景仍需实测。

4.6 从 Node.js 迁移的思路

如果你打算把现有 Node.js 项目试跑在 Bun 上,推荐渐进式、可逆的路线:

  1. 先装 Bun,不删 Node.js:两者可共存,随时回退。
  2. 用 Bun 跑现有脚本bun run 直接执行你的入口文件,看是否能启动。
  3. bun install 装依赖:它兼容 package.json,会生成文本锁文件 bun.lock;CI 里加 --frozen-lockfile,锁文件与 package.json 对不上时直接报错,而不是悄悄改锁文件。
  4. 逐项替换工具,而非一次性重写
    • npm run testbun test
    • node index.jsbun run index.js
    • tsx / ts-node → 直接用 bun run *.ts
  5. 问题隔离:若某依赖在 Bun 上报错,先确认是包的问题还是 Bun 兼容问题;前者提 issue 给 Bun,后者提给包维护者或寻找替代。
  6. 保留回退能力:在 CI / 生产里先以 Node.js 为主,Bun 作为并行验证,跑稳后再考虑切换默认运行时。
Warning

不要为了「赶时髦」把整个生产系统一次性切到 Bun。最稳妥的方式是先在开发、测试、CLI 工具等非核心路径上用起来,积累经验与信心,再评估核心服务。迁移的本质是降低风险,而不是增加风险。

4.7 小结

  • Bun 是 兼容 Node.js API 的独立运行时实现,不是 Node.js 的分支;底层用 JavaScriptCore,而非 V8。
  • 兼容性在持续逼近 100%,但 🟡 部分实现的模块(如 worker_threadschild_process 细节)仍需实测。
  • Bun 里同时有 Web 标准 API、Node.js 兼容 API、Bun 原生 API 三类,可混用。
  • 适合:TS/JSX 免编译、脚本工具、HTTP/全栈、测试、一体化工具链;谨慎:深度依赖 Node.js 私有接口或合规要求严格的核心生产系统。
  • 迁移走渐进、可逆路线,先并行验证,再决定是否切换默认运行时。