Node.js 自带“加速器”:node --run 是否比 Bun 更快?

作者:Legend80s日期:2026/2/3

前言

在 JavaScript 后端运行时领域,速度一直是核心战场。近年来,Bun 以其宣称的“一体化”工具链和闪电般的启动速度异军突起,对老牌王者 Node.js 发起了强劲挑战。bun run 的迅捷,让许多开发者开始重新评估他们的工具选择。

然而,Node.js 并未止步。自 v22.0.0 起,它悄然引入了一个专为启动性能而生的秘密武器:node --run。这个内置于 Node.js 核心的命令,旨在以最精简、最直接的方式执行 package.json 中的脚本,宣称要为最常见的用例提供“顶级性能”。

这引发了我们的好奇:在真实的场景下,这位新秀的表现究竟如何?它与 bun run 及传统的 npm run 相比,孰优孰劣?

本文将通过一系列严谨的对比测试,揭开 node --run 的神秘面纱,用数据回答:在 2026 年的脚本启动性能竞赛中,谁才是真正的速度王者?

各位小伙伴请注意!本文将颠覆这个传统观念“bun 启动一定比 Node.js 更快”。


首先我们回顾下 Node.js 运行文件有三种方式:

  1. 直接启动 node foo.[jt]s 🤼‍♂️ bun foo.[jt]s
  2. package.json 脚本运行 npm run foo 🤼‍♂️ bun run foo
  3. 脚本 --run 直接运行 node --run foo Added in: v22.0.0 🤼‍♂️ bun --run foo

统计方法,我们模仿竞技比赛中,去掉一个最高分和一个最低分,可以避免“冷启动”等极端数据干扰,采取去掉最大和最小值然后取平均值,这样抗干扰性强更公平

第一轮:直接启动 JS 文件速度

分别启动两个 mjs 文件,一个空一个有 IO 输出。测试文件:

1// empty.mjs
2
1// io.mjs
2console.log('hello world');
3
4

Node.js 🟢

分别执行 time node empty.js time node io.mjs 各自三次。

❯ time node empty.mjs

1node empty.mjs  0.00s user 0.17s system 78% cpu 0.217 total
2node empty.mjs  0.00s user 0.17s system 84% cpu 0.203 total
3node empty.mjs  0.00s user 0.16s system 69% cpu 0.225 total
4

无 io 平均耗时:≈217ms\approx217ms≈217ms。

❯ time node io.mjs

1node io.mjs  0.00s user 0.17s system 73% cpu 0.234 total
2node io.mjs  0.00s user 0.17s system 72% cpu 0.236 total
3node io.mjs  0.00s user 0.17s system 74% cpu 0.229 total
4

io 平均耗时:≈234ms\approx234ms≈234ms。

整体耗时:≈225ms\approx225ms≈225ms。

Bun 🍞

1bun empty.mjs  0.04s user 0.17s system 56% cpu 0.375 total
2bun empty.mjs  0.00s user 0.21s system 63% cpu 0.337 total
3bun empty.mjs  0.03s user 0.23s system 70% cpu 0.371 total
4

≈371ms\approx371ms≈371ms

1bun io.mjs  0.05s user 0.17s system 63% cpu 0.338 total
2bun io.mjs  0.00s user 0.20s system 56% cpu 0.351 total
3bun io.mjs  0.03s user 0.20s system 62% cpu 0.369 total
4

≈351ms\approx351ms≈351ms

整体:≈361ms\approx361ms≈361ms

这数据有点反常,1 bun 启动 io 文件速度反而快于空文件,2 其次得到本文第一个非常重要的结论:bun 对 js 文件启动速度反而劣于 Node.js(二者相差 100ms+)。

第二轮:直接启动 TS 文件速度

[!TIP] 注意:想要不加参数直接运行 TS,Node.js 版本需 ≥\geq≥ v22.18.0

分别启动两个 ts 文件,一个空一个有 IO 输出。测试文件:

1# 文件内容一样
2empty-ts.ts
3io-ts.ts
4

Node.js 🟢

1node empty-ts.ts  0.00s user 0.19s system 73% cpu 0.254 total
2node empty-ts.ts  0.00s user 0.17s system 72% cpu 0.236 total
3node empty-ts.ts  0.00s user 0.17s system 71% cpu 0.240 total
4

无 io 平均耗时:≈240ms\approx240ms≈240ms。

❯ time node io-ts.ts

1node io-ts.ts  0.00s user 0.17s system 64% cpu 0.263 total
2node io-ts.ts  0.00s user 0.17s system 67% cpu 0.255 total
3node io-ts.ts  0.00s user 0.17s system 67% cpu 0.254 total
4

io 平均耗时:≈255ms\approx255ms≈255ms。

整体耗时:≈248ms\approx248ms≈248ms。

[!TIP] 小结:Node.js 运行 ts 耗时比 js 增加 ~20ms,这在预期内因为先要 amacro ts 编译器即将所有类型用空格替代

Bun 🍞

1bun empty-ts.ts  0.04s user 0.21s system 69% cpu 0.372 total
2bun empty-ts.ts  0.01s user 0.15s system 45% cpu 0.372 total
3bun empty-ts.ts  0.06s user 0.17s system 56% cpu 0.402 total
4

无 io 平均耗时:≈372ms\approx372ms≈372ms。

1bun io-ts.ts  0.01s user 0.25s system 64% cpu 0.405 total
2bun io-ts.ts  0.00s user 0.21s system 55% cpu 0.388 total
3bun io-ts.ts  0.09s user 0.23s system 74% cpu 0.429 total
4

io 平均耗时:≈405ms\approx 405ms≈405ms。

整体耗时:≈388.5ms\approx 388.5ms≈388.5ms。

[!TIP] 小结:Bun 运行 ts 耗时比 js 增加 ~20ms,预期内。

本文第二个结论:bun 执行 ts 文件启动速度劣于 Node.js(二者相差 388−248=140ms+388 - 248 = 140ms+388−248=140ms+)。

有读者可能会问是否是通过环境变量寻址 bun 耗时导致的。那我们直接跳过寻址:

❯ time /e/pnpm/bun io-ts.ts

1/e/pnpm/bun io-ts.ts  0.00s user 0.21s system 55% cpu 0.384 total
2/e/pnpm/bun io-ts.ts  0.00s user 0.23s system 67% cpu 0.341 total
3/e/pnpm/bun io-ts.ts  0.06s user 0.17s system 56% cpu 0.407 total
4

直接寻址耗时 384ms 384ms384ms,确实少于 405ms 405ms405ms,但依然显著高于 Node.js 的 255ms255ms255ms!所以

结论一

Bun 无论启动 JavaScript 还是 TypeScript 文件都要慢于 Node.js

注意这里是启动而非运行。

第三轮:package.json 脚本启动

结论先行:执行 package.json 内的 scripts bun run 的启动速度快于 npm run。我们测试下。

npm v11.7.0

我们定义两个 script io 和不含 io 的:

1{
2  "type": "module",
3  "scripts": {
4    "io": "echo \"hello world\"",
5    "empty": ""
6  }
7}
8

npm run

❯ time command npm run io

[!TIP]command npm 是因为我在 ~/.zshrc 内对 npm 做了同名 alias 需通过 command 找到原始命令。

1> rsbuild-react-19@1.0.0 io
2> io "hello world"
3
4"hello world"
5command npm run io  0.00s user 0.39s system 58% cpu 0.660 total
6
1command npm run io  0.00s user 0.34s system 52% cpu 0.649 total
2command npm run io  0.01s user 0.31s system 50% cpu 0.638 total
3

npm run io 耗时:650ms650ms650ms。

去除 IO:❯ time command npm run empty

1command npm run empty  0.05s user 0.32s system 60% cpu 0.610 total
2command npm run empty  0.03s user 0.34s system 59% cpu 0.626 total
3command npm run empty  0.00s user 0.33s system 53% cpu 0.611 total
4

纯启动耗时 616ms616ms616ms。

整体耗时:npm run 启动需 ≈600ms\approx600ms≈600ms。这也太慢了,代码啥都没干呢!

接下来试试 bun run

bun run

❯ time bun run io:

1bun run io  0.03s user 0.21s system 79% cpu 0.308 total
2bun run io  0.06s user 0.21s system 78% cpu 0.347 total
3bun run io  0.00s user 0.21s system 68% cpu 0.313 total
4

313ms313 ms313ms 左右

❯ time bun run empty

1bun run empty  0.04s user 0.18s system 60% cpu 0.380 total
2bun run empty  0.01s user 0.21s system 69% cpu 0.330 total
3bun run empty  0.03s user 0.21s system 67% cpu 0.361 total
4

361ms361 ms361ms 左右。第二个反常 io 反而更慢。

整体耗时 337ms337 ms337ms。结论 bun run 大概是 npm run 的两倍(600/300=2600 / 300=2600/300=2)性能。

突然想起 Node.js v22.0.0 支持 node --run 运行脚本,专为性能而生,看看它表现如何。

第四轮:package.json 脚本 `--run` 直接运行

先解释下 node --run,是的,它也可以执行 package.json 中的脚本,而且生来就是为性能考虑(不会执行 pre / post 钩子)。

它将从 package.json 文件的 "scripts" 对象中运行指定的命令。如果提供的 "command" 不存在,则会列出可用的脚本。

node --run 并不旨在完全匹配 npm run 或其他包管理器的运行命令的行为。Node.js 的实现有意更加精简,以便在最常见的用例中专注于顶级性能。其他运行实现中一些被有意排除的功能包括:

  • 除了运行指定的脚本外,还会运行前置(pre)或后置(post)脚本。
  • 定义特定于包管理器的环境变量。

—— nodejs.org/docs/latest…

node --run

❯ time node --run io:

1node --run io  0.00s user 0.17s system 79% cpu 0.216 total
2node --run io  0.00s user 0.16s system 81% cpu 0.192 total
3node --run io  0.00s user 0.19s system 84% cpu 0.220 total
4

216ms216ms216ms 完美 🤩

❯ time node --run empty:

1node --run empty  0.00s user 0.17s system 89% cpu 0.192 total
2node --run empty  0.01s user 0.16s system 80% cpu 0.212 total
3node --run empty  0.00s user 0.17s system 89% cpu 0.192 total
4

192ms192 ms192ms 完美 🤩🤩

node --run 整体平均:204ms204 ms204ms,确实做了性能优化,三倍性能提升 🚀npm run 616ms VS node --run 204ms

bun --run

1bun --run empty  0.06s user 0.14s system 53% cpu 0.370 total
2bun --run empty  0.05s user 0.21s system 75% cpu 0.347 total
3bun --run empty  0.04s user 0.21s system 68% cpu 0.379 total
4

370ms370 ms370ms

1bun --run io  0.01s user 0.18s system 61% cpu 0.324 total
2bun --run io  0.01s user 0.23s system 73% cpu 0.334 total
3bun --run io  0.03s user 0.17s system 52% cpu 0.382 total
4

334ms334 ms334ms (io 反而速度快于空脚本 -_-||)

bun --run 整体耗时 352ms352 ms352ms,反常三:bun --run 慢于 node --run 的 204ms204 ms204ms

性能数据总结

文章从三个维度(直接启动文件、运行 package.json 脚本、使用 --run 命令)对比了 Node.js 和 Bun 的性能。

核心结论

  1. 直接启动文件:无论 TS or JS,Node.js 以显著优势胜出。
  2. 运行 package.json 脚本:Bun (bun run) 击败 npm (npm run),但 node --run 凭借其精简设计击败 bun run / npm run / bun --run

至此本文颠覆了一个传统观念“bun 启动一定比 Node.js 更快”。

附录:详细数据

表格一:直接运行 JS/TS 文件性能对比 (单位:ms)
测试场景Node.js (v22.18.0)Bun (v1.3.2)性能胜出方
启动空 JS 文件~217~371Node.js (快 ~41%)
启动含 IO 的 JS 文件~234~351Node.js (快 ~33%)
JS 文件启动综合耗时~225~361Node.js 胜出
启动空 TS 文件~240~372Node.js (快 ~35%)
启动含 IO 的 TS 文件~255~405Node.js (快 ~37%)
TS 文件启动综合耗时~248~389Node.js 胜出

结论一: 在直接启动文件(无论 JS 或 TS)的场景下,Node.js 🚀 性能显著优于 Bun,平均领先幅度在 35%-41% 左右。虽然有反直觉但是我的 Windows 下确实如此。


表格二:运行 package.json 脚本性能对比 (单位:ms)
执行方式平均耗时 (含IO)平均耗时 (空脚本)综合平均耗时性能排序 (由快到慢)
node --run~216 ms~192 ms~204 ms🥇 第1名
bun run~313 ms~361 ms~337 ms🥈 第2名
bun --run~334 ms~370 ms~352 ms🥉 第3名
npm run~650 ms~616 ms~633 ms第4名

结论二:

  1. node --run 是绝对的性能冠军,速度是 npm run3.1 倍,也比 bun run 快约 65%
  2. Bun 相关命令性能接近:bun runbun --run 性能在同一水平,都显著快于 npm run(快约 88%)。
  3. npm run 垫底:传统 npm 脚本的启动开销最大,耗时最长。

对我们的启发

  • Node.js vs. Bun 启动速度:在直接启动 .js.ts 文件时,Node.js 比 Bun 快约 40%-60% 。这是“一个非常重要的结论”。
  • Package Script 运行速度
    • bun runnpm run 快约 2 倍
    • 而黑马 🐎 node --runnpm run 快约 3 倍

node --run 的意义——包脚本运行的革新node --run 无疑是本次测试的最大亮点,其速度非常接近直接运行 node foo.js 的速度,实现了近乎“裸奔”的脚本执行性能。它通过牺牲 npm 脚本的部分高级功能(如 pre/post 钩子、特定的环境变量),换来了 ~3 倍于 npm run 的速度提升,甚至超越了以速度见长的 bun run。对于追求极致构建、测试或启动速度,且不依赖这些高级特性的项目,node --run 提供了一个近乎完美的“性能模式”。

启发:如果你要直接执行文件请使用 Node.js,如果要执行 npm script 建议 99% 情况下用 node --run(无需运行 pre / post npm script 时)否则 bun run

说明

测试环境 Windows 10、git bash、Node.js 🟢 v22.18.0、npm v11.7.0、bun 🍞 v1.3.2。


—— 完 🎉 最新文章请关注公众号 JavaScript与编程艺术 ——


Node.js 自带“加速器”:node --run 是否比 Bun 更快?》 是转载文章,点击查看原文


相关推荐


拥抱PostgreSQL支持UI配置化
神奇的程序员2026/1/25

前言 前阵子写的日志分析工具NginxPulse,自开源以来,已过去2周时间,目前GitHub已收获1.5k的star。收到了不少用户的反馈建议,花了点时间将这些问题都处理了下。 本文就跟大家分享下新版本都解决了哪些问题,优化了哪些内容,欢迎各位感兴趣的开发者阅读本文。 抛弃SQLite 有不少用户反馈说日志文件很大的时候(10G+),解析速度非常慢,需要解析好几个小时,解析完成之后数据看板的查询也比较慢(接口响应在5秒左右)。 于是,我重写了日志解析策略(解析阶段不做IP归属地查询,仅入库其他


Mac 科研/论文专用快捷键(Word + LaTeX + Finder) 与文件管理
加油_Yeah2026/1/16

✅ 一、只背 15 个的「Mac 生存快捷键」 只记这 15 个,就能高效 + 不踩坑 🔑 核心通用(8 个) ⌘ + Space —— 全局搜索(秒开文件/程序) ⌘ + Z —— 撤销(后悔药) ⌘ + ⇧ + Z —— 重做 ⌘ + C —— 复制 ⌘ + V —— 粘贴 ⌘ + ⌥ + V —— 移动文件(重点) ⌘ + S —— 保存 ⌘ + Q —— 彻底退出程序 📁 文件 / 窗口(7 个) ⌘ + ⇧ + N


微服务架构核心组件、职责与交互全解析
元Y亨H2026/1/8

微服务架构核心组件、职责与交互全解析 一、 微服务全景架构图(分层) 微服务不再是散乱的工程,而是一个分工明确的矩阵。通过分层,我们可以更清晰地看到请求是如何流转的。 ==================== 流量接入层 (Entrance) ==================== [ 外部客户端:App / H5 / Web / PC ] │ (Restful API / HTTPS) ┌───────


2025年12月总结
袁庭新2025/12/31

大家好,我是袁庭新。2025年的最后一个月已经圆满结束,借此机会对本月的工作进行一次总结与回顾。 课程研发 一直想讲一门如何赚钱的课,这就是《微信商业生态平民创业》这门课设计的初衷,这个月编写了2节这门课的讲义,但还未完成录制,现总计录制了20节,计划是24节课程。 放在以前软件开发和我们绝大多数人是没有关系,随着大模型基础服务平台的崛起,你可能无法想象现在不懂任何编程技术零基础也可快速上手定制开发出自己的智能体应用出来,并上线到各大平台,如微信小程序、豆包等。 这个月我也集中注意力开发了7个实


flink的一阶段提交的流程
飞哥大数据2025/12/21

Flink的一阶段提交流程 Apache Flink 是一个分布式流处理框架,用于高效处理大规模数据流。在 Flink 中,“提交”通常指将作业部署到集群执行的过程。用户提到的“一阶段提交”可能指的是 Flink 中某些特定场景下的简化提交机制,尤其是在事务处理或 Sink 端(输出端)的 Exactly-Once 语义实现中。标准 Flink 作业提交涉及多个步骤,但“一阶段提交”更常见于事务管理上下文,例如当 Sink 系统支持幂等操作时,Flink 可以使用一阶段提交来简化流程,避免两阶


告别AI塑料感:阿里Qwen3-Omni-Flash要把大模型做成真人
墨风如雪2025/12/13

如果是长期关注大模型领域的朋友,大概都会有这样一种感觉:现在的AI虽然智商越来越高,但只要一开口说话,那种特有的“塑料感”还是很难消除。无论是语音的机械停顿,还是多模态交互时的“脑子慢半拍”,都时刻提醒着我们,对面只是个程序。 但在2025年12月9日,这个局面似乎被阿里的Qwen团队撕开了一道口子。 他们正式发布的Qwen3-Omni-Flash-2025-12-01,不再仅仅是在刷榜单上的分数(虽然分数确实也刷得很猛),而是实打实地盯着“像人一样交流”这件事死磕。作为一名在这个圈子里摸爬滚打


web3区块链-小镇店铺的 “借力办事”:call 与 delegatecall 的区别与联系Web3-智能合约-整数溢出攻击:“凭空造币”的秘密
想ai抽2025/12/4

加密小镇上有两家店: A 店(水果店):老板是 Alice,有自己的账本(合约存储),记录着 “苹果库存”(存储变量uint256 public appleStock = 100;),但没学会 “盘点库存”“修改库存” 的方法;B 店(管理咨询店):老板是 Bob,专门帮人做库存管理,有两套核心 “操作手册”(合约函数): checkStock():读取自己账本上的库存,返回数值;addStock(uint256 num):把自己账本上的库存增加num个。 A 店想复用 B 店的方法


【C++】c++中“引用”的详解
王璐WL2026/2/12

文章目录 1. 引用1.1 引用的概念和定义1.2 引用的特性1.3 引用的使用小小的延伸1.4 const引用1.5 指针和引用的关系(面试常考) 1. 引用 1.1 引用的概念和定义 ​ 引⽤不是新定义⼀个变量,⽽是给已存在变量取了⼀个别名,编译器不会为引⽤变量开辟内存空间(指针会开辟空间), 它和它引⽤的变量共⽤同⼀块内存空间。比如:水浒传中林冲,外号豹⼦头 ​ 类型&引⽤别名=引⽤对象; ​ C++中为了避免引⼊太多的运算符,会复⽤C语⾔的⼀些符号,⽐如前⾯


Hadoop MapReduce 详解
之歆2026/2/20

想象一个巨大的文档分类任务,一个人处理要一个月。MapReduce 把这个任务分配给一百个人,每人处理一小部分,最后把结果汇总,半小时就完成了!这就是 MapReduce 的威力! 📑 目录 MapReduce 概述名词解释(命令与术语)Map 阶段详解Shuffle 阶段详解Reduce 阶段详解完整 WordCount 示例高级特性MapReduce 与 YARN监控与调试性能优化总结官方文档与参考 🎯 MapReduce 概述 什么是 MapReduce? Map


我的“龙虾”罢工了!正好对比下GLM、MiniMax、Kimi 3家谁更香
飞哥数智谈2026/3/1

OpenClaw(中文名:龙虾,曾用名:Clawdbot、Moltbot)从年底到现在热度持续飙升,而我感觉自己使用的还有些浅,没好意思写相关的内容。 结果今天我的龙虾罢工了,看了下,发现模型的 Coding Plan 到期了。 那正好了解下目前国内几家 Coding Plan 的内容,也方便大家对比。 本文仅涉及 GLM、Minimax、Kimi 3家自有产品的订阅套餐对比,像火山引擎、千问、无问芯穹类的综合套餐未加入对比。 为了方便对比,所有套餐都是采用按月 快速对比 核心指标整理到一

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客