作为一个 Rust 热爱者,我为什么越来越喜欢 Bun?
前两天,我做了一件很“冲动”的事:把机器上的 pnpm、yarn 一类工具都删了,只留下了 bun。
这不是情绪化决定,而是过去一段时间真实使用之后的结果。
但先把立场说清楚:我依然是个 Rust 热爱者。
我喜欢 Rust,不只是因为它快,而是因为它在工程上给人一种很强的信心:
边界清楚、抽象克制、类型系统有力量、性能和可维护性往往能一起成立。
也正因为我很喜欢 Rust,所以我最开始看 Bun 和 Zig,其实是带着一点挑剔甚至怀疑的。
结果越用 Bun,越觉得它值得认真写一篇。因为它让我产生的不是“换了个包管理器”的新鲜感,而是另一种熟悉的敬意:
一个工程团队,真的在试图从底层重新整理整个工具链。
最近随着 Claude Code 的 source map 暴露事件,很多人也注意到它的工程里大量使用了 Bun。对我来说,这件事最有启发的地方,不是“某个明星项目也在用 Bun”,而是另一个问题:
为什么越来越多对启动速度、交互体验、工程统一性极度敏感的项目,会认真选择 Bun?
这篇文章,我想聊三件事:
- Bun 到底是什么,为什么它会让人用了就回不去
- 从 Bun 身上,我们能学到哪些工程思维
- 如果你被 Bun 背后的 Zig 吸引了,应该怎么快速入门
Bun 到底不是“更快的 Node”,而是“重新做了一遍 JavaScript 工具链”
很多人第一次听说 Bun,会把它理解成:
一个更快的 Node.js 替代品。
这个理解不能说错,但不够准确。
Bun 真正厉害的地方在于,它不是只想替代 Node,而是想把过去前端和 Node 生态里四分五裂的工具链,重新收拢起来。
在传统 JavaScript / TypeScript 开发里,我们经常会这样组合:
- 运行时:Node.js
- 包管理:npm / pnpm / yarn
- 测试:Jest / Vitest
- 打包:Vite / esbuild / Rollup / Webpack
- 脚本执行:各种 shell + cross-env + tsx + nodemon
而 Bun 的思路是:
这些能力,为什么不能尽量在一个统一的二进制和一套统一语义里完成?
于是你就得到了一个非常激进、但也非常有吸引力的东西:
bun installbun runbun testbun buildbunx
看起来只是少记几个命令,但本质上发生的是:
原来散落在多个工具、多个作者、多个配置系统中的能力,被收编到了同一个 runtime 的世界观里。
这就是 Bun 最迷人的地方。它不是“一个快一点的工具”,而是“一个更统一的工程入口”。
为什么我用了 Bun 之后,开始嫌弃 pnpm / yarn / 一堆辅助工具
先说结论:
Bun 给人的最强体验,不是 benchmark 数字,而是“摩擦感显著下降”。
很多工程工具并不是不能用,而是用起来总有很多小摩擦:
- 安装依赖慢一点
- 冷启动慢一点
- 测试跑起来再等一下
- 多一个配置文件
- 多一个适配层
- 多一个脚本 hack
这些问题单独看都不致命,但叠加起来就会非常烦。
Bun 的价值就在于:它把这些小摩擦一口气砍掉了一大批。
1. 安装依赖更直接
以前一个项目装依赖,脑子里先想的是:
- 用 npm?
- 用 pnpm?
- 用 yarn?
- monorepo 怎么配?
- lockfile 怎么迁?
现在很多项目里,我直接就是:
bun install没有那种“工具选择焦虑”,也没有那么多“先决定生态阵营,再开始干活”的心理负担。
2. 运行 TypeScript / JSX 的路径更短
很多过去需要 ts-node、tsx、nodemon、babel 参与的场景,在 Bun 里都被直接吸收进 runtime 了。
这件事的意义不是“少装几个包”,而是:
你会开始重新审视,哪些工具原本就是历史补丁。
3. 测试、构建、脚本不再像是不同世界
Node 生态里最让人疲惫的地方之一,就是:
- 运行环境一套语义
- 测试环境一套语义
- 打包环境一套语义
- dev server 又是一套语义
每个工具都能跑,但边界一多,心智负担就上来了。
而 Bun 在很大程度上是想把这些场景重新统一起来。
这就是为什么很多人从“试试看”开始,最后变成“怎么现在越来越多项目都想先用 Bun 起步”。
最近 Claude Code 事件,为什么会让更多人重新关注 Bun?
最近不少开发者在讨论 Claude Code 的源码暴露事件。公开流传出来的内容显示,Claude Code 的工程中大量使用了 Bun。
这件事本身当然有很强的话题性,但我更关注它背后释放出来的信号:
当一个对 CLI 体验、冷启动速度、工程集成度极其敏感的 AI 编码工具选择 Bun,这本身就是一种很强的技术背书。
为什么?
因为 Claude Code 这类产品对下面这些指标都非常敏感:
- 启动够不够快
- CLI 交互是否丝滑
- 子命令、脚本和构建链是否统一
- 跨平台行为是否稳定
- 单文件发布和升级是否方便
这些需求,恰好就是 Bun 擅长的地方。
所以从这个角度看,Claude Code 使用 Bun 不是“偶然”,而是“产品形态和工程约束自然收敛后的结果”。
当然,这里也要保持一个理性态度:
一个知名项目使用某个技术,并不等于那个技术适合所有团队。
但它至少说明了一件事:
Bun 已经不是一个只能拿来玩 demo 的新玩具,而是在真正进入高要求工具链和产品工程的主战场。
Bun 最值得我们学习的,不只是“快”,而是三种工程思维
很多人聊 Bun,最爱聊 benchmark。
我反而觉得,Bun 真正值得学的,不只是性能,而是它背后的工程方法论。
1. 一体化思维:把高频场景收回核心系统
过去很多生态都有一个惯性:
先把核心做小,剩下的都交给插件、三方库和社区。
这条路线当然有它的价值,但也很容易走向另一个极端:
核心越来越薄,项目越来越依赖外部拼装。
Bun 反其道而行之。
它做的不是“更小的 runtime”,而是“更强的默认能力集合”。
从 Bun 身上最值得学的一点就是:
对于高频、稳定、强共性的场景,不一定非要永远外包给三方生态。
当某件事已经成为 80% 用户的日常刚需时,把它做回系统内建能力,往往能带来更低的复杂度和更好的体验。
这个思路对我们做后端框架、基础设施平台、甚至内部开发工具都很有启发。
2. 少一层,就是生产力
Bun 的很多优势,说到底都来自一句话:少一层。
- 少一层 CLI 包装
- 少一层 JS 胶水
- 少一层进程跳转
- 少一层配置转换
- 少一层构建补丁
工程里很多复杂度,并不是算法本身复杂,而是系统层数太多。
所以从 Bun 身上能学到的第二点是:
优化系统,不一定要从最难的算法下手;很多时候,先把中间层砍掉,收益就已经很大。
3. 性能不是一个点,而是一整套设计纪律
为什么 Bun 快?
不是因为某个模块“神优化”,而是因为它从架构一开始就考虑了:
- 启动成本
- 内存分配
- 构建系统
- 语言边界
- 运行时能力
- 工具链统一
这其实是一种非常值得学习的工程纪律:
性能不是后期打磨出来的,而是前期设计决定的。
很多团队一开始只关注“功能先做出来”,等到后面再想补性能,往往很痛苦。
Bun 给人的启发是:
真正优秀的工程,不是某个 benchmark 冲到第一,而是从第一天开始就在避免未来的性能债和复杂度债。
作为 Rust 热爱者,我怎么看 Bun 选择 Zig 这件事?
聊到这里,就绕不开 Zig 了。
Bun 的核心 runtime 主要是用 Zig 编写的,底层则基于 JavaScriptCore。对很多人来说,Bun 其实也是第一次让 Zig 真正进入自己的视野。
那么问题来了:
为什么 Bun 选 Zig,而不是 Rust / C++ / Go?
先说我的态度:这并不构成对 Rust 的否定。
如果今天让我做很多基础设施项目、后端服务、区块链组件、数据库中间层,Rust 依然大概率是我的第一选择。Rust 在内存安全、并发安全、抽象表达力和长期可维护性上,仍然有非常强的吸引力。
但 Bun 不是一个普通后端项目。它是一个:
- runtime
- bundler
- package manager
- test runner
- dev server
揉在一起的系统软件项目,而且它还要深度贴着 JavaScriptCore、C/C++ ABI、Node 兼容层这些边界去生长。
在这种约束下,Zig 的优势就会变得非常具体:
- 足够接近 C,和底层 ABI 打交道很直接
- 没有额外 runtime 和 GC 世界观
- 内存分配策略可以完全自己设计
- 语言复杂度明显低于 C++
- 在“我知道自己在做什么”的前提下,改动路径很短
而这几件事,恰好都很适合 Bun 这种项目。
作为 Rust 用户,我觉得这件事最值得尊重的地方不是“Zig 比 Rust 更强”,而是:
Bun 团队非常清楚自己在优化什么,也非常清楚自己愿意承担什么代价。
Rust 的强项是:尽量在编译期替你兜住很多错误。 Zig 的强项则更像是:我不给你太多魔法,但把控制权尽量完整地交给你。
所以如果用一句更公平的话来总结:
- Rust 更像一门高保障的系统语言
- Zig 更像一门高控制感的系统语言
Bun 之所以选 Zig,不是因为 Rust 不够优秀,而是因为 Zig 更贴合它当下的工程取舍。
这也是我写这篇文章时特别想强调的一点:
喜欢 Bun,不等于要背叛 Rust。
相反,正因为我喜欢 Rust,我才更能看懂 Bun 的价值:
一个真正优秀的系统项目,最重要的不是选了哪门“神语言”,而是有没有围绕自己的约束做出一致、诚实、长期主义的工程决策。
从 Bun 学 Zig:不要一上来就学语法,先学它的世界观
很多人一听说 Zig,第一反应是:
要不要找一本 Zig 教程,从语法开始学?
当然可以,但我更建议另一条路线:
先从 Bun 这类真实项目反向理解 Zig 的价值,再回去学语言本身。
为什么?
因为 Zig 不是那种“语法很炫”的语言。它真正吸引人的地方,是系统编程里的几种思维方式:
- 明确的内存所有权和生命周期
- 少魔法、少隐藏控制流
- 把分配器当成显式设计对象
- 贴着平台边界写代码
- 在性能和可维护性之间做直接权衡
如果你先理解了 Bun 为什么需要这些东西,再学 Zig,就会非常顺。
如何快速入门 Zig:一条最短路径
这里我给一个我认为更适合工程师的 Zig 入门路线。
不是“系统学完语法再写项目”,而是边用边学。
第一步:先建立正确认知
你需要先接受一个事实:
Zig 不是一门“帮你自动做很多事”的语言。
它更像是在不断提醒你:
- 这块内存是谁分配的?
- 谁来释放?
- 生命周期多久?
- 这里是不是在隐式拷贝?
- 这个错误要怎么显式传播?
如果你以前主要写 Java / Go / TypeScript,这会有一点不适应。
但这恰恰是 Zig 最有价值的地方。
第二步:只学最关键的 20%
刚开始不用追求全面掌握,先抓住最重要的内容:
- 基本语法:变量、函数、struct、enum、switch、error union
- 指针与 slice
- allocator 的基本使用
- defer / errdefer
- 错误处理模型
- 与 C 互操作的基本方式
- build.zig 的基本概念
你会发现,学完这些,已经足够读很多 Zig 项目的核心代码了。
第三步:写三个极小练习
不要一上来写大项目,先写三个小东西:
练习 1:实现一个简单的字符串处理 CLI
目标:
- 读命令行参数
- 处理字符串
- 输出结果
作用:熟悉语法、标准库、基本 I/O。
练习 2:手写一个简单的文件扫描工具
目标:
- 遍历目录
- 读取文件
- 统计行数 / 单词数 / 后缀名
作用:熟悉文件系统接口和错误处理。
练习 3:写一个带 allocator 的小型 parser
目标:
- 解析一小段 DSL / 配置文本
- 自己分配和释放对象
作用:开始真正理解 Zig 为什么强调显式内存管理。
第四步:开始读 Bun 这种大项目的局部代码
这个阶段不要试图一口气看懂整个 Bun。
你只需要挑几块最有代表性的:
build.zig:看 Zig 怎么做构建系统src/bundler/:看 Zig 怎么做高性能内存管理src/install/:看 Zig 怎么组织复杂状态机
哪怕你一开始只能看懂 30%,也会比单纯刷语法题进步更快。
第五步:做一个你自己用得上的工具
学习系统语言最好的方式,不是做 LeetCode,而是做一个你每天真会用的小工具。
比如:
- 一个日志清洗工具
- 一个批量重命名工具
- 一个本地代码扫描器
- 一个小型代理/转发器
- 一个简单的代码生成器
只要你真的会每天运行它,你对 Zig 的理解就会快速加深。
如果你本来就喜欢 Rust,该怎么判断自己要不要学 Bun 和 Zig?
我的建议很简单。
Bun 值得学,如果你:
- 经常写 Node / TypeScript 工具
- 讨厌繁琐的脚本和配置
- 很在意开发反馈速度
- 对更统一的工程体验有要求
- 做 CLI、构建工具、AI coding 周边工具比较多
哪怕你最终还是继续用 Rust 做主力后端,Bun 也依然值得你认真用一段时间。 因为它会让你重新思考:
- 什么能力应该内建进 runtime
- 什么能力只是历史补丁
- 什么复杂度其实可以被整体收编
Zig 值得学,如果你:
- 想往底层和系统方向再走一步
- 想真正理解内存、分配器、运行时和构建系统
- 对高性能工具链实现感兴趣
- 想提升自己的工程“底层视角”
但如果你已经是 Rust 用户,我的建议不是“立刻转向 Zig”,而是:
把 Zig 当成一个帮助你扩展系统视角的补充语言。
Rust 会继续给你:
- 强类型约束
- 内存与并发安全
- 更稳健的大型工程体验
而 Zig 会提醒你另一套东西:
- 更直接的 ABI 思维
- 更显式的分配器意识
- 更少语言魔法时,系统代码会长什么样
这两者不是非此即彼,反而非常适合互相参照。
对我来说,最舒服的姿势其实是:
- 继续热爱 Rust
- 认真使用 Bun
- 把 Zig 当成理解现代工具链实现的一把钥匙
Bun 给我的最大启发,不是换了一个包管理器
表面上看,我做的只是删掉了 pnpm、yarn,换成了 bun。
但更深层的变化其实是:
Bun 让我重新意识到,很多我们习以为常的工具链复杂度,并不是天经地义。
我们过去在 JavaScript 生态里接受了太多“理所当然”的东西:
- 多个包管理器并存
- 多套测试体系并存
- 多种构建工具叠加
- 大量脚本胶水
- 一层又一层历史兼容补丁
而 Bun 做的一件很有野心、也很有价值的事,就是试图把这些碎片重新收拢起来。
它不一定已经在所有场景里都完美,但它至少证明了一件事:
更统一、更少层次、更强调默认体验的工具链,是完全有机会赢得开发者的。
而 Zig 则是这个故事背后更深的一层:
它提醒我们,优秀的工程工具,不只是 API 设计得好看,更重要的是底层实现足够克制、足够直接、足够尊重系统本身。
如果说 Bun 是“让我重新对 JavaScript 工具链产生信心”的项目, 那么 Zig 更像是“让我用另一种角度重新审视系统编程”的入口。
而 Rust,依然是那个让我在真正落地复杂工程时,最有安全感的老朋友。
对我来说,这可能才是 Bun 最值钱的地方。
结尾
作为一个 Rust 热爱者,我并不觉得 Bun 和 Zig 的出现是在取代 Rust。
真正让我兴奋的,是另一件事:
优秀的工程项目,总会逼着我们跳出语言阵营,重新思考系统该如何被构建。
Bun 让人看到,一体化、少层次、强默认能力的工具链依然有巨大生命力。 Zig 让人看到,很多性能与控制力,来自对底层边界的诚实面对。 而 Rust 则继续提醒我们,复杂系统的长期演化,同样需要强约束带来的安全感。
所以对我来说,这不是一个“站队哪门语言”的故事。
这是一个关于工程判断的故事:
- 什么场景该追求更强的控制感
- 什么场景该追求更高的安全性
- 什么场景该把复杂度收回系统内部
- 什么场景该用更少的层换来更高的效率
很多时候,真正改变我们的,不是某个工具赢了。
而是我们终于开始用更成熟的方式理解工具背后的取舍。