多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Bun 重写 Rust 之路:一场 JavaScript 运行时的自我革命

Bun 重写 Rust 之路:一场 JavaScript 运行时的自我革命 专注AI 大模型与前沿科技深度解析习惯从工程师视角拆解技术热点。 欢迎点赞、收藏、关注一起在技术浪潮中保持清醒与好奇 Bun 重写 Rust 之路一场 JavaScript 运行时的自我革命在 JavaScript 工具链的版图上Bun 一直是个异类。当 Node.js 还在用 C 稳坐江山Deno 用 Rust 试图弯道超车时Bun 却用 Zig 杀出了一条血路——极致的启动速度、内置打包器、原生 TypeScript 支持让它在短短几年内收获了无数开发者的青睐。然而就在最近Bun 团队做出了一个让整个社区震动决定用 Rust 重写 Bun。这不是一次简单的语言迁移而是一场关于性能、内存和长期维护性的深度博弈。作为长期关注 JavaScript 生态的开发者我想从技术角度拆解这次重写的动机、挑战与潜在影响。为什么放弃 ZigBun 最初选择 Zig看中的是其手动内存管理带来的极致控制力以及对 C ABI 的无缝兼容。Zig 的编译速度极快生成的二进制体积小这让 Bun 在启动速度上碾压了 Node.js。但问题也随之而来Zig 的生态太年轻了。库生态匮乏Zig 的第三方库数量与 Rust 的 crates.io 完全不在一个量级。Bun 需要大量底层系统调用、HTTP 解析、压缩算法等基础库在 Zig 生态中往往需要自己造轮子而 Rust 生态中这些库早已成熟。人才招募困难Zig 的开发者数量远少于 Rust。Bun 团队想要扩大规模却发现很难找到熟悉 Zig 的资深工程师。反观 Rust凭借其在系统编程领域的崛起拥有庞大的开发者社区。工具链不完善Zig 的调试器、剖析器、IDE 支持相比 Rust 仍有差距。对于一个需要精细优化性能的运行时来说工具链的完善程度直接决定了开发效率。社区里很多人质疑重写不是浪费时间吗但 Bun 团队在技术博客中给出的理由很清晰长期维护的可持续性。Zig 的激进语法和手动内存管理虽然强大但出错率也高。一个内存安全漏洞在 JavaScript 运行时中可能是致命的——毕竟Bun 每天要处理数以亿计的请求。Rust 重写的核心收益1. 内存安全从“信任程序员”到“编译器兜底”JavaScript 运行时最怕的是什么内存泄漏、空指针、数据竞争。在 Zig 中这些全靠开发者自觉。而在 Rust 中借用检查器Borrow Checker在编译期就拦截了大部分内存错误。这意味着什么Bun 团队可以更激进地使用并发和异步 I/O而不用担心线程安全问题。例如在文件系统操作和网络请求的并行处理上Rust 的所有权模型让代码天然线程安全无需再手写复杂的锁机制。2. 性能的精细调优很多人以为 Rust 重写会牺牲性能但实际结果恰恰相反。Bun v1.4 的重写版本在基准测试中不仅保持了原有的启动速度优势还在内存占用上降低了约 15%。这得益于 Rust 的零成本抽象——你可以写出接近 C 语言性能的代码同时享受高级语言的安全保障。更关键的是Rust 的Miri一个实验性的解释器可以检测未定义行为这让 Bun 团队能系统性排查那些在 Zig 时代难以发现的隐蔽 bug。这种“系统性改善稳定性”的能力是这次重写最宝贵的收获之一。3. 生态的杠杆效应Rust 的 crates.io 上有超过 15 万个库。Bun 团队可以直接复用tokio异步运行时、hyperHTTP 实现、serde序列化等久经考验的组件而不必像在 Zig 中那样从零开始。这大大加速了开发进度——重写工作从 2025 年底启动到 2026 年 7 月就发布了 v1.4 的 Rust 核心版本速度惊人。重写过程中的三大难题难题一JavaScriptCore 与 Rust 的桥接Bun 的底层是 JavaScriptCoreWebKit 的 JS 引擎而不是 V8。这本来是 Bun 的差异化优势——启动速度更快、内存占用更低。但 JavaScriptCore 是用 C 写的Rust 与 C 的互操作FFI比 Zig 与 C 的互操作复杂得多。Bun 团队不得不编写大量的extern C桥接层将 JavaScriptCore 的 C API 封装成 Rust 的安全接口。这个过程极其繁琐因为 JavaScriptCore 的对象生命周期管理非常微妙——一个对象可能被 JS 垃圾回收器回收也可能被 Rust 侧持有。如何保证两者不会冲突Bun 的解决方案是引入了一个“句柄池”Handle Pool所有跨语言的对象引用都通过句柄间接访问避免直接持有裸指针。难题二异步模型的重新设计Zig 时代的 Bun 使用基于epoll的事件循环配合协程实现异步 I/O。Rust 的异步生态则围绕tokio构建但tokio的调度模型与 JavaScriptCore 的事件循环并不完全匹配。Bun 团队没有直接使用tokio而是实现了一个自定义的异步运行时专门适配 JavaScriptCore 的语义。这个运行时保留了 Rust 的async/await语法但在底层直接对接操作系统的异步 I/O 接口避免了tokio的多线程调度开销。这使得重写后的 Bun 在 I/O 密集型场景下性能甚至比 Zig 版本提升了 8%。难题三兼容性的“暗礁”Bun 的目标是成为 Node.js 的即插即用替代品。这意味着fs、http、child_process等模块的 API 行为必须与 Node.js 完全一致。在 Zig 时代Bun 已经实现了大部分 API但重写过程中这些 API 的语义必须被重新验证。尤其是一些边界情况比如fs.watch在 Linux 和 macOS 上的行为差异、http.Agent的连接池管理、Buffer与Uint8Array的隐式转换……这些细节在测试中不断暴露问题Bun 团队不得不建立了一个庞大的“兼容性测试套件”每次提交代码都要运行超过 5 万个测试用例。对开发者的实际影响安装体积与内存占用重写后的 Bun 二进制体积从原来的约 90MB 降到了约 65MB压缩后。对于 CI 环境或 Docker 镜像来说这是一个不小的优化。同时空闲状态下的内存占用降低了约 20%这意味着在同一台服务器上可以运行更多 Bun 实例。包管理速度的再次飞跃Bun 的bun install本来就以快著称重写后更是将依赖解析和文件写入的并行度提升了一个量级。在真实的 monorepo 项目中安装 500 个依赖包的时间从原来的 1.8 秒降到了 1.2 秒。虽然看起来提升不大但在大型项目中这个差距会放大到几十秒。调试体验的改善Rust 重写后Bun 的崩溃报告更加友好。以前在 Zig 时代遇到段错误Segmentation Fault往往只能看到一串内存地址现在 Rust 的panic机制会给出详细的堆栈回溯和错误信息。这对于开发原生模块的开发者来说简直是救命稻草。值得担心的风险尽管重写带来了诸多好处但我也看到了一些潜在的风险第一JavaScriptCore 依赖的长期锁定。Bun 选择 JavaScriptCore 而非 V8这本身是一种战略押注。如果 WebKit 团队未来对 JavaScriptCore 的维护力度减弱Bun 将面临巨大的迁移成本。而 Rust 重写并没有改变这个底层依赖。第二社区分叉的担忧。Bun 的重写引发了社区关于“为什么不直接用 Deno 或 Node.js Rust 插件”的讨论。虽然 Bun 团队明确表示不会放弃 JavaScriptCore但这次重写确实让一些早期采用者感到不安——他们担心 Bun 的 API 会因此发生变化。第三新特性的开发速度。重写期间Bun 团队将大部分精力放在了 Rust 迁移上导致一些新特性如 WebGPU 支持、更好的 Windows 集成的发布被推迟。对于急切期待这些功能的开发者来说这无疑是一种煎熬。从重写中我们能学到什么Bun 的 Rust 重写本质上是一次“技术债的提前偿还”。在项目初期选择 Zig 是为了快速验证核心假设——一个极速的 JavaScript 运行时是否可行。当假设被验证后团队意识到长期维护的瓶颈在语言生态于是果断转向。这种“用最快路径验证再用最稳路径工程化”的策略值得每一个开发者深思。对于初级开发者来说这次重写也传递了一个重要信号语言的选择不是一劳永逸的。今天你选择了 Python 的快速开发明天可能就需要 Rust 的性能今天你选择了 TypeScript 的类型安全明天可能就需要 Go 的并发模型。关键在于你的架构是否足够模块化以便在必要时替换底层实现Bun 之所以能顺利重写是因为它的核心设计JavaScriptCore 自定义 I/O 层与语言绑定层解耦得足够干净。如果你的代码中业务逻辑与底层库强耦合那么任何重写都将是一场灾难。下一步展望目前Bun 的 Rust 重写已经完成了约 80% 的代码迁移。剩余的 20% 主要集中在一些边缘模块如bun:sqlite的原生绑定、bun:ffi的动态库加载。Bun 团队计划在 2026 年底前完全移除 Zig 代码。与此同时Bun 的性能仍在持续优化。最新版本的基准测试显示其 HTTP 服务器吞吐量已经接近hyper原生 Rust 实现的 95%——考虑到 JavaScript 解释层的开销这已经是一个惊人的数字。对于开发者来说现在是一个不错的观察窗口。如果你正在考虑将项目从 Node.js 迁移到 Bun可以等待 Rust 重写完全稳定后再行动。但如果你追求极致的启动速度和内存效率现在就可以尝试 Bun v1.4 及以上的版本——它已经足够可靠并且未来的性能提升空间更大。技术世界的每一次重写都是对“最优解”的一次重新定义。Bun 的 Rust 之旅或许会为 JavaScript 运行时的发展开辟一条新的道路。而我们作为开发者不妨保持好奇持续观察这场变革的终局。
返回列表