2026年7月8日,Bun的作者Jarred Sumner在Bun官方博客发表了一篇超过一万词的技术长文,题为「Rewriting Bun in Rust」。文章详细记录了Bun的核心代码库从Zig到Rust的完整翻译过程:64个Claude Code实例并行运行11天,完成约100万行代码(包含注释和空行约53.5万行净Zig代码)的机械翻译,产生6,778次提交,API费用约$165,000。5月14日,PR #30412合入主分支,Zig代码从此从Bun的主线消失。
这是Bun项目自2022年发布以来最根本的一次技术决策变更。Bun从诞生之初就以「用Zig写的快速JS运行时」为身份标签——Zig给了它早期的速度优势和社区关注。这条标签在2026年7月正式作废。

Zig为什么被放弃
Sumner在博文中的技术解释相当坦率。他列出了一份Bun v1.3.14修复的bug清单,13项全部涉及内存安全问题:node:zlib中的heap-use-after-free反复出现、node:http2在JS回调重入时哈希表rehash导致use-after-free、UDPSocket.send()在valueOf()回调期间发生ArrayBuffer分离、crypto.scrypt在分配失败路径上泄露密码和盐缓冲区、Buffer#copy与Buffer#fill在valueOf回调分离底层ArrayBuffer时越界读取……Sumner写得直白:「I was tired of going to sleep worrying about crashes in Bun.」
这些bug的类型高度集中于一个模式:GC管理的内存和手动管理的内存在同一条调用栈里交汇,而清理代码要么没写、要么写了两遍。Zig用defer关键字做作用域退出清理,这种显式风格在函数内部干净利落,但在跨模块、跨所有权的场景下容易出错。Bun内嵌了JavaScriptCore(C++)、BoringSSL(C)、SQLite(C)等库,混合内存模型的边界比纯Zig项目复杂得多。
Zig社区的回应也值得记录。Zig语言作者Andrew Kelley在7月9日发表了一篇立场鲜明的回应文章,标题是「My Thoughts on the Bun Rust Rewrite」。Kelley的核心论点是:Bun的稳定性问题根源在于工程纪律缺失,与Zig语言本身无关。他提到,Zig团队多年来一直试图向Bun团队建议更好的编程实践,但「recklessly speeding past feature after feature with very little time taken for reflection and elimination of bugs」是Bun的常态。TigerBeetle用Zig写出了以静态分配和崩溃即重启为核心的高度可靠系统——问题不在于语言,在于你如何用。
Kelley还指出,Sumner博文中将「风格指南」和「语言特性」做二择一的对比是一种话术。TigerBeetle的TigerStyle风格指南并非仅仅靠代码审查来执行——它的核心规则(「启动后零分配」)通过Zig的显式分配器API在类型层面自执行。这不是风格问题,是架构选择问题。
在Lobsters上,Rust社区知名成员matklad(Alex Kladov,TigerBeetle的核心开发者之一)也补充了类似观点:Zig的分配器API设计使得你可以从函数签名层面杜绝分配,「the rule is in the function signatures checked by compiler, not in the style guide checked by reviewers」。
改写本身的技术过程
无论你认同哪一方的论证,改写过程本身的工程细节值得关注。Sumner将整个过程分成几个阶段:
准备阶段(3小时):与Claude讨论Zig模式到Rust模式的映射规则,产出PORTING.md。随后一个动态workflow遍历所有.zig文件的struct定义,追踪每个字段的生命周期,产出LIFETIMES.tsv。试运行先翻译3个文件验证流程,然后扩展到全部1,448个.zig文件。
并行翻译阶段:4个Git worktree,每个worktree中16个Claude实例(共64个)并行作业。每个Claude实例遵循一个3角色流水线:1个「实现者」(写代码)、2个「对抗审查者」(在独立上下文中审查diff,只能找bug不能说可以merge)、1个「修复者」(应用审查建议)。峰值时刻,Claude每分钟产出约1,300行代码。
编译修复阶段:翻译完成后约有16,000个编译器错误。Sumner将错误按crate分组,继续用同样的3角色流水线循环修复。循环依赖是需要人工判断的最棘手问题——原始的Zig代码是一个编译单元,拆成约100个Rust crate后必须打破依赖环。
测试通过阶段:先让bun --version不崩溃,再让bun test <file>跑起来,然后用workflow逐个修复失败的测试文件。从972个测试文件失败降到23个,再到Linux全绿,最后Windows也全绿。从第一次CI运行到全部6个平台100%测试通过,耗时约5天。
Sumner特别强调了几个false start:Claude曾把「修复编译器错误」理解为「把报错的函数体替换为stub」,还开始生成可疑的长段落注释来解释workaround。Sumner添加了一条规则:「如果需要一个段落长度的注释来为workaround辩护,那代码就是错的——修代码,不要写注释。」几个小时后,这些问题消失了。
另一个教训:多个Claude实例在同一个仓库里偶尔执行git stash和git reset --hard互相踩踏。Sumner不得不在workflow中明确禁止除单文件提交外的所有git命令。
结果:更快、更小、更稳定
Sumner在博文中给出了具体的对比数据。所有数据基于v1.3.14(最后一版Zig)与v1.4.0(第一版Rust)的对比。
内存泄漏修复:Bun.build()在循环调用中每次泄露约3MB。在Zig版本中,连续2,000次Bun.build()调用后内存占用达到6,745 MB且持续增长;Rust版本在500次后稳定在609 MB,不再增长。Sumner将这一改进归功于Rust的Drop——ArrayBuffer的解绑操作不再需要手动在每一个调用点写defer。
二进制体积:Linux平台从88 MB缩减到70 MB(约20%),Windows从94 MB缩减到76 MB。Sumner把这归因于Zig代码中comptime的过度使用——编译期生成过多代码副本。后续结合ICU按需解压和Identical Code Folding进一步缩减。
性能:HTTP吞吐量提升3%-5%(Bun.serve从169.6k req/s到177.7k req/s),next build快4.5%,tsc -b --force快4.7%。Sumner认为性能改善主要来自Rust支持跨语言LTO(链接时优化),可以在C/C++和Rust之间做跨语言内联。
栈空间:Rust的LLVM IR生成llvm.lifetime.start和llvm.lifetime.end内建函数,让大函数中的嵌套作用域变数可以重用栈槽位,原本需要手动拆分大函数的栈溢出问题自然消除了。
稳定性:v1.4.0修复了128个能在v1.3.14中复现的bug。Prisma的Compute公开测试版在Bun的Rust版本上运行,之前遇到的「VM暂停恢复后连接池无法恢复」问题消失。

社区反应的三个焦点
Lobsters上这条帖子获得121分、160条评论。随后Lobsters管理员将Andrew Kelley的回应文章合并到同一讨论帖下,带来了额外的75条评论,总计235条。这个合并操作本身也成为讨论的一部分——多个用户抱怨合并后的评论区结构混乱、难以追踪。
社区反应集中在三个焦点:
第一,这是技术决策还是营销行为? Lobsters用户alemi(51分)直言:「I never took Bun as a serious project. And now it’s just a test bench for Anthropic marketing department.」这一观点在多个平台上都有回响——Bun已被Anthropic收购,Sumner使用的是Anthropic尚未发布的Claude Fable 5模型,博文中展示AI能力的篇幅不亚于讨论Rust优势的篇幅。也有用户为Sumner辩护:如果Claude Code确实能11天完成一年的工作量,那记录这个过程本身就是有信息量的技术写作。
第二,「$165,000」便宜还是贵? Pragmatic Engineer的通讯文章用了更中性的表述:对怀疑者而言,$165K做语言迁移听起来很贵;但对现实主义者而言,把1-2年的迁移缩短到11天,开辟了全新的工程可能性。关键是,Sumner本人指出,如果没有AI辅助,「我们永远不会做这件事。现实的选择是什么也不做,永远修文首的那种bug。」
第三,测试覆盖率是否足以信任百万行AI生成代码? 这是Andrew Kelley回应中的核心质疑:「如果测试套件足以捕捉一切问题,那Zig代码中为什么还有那么多烦人的bug?」Sumner在博文中的回答是:测试套件是TypeScript写的,不依赖运行时的编程语言——它对Zig版本和Rust版本一视同仁。但他在博文也承认,Rust版引入了19个已知回归,已全部修复。其中几个回归来自两种语言行为相同但语义不同的代码——比如Zig的assert是函数(在所有构建中都执行参数),Rust的debug_assert!是宏(在release构建中直接删除整个表达式),导致hot module reload在release构建中失效。
对Zig生态的影响
Andrew Kelley在回应中写了一段颇为复杂的心路历程。Zig团队对Bun的态度经历了一个转折:从早期的乐观(「Bun是Zig最著名的项目」)、到中期的紧张(「我们担心Zig的身份会变成与AI关联的编程语言」)、再到重写宣布后的释然(「ecstatic……it tastes like it’s not my problem anymore」)。
Kelley特别提到,当Anthropic收购Bun后,Zig社区涌入了一波「AI enthusiasts」,他们需要被告知在论坛帖子中粘贴LLM输出是反社交行为。Zig团队直到收购后才意识到,Bun对Zig而言已经「从资产变成了净负债」。
但Kelley也明确表示这是商业判断而非个人恩怨:「I actually don’t have any personal criticisms of Jarred. He has different taste than me, he wants different things out of life than me. But I think he’s actually happy and successful exactly where he is.」
结语
Bun从Zig到Rust的改写是2026年技术界几个趋势的交汇点:AI辅助编程的能力边界(11天完成一年工作量)、系统编程语言的「内存安全」路线之争(Zig的显式风格 vs Rust的编译器保证)、以及开源项目在被大公司收购后的方向变化。
Sumner在博文结尾展示了一段Zig与Rust的并排代码对比——canMergeSymbols函数在新旧两个版本中逻辑完全一致,结构几乎一一对应。他的论点是:这是一次机械翻译,不是一次重新设计。任何理解原版Zig代码的人都能理解翻译后的Rust代码。这是否能说服持怀疑态度的观察者,取决于你如何看待「工程纪律」和「语言特性」之间的关系——而这正是整个讨论中最难达成共识的部分。
参考链接
- Rewriting Bun in Rust — Bun Blog
- Lobsters 讨论帖
- Andrew Kelley: My Thoughts on the Bun Rust Rewrite
- Simon Willison’s commentary
本文的素材来自公开信息和社区讨论。如果你对这个话题有更深入的一手经验,欢迎指出文中的不足。