Nub:不造新运行时,而是给 Node 补齐全家桶的 Rust 工具链
阅读时间: 大约 10 分钟
Nub:不造新运行时,而是给 Node 补齐全家桶的 Rust 工具链
这两年 Bun、Deno 都想用全新运行时正面挑战 Node。Nub 走了一条相反的路:它不取代 Node,而是用一个 Rust 二进制把”跑 TS、跑脚本、装依赖、管 Node 版本”这一整套围绕 Node 的工具链体验补齐。本文基于其官网公布的基准数据,分析它的机制、性能数字与口径。

一、背景:Node 工具链的”胶水税”
用 Node 做项目,开发者往往要装一堆工具:用 tsx 或 ts-node 跑 TS、用 dotenv 加载环境变量、用 tsconfig-paths 解析路径、用 pnpm/npm 管依赖、用 nvm/fnm 管版本、用 npx 调 CLI。每个工具都是 Node 程序,每次冷启动都要加载一遍 JS——这就是脚本命令”明明什么都没干却卡几百毫秒”的根源。Nub 的野心是用一个 Rust 二进制把这些胶水全换掉。
二、核心机制:内存转译,跑在真 Node 上
Nub 的架构选择是它和 Bun/Deno 最本质的区别。官网原话:“Nub transpiles your code in memory with oxc (compiled into a native Node addon) and runs the output on the stock node binary. There’s no Nub runtime, just real Node.”
也就是说:
- 它用 oxc(编译成 Node 原生扩展)在内存里把 TS 转译掉,然后交给你本机真实的 node 二进制执行;
- 跑在 Node 18 LTS 及以上;
- 因此它不是”类型擦除”——Node 原生 type stripping 拒绝的 enum、参数属性、无扩展名导入,Nub 的 load hook 都能处理;
- 它会读你的
tsconfig.json(含 extends、paths)、自动加载.env,还能直接 import YAML/TOML/JSON5/JSONC。
官网特意强调”零锁定”:没有 Nub 全局、没有 nub:* 模块命名空间、没有 @nub/* 包、没有 package.json 里的 nub 字段、没有 Nub 专属 lockfile。你的代码就是普通 Node 代码。
三、关键数据:性能基准
官网给出多组 hyperfine 基准(已核实原文):
跑一个 TS 文件(macOS):
| 命令 | 耗时 | 对比 |
|---|---|---|
node hello.ts | 44 ms | 基准 |
nub hello.ts | 44 ms | 持平 |
tsx hello.ts | 128 ms | 慢 2.9× |
脚本分发(warm,50 次,macOS):
| 命令 | 耗时 | 对比 |
|---|---|---|
nub run | 14.7 ms | 基准 |
node --run | 32.2 ms | 慢 2.2× |
npm run | 329.9 ms | 慢 22× |
pnpm run | 442.7 ms | 慢 30× |
调本地 CLI(esbuild —version,macOS):
| 命令 | 耗时 | 对比 |
|---|---|---|
nubx esbuild | 11 ms | 基准 |
pnpm exec esbuild | 191 ms | 慢 17× |
npx esbuild | 226 ms | 慢 19× |
warm frozen 安装(1168 包,Linux):
| 命令 | 耗时 | 对比 |
|---|---|---|
nub install | 346 ms | 基准 |
nub --hoisted | 1461 ms | 慢 4.2× |
bun | 1896 ms | 慢 5.5× |
pnpm | 3453 ms | 慢 10× |
npm | 12945 ms | 慢 37.4× |
可以看到 Nub 的提速本质是把 JS 启动开销换成 Rust 启动——跑业务代码本身和原生 node 持平,省的是工具自己的那几百毫秒。
四、Node 兼容率:口径要核对
这是 Koala 周报与官网原文对不上的地方,必须分清:
Koala 称”在 Deno 的 Node 兼容测试里拿到 98.8%,远超 Bun 和 Deno”。但官网原文给的是 Nub 98.4%(4,613 / 4,690),对比如下:
| 运行时 | 兼容率 | 通过/总数 |
|---|---|---|
| Node 26.7 本体 | 100% | 4,690 / 4,690 |
| Nub | 98.4% | 4,613 / 4,690 |
| Deno 2.9 | 72.4% | 3,397 / 4,690 |
| Bun 1.4 | 68.5% | 3,214 / 4,690 |
也就是说,Nub 确实以 98.4% 大幅领先 Deno(72.4%)与 Bun(68.5%),但具体数字是 98.4% 而非 98.8%。更重要的是官网对这 77 个失败测试的解释:“Most of Nub’s 77 misses are tests that assert on machinery Nub installs itself——the permission model, module-loader hooks, the test runner, the compile cache”——即大部分未通过项是那些”断言 Nub 自己加装的内部机制”的测试,而非真实业务代码不兼容。这个 nuance 很关键:98.4% 是”在 Deno 兼容性透镜下”的得分,且失分多在自安装件上。
五、供应链安全:默认加固
Nub 内置的包管理器(引擎代号 aube)默认开启供应链防护,无需配置:
- postinstall 脚本默认拒绝(deny-by-default);
- 每次新鲜解析都向 OSV 查询恶意包公告(官网举例
@ledgerhq/connect-kit因 MAL-2023-8697 被拒装); - 拒绝”发布信任证据较前一版本变弱”的版本;
- 对发布时间短于 **minimumReleaseAge(24 小时,与 pnpm 对齐)**的包延迟拉入,防止刚被入侵的版本被立刻装走。
它还是个”元包管理器”:自动识别项目当前用 pnpm/npm/bun,就地读写对应 lockfile(package-lock.json / pnpm-lock.yaml / bun.lock),无需迁移。
六、官方承认的局限与口径偏差
- 版本很早期:当前 v0.7,配置兼容表仍在补齐(
trustedDependencies等规则列里 nub 暂为空); - 基准全是厂商自测:hyperfine、指定硬件、指定包数,数字漂亮但缺第三方独立复现;
- “30× faster”是脚本分发冷启动差距,不是业务代码跑更快——跑 TS 文件时它和 node 本身持平;
- 兼容率 98.4% 是 Deno 测试套件口径,且失分集中在自安装件,不能等同于”跑任何 Node 包都 100% 兼容”;
- 仍需本机有 Node 二进制——它不替代 Node,只是前置转译与工具层。
七、适用 / 不适用场景
适合:
- 受够了 pnpm run/npx 冷启动卡顿的 monorepo 团队;
- 想在一个工具里统一跑 TS、跑脚本、装依赖、管 Node 版本;
- 看重供应链默认加固(禁 postinstall、OSV、24h 冷却)的团队。
不适合:
- 已经习惯 Bun/Deno 并享受其内置现代 API、不想保留 Node 的人;
- 需要极高稳定性、不愿押注 v0.7 工具链的生产关键路径;
- 只跑纯 JS、根本不用 TS 的极简项目。
八、它意味着什么
Nub 代表了 Node 生态的一条务实路线:不去赌一个新运行时,而是用 Rust 把围绕 Node 的工具链毛刺全部磨平。它的聪明在于”完全不 fork Node、flag-for-flag 兼容、零 lock-in”——你随时可以把 nub 换回 node/pnpm,没有心理负担。在 Bun/Deno 疯狂抢占叙事时,Nub 安静地证明了:很多开发者其实不想换运行时,只想让现有 Node 工作流更快、更安全。对一个 v0.7 项目,它的完成度和文档已经相当可观;但能否像 pnpm 那样沉淀为事实标准,还要看它能否守住 100% 兼容承诺并补齐配置边界。