作为一个 Rust 热爱者,我为什么越来越喜欢 Bun?

  • King
  • 发布于 22小时前
  • 阅读 37

前两天,我做了一件很“冲动”的事:把机器上的pnpm、yarn一类工具都删了,只留下了bun。这不是情绪化决定,而是过去一段时间真实使用之后的结果。但先把立场说清楚:我依然是个Rust热爱者。我喜欢Rust,不只是因为它快,而是因为它在工程上给人一种很强的信心:边界清楚、抽象克

前两天,我做了一件很“冲动”的事:把机器上的 pnpmyarn 一类工具都删了,只留下了 bun

这不是情绪化决定,而是过去一段时间真实使用之后的结果。

但先把立场说清楚:我依然是个 Rust 热爱者。

我喜欢 Rust,不只是因为它快,而是因为它在工程上给人一种很强的信心:

边界清楚、抽象克制、类型系统有力量、性能和可维护性往往能一起成立。

也正因为我很喜欢 Rust,所以我最开始看 Bun 和 Zig,其实是带着一点挑剔甚至怀疑的。

结果越用 Bun,越觉得它值得认真写一篇。因为它让我产生的不是“换了个包管理器”的新鲜感,而是另一种熟悉的敬意:

一个工程团队,真的在试图从底层重新整理整个工具链。

最近随着 Claude Code 的 source map 暴露事件,很多人也注意到它的工程里大量使用了 Bun。对我来说,这件事最有启发的地方,不是“某个明星项目也在用 Bun”,而是另一个问题:

为什么越来越多对启动速度、交互体验、工程统一性极度敏感的项目,会认真选择 Bun?

这篇文章,我想聊三件事:

  1. Bun 到底是什么,为什么它会让人用了就回不去
  2. 从 Bun 身上,我们能学到哪些工程思维
  3. 如果你被 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 install
  • bun run
  • bun test
  • bun build
  • bunx

看起来只是少记几个命令,但本质上发生的是:

原来散落在多个工具、多个作者、多个配置系统中的能力,被收编到了同一个 runtime 的世界观里。

这就是 Bun 最迷人的地方。它不是“一个快一点的工具”,而是“一个更统一的工程入口”。


为什么我用了 Bun 之后,开始嫌弃 pnpm / yarn / 一堆辅助工具

先说结论:

Bun 给人的最强体验,不是 benchmark 数字,而是“摩擦感显著下降”。

很多工程工具并不是不能用,而是用起来总有很多小摩擦:

  • 安装依赖慢一点
  • 冷启动慢一点
  • 测试跑起来再等一下
  • 多一个配置文件
  • 多一个适配层
  • 多一个脚本 hack

这些问题单独看都不致命,但叠加起来就会非常烦。

Bun 的价值就在于:它把这些小摩擦一口气砍掉了一大批。

1. 安装依赖更直接

以前一个项目装依赖,脑子里先想的是:

  • 用 npm?
  • 用 pnpm?
  • 用 yarn?
  • monorepo 怎么配?
  • lockfile 怎么迁?

现在很多项目里,我直接就是:

bun install

没有那种“工具选择焦虑”,也没有那么多“先决定生态阵营,再开始干活”的心理负担。

2. 运行 TypeScript / JSX 的路径更短

很多过去需要 ts-nodetsxnodemon、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%

刚开始不用追求全面掌握,先抓住最重要的内容:

  1. 基本语法:变量、函数、struct、enum、switch、error union
  2. 指针与 slice
  3. allocator 的基本使用
  4. defer / errdefer
  5. 错误处理模型
  6. 与 C 互操作的基本方式
  7. 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 给我的最大启发,不是换了一个包管理器

表面上看,我做的只是删掉了 pnpmyarn,换成了 bun

但更深层的变化其实是:

Bun 让我重新意识到,很多我们习以为常的工具链复杂度,并不是天经地义。

我们过去在 JavaScript 生态里接受了太多“理所当然”的东西:

  • 多个包管理器并存
  • 多套测试体系并存
  • 多种构建工具叠加
  • 大量脚本胶水
  • 一层又一层历史兼容补丁

而 Bun 做的一件很有野心、也很有价值的事,就是试图把这些碎片重新收拢起来。

它不一定已经在所有场景里都完美,但它至少证明了一件事:

更统一、更少层次、更强调默认体验的工具链,是完全有机会赢得开发者的。

而 Zig 则是这个故事背后更深的一层:

它提醒我们,优秀的工程工具,不只是 API 设计得好看,更重要的是底层实现足够克制、足够直接、足够尊重系统本身。

如果说 Bun 是“让我重新对 JavaScript 工具链产生信心”的项目, 那么 Zig 更像是“让我用另一种角度重新审视系统编程”的入口。

而 Rust,依然是那个让我在真正落地复杂工程时,最有安全感的老朋友。

对我来说,这可能才是 Bun 最值钱的地方。


结尾

作为一个 Rust 热爱者,我并不觉得 Bun 和 Zig 的出现是在取代 Rust。

真正让我兴奋的,是另一件事:

优秀的工程项目,总会逼着我们跳出语言阵营,重新思考系统该如何被构建。

Bun 让人看到,一体化、少层次、强默认能力的工具链依然有巨大生命力。 Zig 让人看到,很多性能与控制力,来自对底层边界的诚实面对。 而 Rust 则继续提醒我们,复杂系统的长期演化,同样需要强约束带来的安全感。

所以对我来说,这不是一个“站队哪门语言”的故事。

这是一个关于工程判断的故事:

  • 什么场景该追求更强的控制感
  • 什么场景该追求更高的安全性
  • 什么场景该把复杂度收回系统内部
  • 什么场景该用更少的层换来更高的效率

很多时候,真正改变我们的,不是某个工具赢了。

而是我们终于开始用更成熟的方式理解工具背后的取舍。

点赞 1
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
King
King
0x56af...a0dd
擅长Rust/Solidity/FunC/Move开发