Bun 为什么比 Node.js 快?底层架构与性能优化全解析
Bun 是由 Jarred Sumner 创建的全能型 JavaScript 运行时,自 2022 年发布以来凭借惊人的启动速度和 HTTP 吞吐量迅速赢得开发者关注。官方基准测试显示,Bun 的启动时间仅 8-15ms,是 Node.js(60-120ms)的 5-12 倍;HTTP 请求处理达 11 万 QPS,远超 Node.js 的 4.5 万 QPS。2025 年底 Anthropic 收购 Bun 后,其冷启动优势成为 Claude Code 等 AI 工具的核心基础设施。这种高性能并非偶然,而是底层架构设计哲学的直接产物:选用 JavaScriptCore 替代 V8、用 Zig(后迁移 Rust)实现零开销抽象、将运行时/包管理/打包/测试四合一。本文将拆解 Bun 性能优势的每一个技术支柱。
JavaScriptCore:比 V8 更快的启动引擎
Bun 性能优势的第一根支柱是选择了 Apple 的 JavaScriptCore(JSC)而非 Google 的 V8 作为 JavaScript 引擎。这个选择直接决定了 Bun 的启动速度优势。
JavaScriptCore 是 Safari 的 JS 引擎,与 Chrome/Node.js 使用的 V8 有着根本不同的优化策略:
- 更快的启动编译:JSC 的解释器和 JIT 编译器启动开销远低于 V8。V8 需要先解释执行代码、收集类型反馈,再由 TurboFan 编译优化,这个过程在短生命周期脚本中成本高昂。JSC 则采用更轻量的分层编译策略,冷启动更快。
- 更低的内存基线:JSC 的初始内存占用比 V8 低约 30%。对于 Serverless 场景中频繁冷启动的函数,这意味着更少的资源浪费和更低的费用。
- Safari Web API 原生复用:Bun 直接复用了 JSC 中已实现的 Web 标准 API(如 fetch、WebSocket、ReadableStream),避免了从零实现的工程成本和性能损耗。
Bun 的作者 Jarred Sumner 明确表示,选用 JavaScriptCore 是 Bun 速度的两大关键因素之一。
Zig 语言:手动内存管理与编译期计算
Bun 最初完全用 Zig 编写,这是性能优势的第二根支柱。Zig 的选择并非追逐潮流,而是基于以下技术考量:
手动内存管理消除 GC 暂停
Zig 没有隐式垃圾回收,所有内存分配由开发者显式控制。Bun 团队为此编写了高度优化的自定义分配器:
- 热路径零分配:在 HTTP 请求处理、文件 I/O 等关键路径上,Bun 通过预分配内存池和对象复用避免了运行时动态分配,消除了 GC 暂停。
- 精确的内存生命周期:Zig 的
defer和errdefer语法让资源释放时机一目了然,内存泄漏风险远低于手动malloc/free。
Comptime 编译期代码生成
Zig 的 comptime 能力是性能利器——在编译期执行代码并生成高度特化的机器码:
zig// 编译期生成特化的解析函数 fn Parser(comptime T: type) type { return struct { pub fn parse(input: []const u8) ?T { // 编译期根据 T 生成专用解析逻辑 } }; }
Bun 的 JSX/TypeScript 转译器大量使用 comptime 特化,避免运行时分支判断,这是其转译速度远超 Babel/swc 的原因之一。
与 C 生态的无缝互操作
Zig 可以直接 @cImport C 头文件而无需 FFI 绑定层。Bun 利用这一点直接调用 JavaScriptCore 的 C API,调用开销接近零,而 Node.js 通过 N-API 调用 C++ 则需要经过多层封装。
四合一架构:消除进程间通信开销
Bun 将运行时、包管理器(bun install)、打包器(bun build)、测试运行器(bun test)整合在单一二进制文件中,这是性能优势的第三根支柱。
传统 Node.js 开发需要 Node.js + npm/yarn + webpack/esbuild + Jest 多个进程协同工作:
- 进程启动开销:每个工具独立启动,重复加载 V8 和基础库。
- IPC 通信成本:工具间通过管道或临时文件传递数据,序列化/反序列化开销显著。
- 重复解析:TypeScript 代码被不同工具反复解析多次。
Bun 的四合一架构让所有工具共享同一个 JavaScriptCore 实例和 AST:
bash# 一个二进制完成所有工作 curl -fsSL https://bun.sh/install | bash bun init # 初始化项目 bun install # 安装依赖(比 npm 快 30 倍) bun test # 运行测试(比 Jest 快 3 倍) bun build ./src/index.ts --outdir=dist # 打包
包管理器的性能差异尤为明显:Bun install 对中型项目的冷安装约 1 秒,而 npm 需要 20 秒。原因在于 Bun 仅执行约 16.5 万次系统调用,而 npm 执行近 100 万次,同时 Bun 使用硬链接避免重复下载。
内置数据库与 I/O 优化
Bun 1.2 引入了内置数据库支持,直接在运行时层面优化 I/O:
bun:sqlite 同步 API
Bun 内嵌了 SQLite 并提供同步 API。在 Node.js 中访问 SQLite 需要通过 better-sqlite3 的 C++ 绑定跨越 JS/C++ 边界,而 Bun 的 SQLite 操作直接在 Zig 层完成:
typescriptimport { Database } from "bun:sqlite"; const db = new Database(":memory:"); const stmt = db.prepare("SELECT * FROM users WHERE id = ?"); // 同步调用,无 Promise 开销 const user = stmt.get(42);
内置 PostgreSQL 与 S3 客户端
Bun 1.2+ 还内置了 Bun.SQL(PostgreSQL 客户端)和 S3 客户端,减少了外部依赖和网络中间层。
Zig 到 Rust 的迁移:2026 新篇章
2025 年 12 月 Anthropic 收购 Bun 后,团队启动了从 Zig 到 Rust 的大规模迁移。2026 年 5 月,68% 的代码库(96 万行)在 6 天内完成重写,达到 99.8% 测试兼容性。
迁移的技术动机:
-
Rust 的所有权模型消除手动内存管理导致的内存泄漏问题。重写后 Bun 运行时中的内存安全缺陷大幅减少。
-
AI 辅助开发更友好:Anthropic 的 AI 工具对 Rust 的理解和生成能力远强于 Zig,这是迁移的重要推动力。Zig 社区的反 AI 立场与 Anthropic 的技术路线冲突。
-
生态与社区:Rust 拥有更成熟的工具链(Cargo)和更丰富的库生态,有利于长期维护。
迁移后的性能表现:HTTP 吞吐量提升至 Node.js 的 4 倍,但社区也对 AI 快速重写引入的 13000+ 个 unsafe 块和部分测试修改提出了质量担忧。
实战:Bun 性能优化的最佳实践
适合 Bun 的场景
- Serverless / Edge Function:冷启动 8-15ms,是 Node.js 的 1/10,直接降低云函数延迟和费用。
- 高频 HTTP 服务:11 万 QPS 的吞吐量适合 API 网关和微服务。
- CI/CD 流水线:
bun install比 npm 快 30 倍,bun test比 Jest 快 3 倍,显著缩短构建时间。 - TypeScript 开发:零配置运行 TS,无需
ts-node或tsc预编译。
注意事项
- 生态兼容性:Bun 通过了 98% 的 Node.js 测试套件,但少数 N-API 原生模块可能存在兼容问题,迁移前需验证。
- 内存模型差异:Bun 的内存管理策略与 Node.js 不同,长时间运行的进程需关注内存增长趋势,可使用
Bun.gc()手动触发回收。 - Rust 迁移过渡期:当前处于 Zig→Rust 迁移期,部分功能可能存在两个实现并行的情况,建议关注官方发布日志。
快速上手
bash# 安装 curl -fsSL https://bun.sh/install | bash # 创建项目 bun init # 运行 TypeScript bun run src/index.ts # 启动 HTTP 服务 bun run server.ts # 支持 Bun.serve() # 性能基准测试 bun bench
Bun 证明了 JavaScript 运行时可以同时做到快速启动、高吞吐和低内存占用——关键在于从引擎选择、实现语言到架构设计的每一层都做出有利于性能的决策。随着 Rust 迁移的推进,Bun 正从实验性工具走向生产级基础设施。