Biome 编译型 linter 比 ESLint 快 10–30 倍,解决了 AI 批量提交时代码检查成为瓶颈的问题,可放弃部分类型感知规则换取速度。
我把 ESLint 换成了 Biome,因为在一个原本流畅的循环里,linting 成了拖慢速度的那一环。Claude Code 或 Codex 可以一次性给我一个完整的补丁,然后 ESLint 让我等待才能知道这个补丁是否可用。
Biome 让保存和检查的循环变得即时。我放弃了一些类型感知的规则,反正我也几乎不看它们的输出。
ESLint 不是为那种 AI 一次性提交 300 行代码的工作流设计的。它是一个插件框架,每一层都会增加开销:
最后一项才是真正的性能杀手。像 @typescript-eslint/no-floating-promises 这类类型感知规则,要求 ESLint 在运行前先解析整个 TypeScript 类型图。在中等规模的项目上,这需要每次运行 15–30 秒。
ESLint 也运行在 Node.js 上。这不是抱怨——它就是这么分发给所有人的。但对于 CPU 密集型的解析工作来说,解释型 JavaScript 就是比编译型代码慢。
结果是:大多数团队悄悄地禁用了类型感知规则,因为 CI 时间会膨胀。没有它们,ESLint 只能捕获样式问题,而非逻辑 bug。跑一个慢工具,回报却微乎其微。
Biome 是一个用 Rust 编写的 linter 和 formatter,拥有自己的解析器,不依赖 TypeScript 编译器。
仅双重解析问题在大规模下就很关键。ESLint 解析你的文件,然后 Prettier 再解析一遍用于格式化。Biome 只解析一次,在同一个 AST 上运行两个流程。
根据 Biome 自己的基准测试,格式化比 Prettier 快约 25 倍(现代硬件上的多线程),linting 在同等规则集下比 ESLint 快约 15 倍。单线程情况下,这两个数字分别下降到约 7 倍和 4 倍。这两组数据都来自 Biome 的基准测试套件,而非独立测试——ESLint 的对比刻意排除了类型感知规则,因为 Biome 不支持它们。在 commit 这些数字之前,先在你的实际代码库上跑一下基准测试。
默认情况下,所有操作都在文件间并行运行。
npm install --save-dev --save-exact @biomejs/biome
npx @biomejs/biome init
init 会生成 biome.json。一个 TypeScript React 项目的可用配置:
{
"$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"trailingCommas": "es5"
}
}
}
"scripts": {
"lint": "biome lint ./src",
"format": "biome format --write ./src",
"check": "biome check --write ./src"
}
biome check 在一次运行中执行 lint、format 和 import 排序。这是你在保存时和 CI 中要用的命令。
对于 VS Code,安装 Biome 扩展并将其设为默认 formatter:
{
"[javascript]": { "editor.defaultFormatter": "biomejs.biome" },
"[typescript]": { "editor.defaultFormatter": "biomejs.biome" },
"[typescriptreact]": { "editor.defaultFormatter": "biomejs.biome" }
}
如果安装了 Prettier 就禁用它——它们在保存时会冲突。
Biome 的规则覆盖面更小——约 250 条规则 vs ESLint 的 1000+ 条。没有 @typescript-eslint/no-misused-promises。没有 eslint-plugin-react-hooks。完全没有类型感知规则,因为 Biome 不运行 TypeScript 编译器。用 JavaScript 编写自定义规则是不可能的;Biome 的规则是编译后的 Rust,所以你只能局限于项目自带的那些。
迁移还意味着第一天会有大量的格式化 diff。Biome 的 formatter 在大多数情况下与 Prettier 的输出匹配,但并非全部。如果你的仓库有干净的格式化历史,做好心理准备会有一个很多噪音的 commit。
这些都是真实的限制。它们是否重要,取决于你对小众规则的依赖程度。
ESLint 的价值一直在于捕获人类遗漏的问题——规范违反、promise 误用、hook 中忘记的依赖。
有了 AI 生成初稿,我可以直接把 lint 错误抛回给写这段代码的 agent。这让快速反馈对我更有价值,而不是一个庞大但拖慢循环的规则目录。
这改变了我对 linter 的需求。它必须在每次保存时运行,捕获明显的错误,并且靠边站。在我的项目中,Biome 比大型 ESLint 插件栈更适合这个角色。
我在自己的项目中从 ESLint 切换到了 Biome。在保存格式化循环中,速度差异是立即可感的。我放弃的是:我几乎不看输出的那几个类型感知规则。我获得的是:一个我真正会一直开启的 linter。
在 Claude Code 的同一 AI 编码循环中,lint 速度是我实际使用的一部分。