bunx 是 Bun 的包运行器,也是 bun x 的别名;它无需全局安装即可从 npm 下载并运行包的可执行文件,与 npx 和 yarn dlx 的功能完全相同。
如果你曾经坐在那里等待 npx 启动一个每天要运行十几次的脚手架命令,那段小小的延迟正是 bunx 要解决的问题。如果你每天都在输入 npx create-next-app 或 npx shadcn@latest,那么一旦你的机器上安装了 Bun,bunx 就是你几乎可以无缝替换的工具——只需了解一个运行时细节(--bun 标志)和一个真正需要注意的坑(那些将字符串 npx 硬编码的工具),就能顺利完成切换。
本文将为你建立完整的认知模型:bunx 是什么、它如何解析包、为何启动速度比 npx 更快、--bun 标志的实际作用,以及何时使用它的决策规则。
核心要点
bunx是 Bun 的包运行器,也是bun x的别名;它无需全局安装即可运行 npm 包的可执行文件,与npx或yarn dlx的作用完全相同。- 与
npx一样,bunx会优先检查本地已安装的包,仅在本地不存在时才从 npm 自动安装;两个工具都会缓存已解析的包。真正的区别在于:bunx运行在 Bun 开销更低的运行时上,并将包存储在 Bun 自己的全局缓存中。 --bun标志会强制 Vite、Next、Prisma 等 CLI 工具在 Bun 运行时上执行,而非 Node,且该标志必须出现在可执行文件名之前(bunx --bun vite)。- 对于一次性脚手架和 CLI 工具,优先使用
bunx;仅当某个工具将npx硬编码或在 Bun 运行时上出现兼容性问题时,才继续使用npx。 - 像
alias npx=bunx这样的 Shell 别名在交互式终端中有效,但对非交互式子进程不可见;应将真实的可执行文件放在PATH中代替。
bunx 是什么?
bunx 无需全局安装即可运行 npm 包中的可执行文件,并随 Bun 自动附带安装。官方文档确认,bunx 是 bun x 的别名,在安装 bun 时会自动安装。它是 Bun 对应 npx 或 yarn dlx 的等价工具。
调用方式与 npx 完全相同:
# npx
npx create-next-app@latest my-app
# bunx
bunx create-next-app@latest my-app
包通过 package.json 的 "bin" 字段声明其可执行文件;bunx <package> 会找到该可执行文件并运行它。版本锁定的方式与 npx 相同,在包名后追加 @version 即可:
bunx uglify-js@3.14.0 app.js
bunx shadcn@latest add button
当可执行文件名与包名不同时,使用 -p/--package 显式指定包名,再跟上可执行文件名:
bunx -p @angular/cli ng new my-app
bunx 如何解析包?
Discover how at OpenReplay.com.
bunx 会优先检查本地是否已安装该包,若未找到则回退到从 npm 自动安装,并将安装的内容存储在 Bun 的全局缓存中以供复用。这是有文档记载的行为:“与 npx 一样,bunx 会优先检查本地已安装的包,若未找到则回退到从 npm 自动安装。“已解析的包会存入 Bun 的全局缓存,后续运行时可跳过下载步骤。
有一点值得澄清:现代 npx(npm v7+,即 npm exec)并非每次运行都下载后丢弃。它同样维护着持久化的用户级缓存,并在重复调用时复用已缓存的包。因此,真正的区别并不是”npx 用完即弃,bunx 持久保存”——两者都有缓存。真正的差异在于缓存的存储位置(Bun 自己的全局存储)以及从调用到执行的运行时开销。
为何 bunx 比 npx 更快
bunx 启动更快,因为它运行在 Bun 的运行时上,该运行时基于 JavaScriptCore(Safari 的 JavaScript 引擎)构建,而非启动 Node 进程,因此启动包运行器的固定成本更低。Bun 团队给出了具体的量化说明:bunx 发布时宣称其安装和运行 npm 可执行文件的速度比 npx 快 100 倍——文档特别指出,这一数字针对的是本地已安装的包。
请将这个数字视为 Bun 官方公布的、针对缓存命中(已安装)场景的数据,而非通用基准测试结果。真正具有普遍意义的是启动速度的提升:对于冷启动 CLI 调用(即每天在项目脚手架中执行数十次的操作),Bun 更低的进程启动开销正是节省时间的关键所在。对于首次安装(需要访问网络)的情况,两个工具都要承担下载成本,速度差异缩小为安装吞吐量加上启动时间差,而非 100 倍的差距。
如果你需要一个可靠的数据,建议自行测量,并区分冷缓存和热缓存两种场景:
# 热缓存(两者均已解析)与冷缓存的对比——实测,而非假设
hyperfine 'npx cowsay hi' 'bunx cowsay hi'
—bun 标志
--bun 标志会强制 Vite、Next、Prisma 等 CLI 工具在 Bun 运行时上执行,而非 Node,从而覆盖工具通常附带的 #!/usr/bin/env node shebang。默认情况下,Bun 会遵循该 shebang 并启动 node 进程来运行文件;--bun 则告诉它改用 Bun 的运行时:
bunx --bun vite dev
该标志对位置敏感,必须出现在可执行文件名之前。出现在文件名之后的任何内容都会直接作为参数传递给工具本身:
bunx --bun my-cli # 正确 —— 在 Bun 上运行 my-cli
bunx my-cli --bun # 错误 —— 将 --bun 作为参数传递给 my-cli
当你确实希望工具在 Bun 上运行时(例如利用 Bun 更快的启动速度或原生 TypeScript 支持),才使用 --bun。当工具依赖 Node 特定行为时,保持默认设置(不加 --bun)——某些构建工具和 CLI 依赖 Node 内部机制,强制切换到 Bun 运行时可能会导致兼容性问题。在实际使用中,一种常见的失败场景是:某个 CLI 在普通的 bunx toolname 下运行正常,但加上 --bun 切换运行时后就会报错。通常的解决方法是去掉 --bun,让 Node shebang 正常生效。
何时使用 bunx(以及何时继续使用 npx)
决策规则: 对于一次性脚手架和 CLI 工具(bunx create-next-app my-app、bunx prisma migrate、bunx prettier foo.js),优先使用 bunx;仅当某个工具将字符串 npx 硬编码或在 Bun 运行时上出现兼容性问题时,才继续使用 npx。
| 任务 | npx | bunx |
|---|---|---|
| 创建应用脚手架 | npx create-next-app my-app | bunx create-next-app my-app |
| 启动开发服务器 | npx vite | bunx vite |
| 运行数据库迁移 | npx prisma migrate | bunx prisma migrate |
| 添加组件 | npx shadcn@latest add button | bunx shadcn@latest add button |
| 格式化文件 | npx prettier foo.js | bunx prettier foo.js |
真正需要注意的坑是那些按名称调用 npx 的工具。像 alias npx=bunx 这样的 Shell 别名在交互式终端中输入命令时有效,但 Shell 别名仅存在于交互式 Shell 中——对非交互式子进程不可见。一个在内部调用 npx 的工具(例如 uv run 在内部调用它)根本不会识别这个别名。
解决方法是在 PATH 中放置一个名为 npx 的真实可执行文件,这样任何派生 npx 的进程都能解析到你的 shim。htdocs 提供的解决方案只需三行:
mkdir -p ~/.local/bin
printf '#!/bin/sh\nexec bunx "$@"\n' > ~/.local/bin/npx
chmod +x ~/.local/bin/npx
确保 ~/.local/bin 在 PATH 中排在靠前的位置。由于这是磁盘上的真实文件而非 Shell 别名,非交互式子进程同样能够解析它。如果你希望有一个仅在 Bun 已安装时才通过 Bun 路由的回退方案,可以参考 nrjdalal 展示的带有 --real 逃生舱口的条件包装函数——这是同一思路的进阶版本。
总结
将 bunx 理解为运行在更快运行时上的 npx:相同的解析顺序、相同的版本锁定语法、相同的命令格式,同时具备更低的启动开销,并将包缓存在 Bun 自己的存储中。仅在你希望工具本身在 Bun 上运行时才添加 --bun 标志,且要将其置于可执行文件名之前;对于少数要求字面命令 npx 的工具,在 PATH 中放置一个真实的 npx shim。安装 Bun,在下次脚手架操作中将一个 npx 替换为 bunx,然后亲自测量一下速度差异。
常见问题
bunx 是 npx 的直接替代品吗?
bunx 几乎可以作为 npx 的直接替代品:它们共享相同的命令格式、相同的 @version 后缀版本锁定语法,以及相同的本地优先解析顺序。唯一的例外是那些在内部将字符串 npx 硬编码的工具或脚本——除非你在 PATH 中放置一个名为 npx 的真实可执行文件,否则它们不会识别 bunx。对于这些情况,bunx 不会被自动替换。
使用 bunx 是否需要单独安装 Bun?
是的,bunx 需要 Bun。bunx 是 bun x 命令的别名,在安装 Bun 本身时会自动安装,因此不存在独立的 bunx 包。一旦你的机器上安装了 Bun,bunx 即可直接使用,无需额外配置。如果未安装 Bun,则 bunx 命令不存在,你必须回退到 npx 或其他包运行器。
bun x 和 bunx 有什么区别?
两者没有功能上的区别:bunx 只是 bun x 的别名,因此两个命令的运行方式完全相同。两者都调用 Bun 的包运行器,无需全局安装即可执行包的可执行文件。使用你喜欢的任意写法即可。bunx 的存在主要是为了提供一种更简短、对熟悉 npm 的开发者来说更直观的形式。
为什么 bunx --bun 会导致某些 CLI 崩溃,而不加 --bun 时却运行正常?
因为 --bun 会强制 CLI 在 Bun 运行时上运行,而非 Node,从而覆盖工具附带的 Node shebang。某些构建工具和 CLI 依赖 Node 特定的内部机制,切换运行时会导致兼容性问题。一个在普通 bunx toolname 下运行正常的工具,加上 --bun 后可能会报错。解决方法是去掉 --bun,让工具按其 shebang 的意图在 Node 上运行。
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.
Star on GitHub12k