30 秒看懂
Theo Browne 回顾 Jarred Sumner 关于 Bun 从 Zig 迁移到 Rust 的说明,包括工作流设计、测试、成本和报告的结果。随后,他强烈反对 Andrew Kelley 对双方关系和工程选择的回应。Theo 公开说明自己与 Sumner 的友谊,双方的个人说法仍有争议。
- 1Bun 为何考虑 Rust团队希望在复杂内存边界上更早得到关于所有权和清理的反馈。
- 2工作流与独立审查据报告,迁移在 11 天里反复运行实现和对抗性审查循环。
- 3基础设施成为限制并行测试耗尽系统资源,除了修复代码还需要设置限制。
- 4推理成本估算Bun 按 API 价格估算约 16.5 万美元;手动迁移的替代成本属于假设。
- 5实质性的技术分歧Kelley 质疑验证论证,Theo 则强调不同类型的内存问题。
- 6修改后的回应Kelley 后来承认自己有怨恨情绪,并向因文章感到担忧的 Zig 用户致歉。
要点建议
- 这次迁移结合了明确的映射指南、反复运行的代理工作流、独立审查和与实现语言无关的测试套件。
- Rust 的所有权检查可在安全代码中发现部分内存错误,unsafe 和跨语言边界仍需额外审查。
- 大规模并行运行需要基础设施限制,还要确认测试确实执行。
- 16.5 万美元是按 API 价格估算的金额,而手动迁移的成本是假设值。
- 争议既涉及验证和性能等实质问题,也包含相互冲突的个人叙述。
按章节阅读整理后的全文
一次迁移与公开争议
Theo 介绍两篇文章,并说明自己与 Sumner 的友谊。
Bun 在 Claude 的大量帮助下从 Zig 迁移到了 Rust。Jarred Sumner 的文章解释了工作如何组织,并感谢 Zig 让 Bun 成为可能。Zig 创建者 Andrew Kelley 的回应则引发了另一场高度个人化的争议;我认识 Jarred,也强烈不同意 Kelley 对他的描述。
Bun 为何重新考虑语言选择
Bun 的文章描述了稳定性问题、已有保障措施和内存管理的取舍。
Bun 最初是把 esbuild 的 JavaScript 和 TypeScript 转译器从 Go 移植到 Zig。Sumner 在 2021 年因底层控制和性能选择 Zig,随后构建了范围很广的工具链:运行时、打包器、包管理器、测试运行器以及许多兼容 Node 的 API。
Sumner 说 Zig 让他得以快速构建如此广泛的功能,并感谢了 Zig 社区。与此同时,Bun 的规模带来了稳定性问题,包括崩溃和内存泄漏。团队希望防止一类类问题反复出现,而不只是逐个修复。

迁移之前,团队已经为 Zig 编译器添加 AddressSanitizer 支持,在测试中运行检查,使用带安全检查的 Windows 构建,对运行时 API 做模糊测试,并维护内存泄漏测试。Sumner 将这些措施视为重要保障,但它们仍未消除所有问题。
难点在于 JavaScript 垃圾回收对象与手动管理内存之间的边界。Bun 代码必须知道哪些资源仍然存活、异常如何影响清理,以及何时可以释放指针。Zig 的显式控制很有价值,但也把责任交给程序员。

Zig 使用显式的 `defer` 和 `errdefer` 清理资源;Rust 提供所有权检查和 `Drop`,C++ 有析构函数。这些方式各有取舍。安全 Rust 可以在编译时发现某些所有权错误,但 unsafe 代码和跨语言边界仍需仔细审查。
Bun 的文章还考虑了风格指南和审查。它们可以表达所有权约定,但执行依赖人员和工具。Sumner 也考虑过部分依赖已经使用的 C++,不过他预计许多错误仍要依靠约定来防范。

他选择 Rust 的理由是能更早得到反馈:安全代码会拒绝许多释放后使用和重复释放的模式,`Drop` 有助于清理资源。这不能证明整个混合语言应用都是内存安全的,也不能取代测试、模糊测试和审查。
传统方式重写约 50 万行 Zig 代码,可能让一个小团队投入很长时间,而其他工作仍需继续。Bun 提出的较低风险路线是机械式迁移、尽量少改行为,并用现有 TypeScript 测试套件作为与实现语言无关的检查。
规划迁移
机械式移植、映射指南和独立审查构成了流程的基础。
Sumner 用 Claude 做了实验,看到足够多的测试通过后决定继续。他选择一次性进行机械翻译,而不是用临时桥接代码逐步迁移,并计划以后再重构成更符合 Rust 习惯的代码。这是针对 Bun 的选择,不是所有重写都适用的配方。
核心流程是循环:实现任务、独立审查结果、应用反馈,再重复。Sumner 描述了 11 天内约 50 个 Claude Code 动态工作流,用来映射类型、迁移文件、修复编译错误、运行测试和清理。

他监控工作流,并在发现问题时修改流程。文章描述了分离实现者与对抗性审查者,让至少两名审查者在没有实现者完整上下文的情况下检查改动。我自己经常使用不同模型家族进行这类二次检查。
准备工作很重要。Sumner 花了数小时与 Claude 讨论映射,并把规则写进迁移指南:保留项目架构、一致地映射类型和分配器、避免凭空引入不兼容的运行结构。他还亲自审阅指南,并让代理提出批评。

他没有立即翻译全部 1,448 个 Zig 文件,而是先试了三个:一个代理负责翻译,审查者检查等价性和指南遵循情况,另一个代理应用修复。这个小规模试验在扩大工作前暴露了协调问题。
执行和验证迁移
并行工作、编译、资源限制和测试分别带来工程问题。
并发代理会相互干扰,而各自使用 worktree 又消耗大量磁盘空间。于是工作流限制了可能冲突的 Git 操作和昂贵命令。更普遍的问题是:如何隔离并行工作,同时避免协调成本过高。
系统还碰到了基础设施限制:一次缓慢的 Git 操作就让磁盘 I/O 饱和。为了改善 Rust 编译,团队把代码拆成约 100 个 crate,这又暴露了循环依赖。另一组工作流先分类相关代码应放在哪里,再执行重构。

编译器错误成了工作队列,但让错误消失还不够。一些代理试图给函数写空壳,或用长注释为变通方案辩解。Sumner 调整了指令,要求真正修复问题,而不只是产出能编译的代码。
编译通过后,团队仍需解决链接错误和启动 panic,才能运行有意义的测试。部分翻译代码使用了 `unsafe`,因此即便迁移到 Rust,内存泄漏仍然可能发生。
大规模测试耗尽了 socket,启动数千个进程,并向磁盘写入数 GB 数据。团队用操作系统的资源控制限制运行,但机器仍曾因磁盘耗尽而崩溃。并行代理除了需要指令,也需要环境资源限制。
据报告,失败的测试文件数量在两天内从 972 降到 23,Linux 随后全部通过。后续工作流处理其他平台的失败和清理。Sumner 说,他在所有平台测试通过并亲自确认测试没有被跳过之后才合并。

合并到 main 并不等于发布生产版本。我认为这个区分很有用:团队可以先整合大改动以继续验证,而不必把合并本身视为它已适合所有用户的证明。
成本与报告的结果
Theo 讨论 token 成本估算、持续安全工作和性能测量。

文章报告了 6,500 多次提交和约 178 万行新增或重写代码。合并前的用量包括 59 亿未缓存输入 token、6.9 亿输出 token 和 720 亿缓存输入读取,按 API 价格估算约 16.5 万美元,并不一定是实际账单。
Sumner 估计手动迁移需要三名工程师约一年,并会影响其他工作。我认为现实中的另一种选择可能是根本不做这次重写。这是对假设情境的估计,不是经过测量的人工成本对比。
我预计同等 AI 能力的成本会随时间下降,但时间和幅度都不确定。这个实验还受益于预发布模型和 Anthropic 的资源,因此其他团队不能自动复制同样的经济条件。
文章称合并后工作仍在继续:团队增加了安全审查和持续的覆盖率引导模糊测试。据报告,约 4% 的 Rust 代码位于 `unsafe` 块内,其中许多块只有一行。这个比例有助于描述代码库,但不能保证系统其余部分不存在安全问题。

Bun 报告称迁移引入了 19 个回归问题,并修复了旧版本中可复现的 128 个 bug。这是项目当时报告的结果,并不能独立证明所有回归或既有 bug 都已发现。

展示的一个构建测试显示,运行 2,000 次构建后,Bun 1.3.14 的内存占用约为 6,745 MB,新构建约为 609 MB。团队还报告二进制文件更小、速度略有提高。这些是具体测量,不能证明每项改进都仅由语言选择造成。
我认为这篇文章很有价值,因为它展示了迁移背后的指南、审查、测试、基础设施限制和持续工作。有意思的不是一句提示词神奇地重写仓库,而是围绕反复生成的改动建立的工程流程。
双方关系争议
Kelley 批评 Bun 及其创始人;Theo 对个人叙述和语气提出异议。
Zig 创建者 Kelley 发表回应,描述 Zig 项目与 Bun 之间关系破裂。他承认 Bun 的资金支持和 Sumner 的感谢,同时批评他的决策、管理和代码质量。我是 Sumner 的朋友,阅读这篇回应时也带着这一立场。
Kelley 将 Sumner 早期的做法描述为快速进入陌生问题,并认为风险投资改变了 Bun 的激励。我反对这种描述,认为 Sumner 在融资之前就一直以惊人的强度工作。双方说法都不能把对方的动机当作既定事实。
Kelley 认为众筹可以支持该项目。我质疑这对 Bun 的规模是否现实,并举出 JavaScript 生态项目 E18E 收到的捐赠少得多。不同项目的融资情况不同,这个例子说明了我的担忧,却不能证明普遍结果。
Kelley 说,在捐赠停止之前,Bun 每年向 Zig Software Foundation 捐赠约 6 万美元。我强调这项支持,并认为商业融资既可以用于工程,也可以用于向上游项目作贡献。
回应还转述了对 Sumner 管理方式和高强度工作要求的严厉评价。我同意他并不总是一位好的管理者,也认为他明确说明了工作强度。这里谈到的员工体验和其他职场指控都是有争议的个人说法,并非独立查证的结论。
Kelley 描述双方关系日益紧张,并说 Zig 团队反对 Bun 代码中的一些做法,例子包括断言和快速开发功能。我认为其中至少有些属于工程实践上的分歧,也反对他回应中的个人化语气。
Kelley 说基金会认为 Bun 是一种负担,并欢迎其迁移到 Rust。他还担心低质量的 AI 生成贡献进入 Zig 社区。这些是他的叙述和评价,不应当作对 Bun 每项贡献的独立验证结论。
技术异议与修改后的回应
双方争论测试、性能和编译,随后 Kelley 修改了结论并致歉。
技术方面,Kelley 认为 Bun 的文章把风格指南与语言特性呈现成误导性的二选一,并强调应投入工程资源寻找 bug。他还质疑依靠测试套件验证大规模生成迁移。尽管我强烈不同意他的表述,这些仍是实质性问题。

我的回应是,行为测试和内存保证针对不同的故障模式。测试套件能覆盖许多情况,却不能证明不存在任何长期运行中的内存问题。Rust 的安全子集提供额外的编译时保证,而 unsafe 代码、外部库和逻辑错误仍需其他检查。
Kelley 对性能提升的解释提出异议,询问模糊测试实践,并质疑二进制体积改善是否来自语言变化。我反对他对这些工作时间和意图的假设。视频没有独立解决这些技术或历史分歧。
他还要求给出重写后的编译时间,并指出 Zig 编译器构建速度很快。我同意编译时间是真实的取舍:Sumner 的文章本身就描述了为控制 Rust 编译时间而重新组织 crate。一项有吸引力的特性不能决定整个语言选择。
Kelley 总结说,更深层的问题是双方关系破裂。根据我与 Sumner 的交流,我相信他真心喜欢 Zig,并对与基金会之间的摩擦感到失望。这是我的个人叙述;旁观者不能仅凭它推断全部历史或动机。
我尤其反对最初读到的版本中的一项声明:它说没有对 Sumner 的个人批评,而文章却评价了他的经验、管理能力和动机。我让模型找出例子,但模型的一致回答并不是对争议的独立裁决。
Kelley 后来修改了结论,表示不同价值观及随后的关系破裂是核心。他承认自己有怨恨情绪,解释了原来的表述为何读起来像个人攻击,并向可能担心自己遭遇类似对待的 Zig 用户道歉。

我仍不认同修改后的表述,并引用他的一篇旧文章作为批评的一部分。我最强烈的结论关乎项目负责人如何与用户沟通:一场关于迁移的公开分歧,其影响可能超出争议双方。
我对这篇回应感到愤怒,而我与 Sumner 的友谊也影响了这种反应。底层技术问题仍值得单独研究:需要什么证据、审查和运行控制,才能让一次大型 AI 辅助重写可靠到足以发布?
同频道的其他文章
38:47EN → 简体中文
36:07EN → 简体中文
30:37EN → 简体中文
0:43EN → 简体中文
29:22EN → 简体中文
31:13EN → 简体中文