在去年为一个支付客户推出金融科技仪表板前三周,我们的资深开发 Priya 走进了我们 Shoreditch 的办公室,说"我想把 API 层换成 Bun"。我几乎凭直觉说了不。然后我没有。这个决定让我对两种运行时的理解,比 Hacker News 上任何基准讨论都要深得多。
自 2015 年以来我一直在 Node 上构建。在 Seahawk Media,我们已经在 WordPress、Next.js、Remix、纯 Express 以及许多其他奇怪的东西上部署了超过 12,000 个网站和应用。Bun 从 2023 年中期开始认真进入我们的技术栈。到现在我已经有了真正的看法。不是热点话题。是真正的看法。
以下是我实际学到的东西。
---
基准测试的争论基本上是噪音
每半年都会有人发布一个新的对比,显示 Bun 在某个综合的 HTTP hello-world 测试中处理 80,000 个请求/秒,而 Node 只有 40,000。说实话?这个数字是真实的。Bun 自己的基准测试显示确实令人印象深刻的吞吐量,特别是在 I/O 密集型工作负载上。
但事情是这样的。没人在生产环境中运行 hello-world。
一旦你添加了真实的 ORM、Redis 客户端、三层中间件、JWT 验证和文件上传处理程序,差距就会明显缩小。我对金融科技项目运行了相同的 Express 兼容应用(一个在 Node 22 上,一个在 Bun 1.1 上)连接 Postgres 实例,看到 Bun 在 p50 延迟上赢了约 18%。意义重大,但不是奇迹般的。
速度真正起作用的地方
我注意到 Bun 性能优势最多的地方不是 HTTP 吞吐量。是启动时间和脚本执行。运行一个 Node 需要 1.4 秒才能启动的一次性数据迁移脚本?Bun 在 180 毫秒内完成。对于 CLI 工具、本地开发脚本和定时任务,这个差异在整个团队中复合成真正的生活质量改进。
---
Node 生态系统仍然是不公平的优势
我想直言不讳,因为我看到太多人对此草率了事。Node 的 npm 生态系统已有 15 年历史。Bun 与大多数兼容,是的,但"大多数"在这句话中承载了很大的分量。
回到 2024 年初,一个客户项目需要 sharp 来进行服务器端图像处理。足够简单。除了我们需要的特定版本有一个原生绑定,Bun 的 FFI 层当时没有干净地处理。我们在这上面花了一天时间,最后我只是把那个服务换回了 Node 20。没有戏剧性,没有意识形态,只是实用主义。
兼容性故事从那时起已经改进了很多。但如果你的技术栈严重依赖原生 Node 插件(比如 canvas、argon2、任何带有 .node 绑定的东西),在提交之前要彻底测试。不要假设。在开始迁移前查看 Bun 兼容性跟踪器。
包管理是另一回事
Bun 的包管理器确实比 npm 快,现在我甚至在 Node 项目上也使用它。在拥有 400 个依赖项的项目上,我的 M2 MacBook Pro 上 bun install 大约需要 8 秒。同一台机器上 npm 需要 47 秒。这不是基准测试。这是我上周二用 time bun install 对比 time npm install 实际计时的。
我现在在可能 60% 的项目中使用 Bun 作为包管理器,Node 作为运行时。两全其美。
---
TypeScript:Bun 明显胜出
我直言不讳。在 Node 上运行 TypeScript 仍然需要构建步骤、ts-node、tsx 或某种配置组合,这让我想躺平。Bun 原生运行 .ts 文件,无需配置。完全无需。
对于 Seahawk 的内部工具,这改变了游戏规则。我写一个 TypeScript 脚本,用 bun script.ts 运行它,完成。没有 tsconfig.json 的复杂操作,没有 esm 与 cjs 的纠纷。对于一个在多个客户项目间高速交付的团队,摩擦力的减少是真实存在的。
需要注意的是:Bun 使用自己的 TypeScript 转译器,而非官方 TypeScript 编译器。所以类型错误不会停止执行。它会去掉类型并运行。如果你依赖 TypeScript 编译器在运行时提供正确性保证(你不应该这样做,但有人会),这是个需要理解的差距。
---
我现在在生产中实际运行的东西
让我具体说,因为模糊的泛泛而谈帮不了任何人。
在 Node 22 上:
- 所有使用 WPGraphQL + Apollo Server 的 WordPress 无头后端
- 任何有原生二进制依赖的服务
- 配有经过验证的中间件栈的长期运行 Express API
- 任何涉及重型 CommonJS 模块的遗留代码库
在 Bun 1.1+ 上:
- 内部 CLI 工具和开发脚本
- 新的基于 Hono 的 API 服务(Hono on Bun 真的很棒)
- 定时 cron 任务和一次性迁移脚本
- Webhook 接收器和轻量级边缘邻近服务
这个模式很简单。绿地项目和内部工具:用 Bun。具有复杂依赖树的面向客户的生产服务:用 Node,除非有特殊理由切换。
---
SQLite 事件(以及它教了我什么)
我在开头提到过。值得解释。
Bun 内置了 SQLite 驱动程序。快速、零依赖、真正有用。在 2023 年底的一个内容管理工具的暂存环境中,我们用它存储会话数据。在负载测试期间进行了一系列特别激进的并发写入后,数据库文件陷入了一个奇怪的状态。没有损坏到无法恢复的程度,但以需要在我的时间凌晨 2 点进行手动干预的方式被锁定。
这是 Bun 的具体错误吗?老实说,我不确定。可能是我们的写入模式。但在相同的工作负载下,我之后测试的 Node + better-sqlite3 设置没有重现这个问题。
教训不是"Bun SQLite 坏了"。而是 Bun 的内置 API,尽管方便,但社区覆盖面较小。当凌晨 2 点出现问题时,你希望有 Stack Overflow 帖子和 GitHub issue。Node 有十七年的这些。Bun 有三年。
---
部署和工具兼容性
这部分比人们承认的更重要。
Vercel、Railway、Render 和 Fly.io 现在都支持 Bun 部署。Railway 尤其简化了这个流程,大致上和 Node 一样容易。AWS Lambda 则比较复杂。你需要打包自定义运行时或使用层,这增加了复杂性。
Docker 没问题。oven/bun 是官方基础镜像,效果很好。我在几个服务上都在用。如果你在乎的话,这个镜像比 Node 的等效镜像更轻量。
不够成熟的是可观测性层。像 Datadog 的 Node.js APM 代理、某些 OpenTelemetry 自动检测包,还有一些 Sentry SDK 功能在 Bun 上表现不同或根本不工作。去年春天我花了大约四个小时来搞清楚为什么分布式追踪在 Bun 服务上丢失了跨度。结果是异步上下文传播的差异。Node 的 AsyncLocalStorage 行为和 Bun 的实现在细微的地方有偏差,这会在追踪时咬你一口。
如果你运行严肃的生产可观测性,在 Bun 上线前测试你的整个遥测栈。不是上线后再测。
---
我对"我应该切换吗?"这个问题的诚实看法
这是我在客户或团队成员提问时使用的快速框架:
- 这是一个新项目且没有遗留依赖?认真评估 Bun。
- 你主要在写内部工具或脚本?现在就用 Bun。
- 你需要原生插件或非常特定的 npm 包?坚持用 Node,先测试。
- 启动时间或脚本执行速度是个痛点?Bun 会明显帮助。
- 你在 AWS Lambda 或没有一流 Bun 支持的平台上?Node 摩擦力更小。
- 你的团队已经熟悉 Node 生态的怪癖了?把 Bun 的学习曲线也考虑进去。
还有一些值得关注的事情:
- Bun 的 Windows 支持大幅改进但在边界情况上仍然落后 macOS 和 Linux
bun:test内置运行器实际上很不错,但你依赖的 Jest 插件可能不兼容- 用
--hot进行热模块重载令人印象深刻,但在复杂的模块图上偶尔不可预测
---
FAQ
Bun 在 2026 年生产就绪吗?
对于特定用例,绝对是的。对于一个依赖最少的全新 API 服务,Bun 生产就绪已经有一段时间了。对于有多年 Node 专有依赖的复杂企业应用,我会说"生产就绪但有附加条件"。这些附加条件不是破坏交易的,但它们需要尽职调查。
我应该把现有 Node 项目迁移到 Bun 吗?
几乎肯定不应该,除非你有 Bun 能解决的那个项目的特定问题。迁移有风险。如果你的 Node 应用在运行,迁移的生产力成本相比只在新项目上用 Bun 很少能付出。我没有迁移过任何现有客户项目。我在 Bun 上启动了新的。
Bun 对所有工作负载都比 Node 快吗?
不。CPU 密集型工作负载的差异最小,因为两者最终都运行 V8(Node)或 JavaScriptCore(Bun)。收益主要出现在 I/O 密集型工作负载、启动时间,以及任何 Bun 的原生实现(HTTP 服务器、文件 I/O、SQLite)替换 JavaScript 层等效品的地方。对于计算密集型服务,你不会注意到什么差别。
哪个框架最适配 Bun?
Hono 是我首选的。它轻量、TypeScript 优先,并且是为像 Bun 这样的运行时设计的。ElysiaJS 是另一个流行选择,是 Bun 原生的,基准数字令人印象深刻。两个我都用过。在生产中我更信任 Hono,因为社区更大,边界情况文档更齐全。
Bun 最终会替代 Node 吗?
可能不会替代。会共存。Node 在企业环境中有太多制度惯性,npm 生态会让两者长期保持相关性。Bun 已经做到的是推动 Node 改进。Node 22 比 Node 18 明显更快,部分原因是竞争存在。这对所有写服务端 JavaScript 的人都是好事。
---
你选择的运行时不如你在其上写的代码重要。但为错误的项目选择错误的运行时确实会浪费你的时间,而时间是我唯一买不到更多的东西。在合理的地方使用 Bun。在值得信任的地方依赖 Node。看在老天爷的份上,在两者上都用 bun install。
