运行时包管理器打包器测试运行器代码检查格式化指南参考博客反馈

bun install

使用 Bun 的快速包管理器安装包

基本用法

terminal
bun install react
bun install react@19.1.1 # 指定版本
bun install react@latest # 指定标签

bun CLI 包含一个兼容 Node.js 的包管理器,旨在以显著更快的速度替代 npm、yarn 和 pnpm。它是一个独立工具,可在现有的 Node.js 项目中运行;如果你的项目中有 package.json,就可以使用 bun install。

针对 Linux 用户

建议使用的最低 Linux 内核版本是 5.6。如果你使用的是 Linux 内核 5.1 到 5.5,bun install 能工作,但 HTTP 请求会较慢,因为缺少对 io_uring 的 connect() 操作支持。

如果你使用的是 Ubuntu 20.04,可以通过以下方式安装新版内核:

terminal
# 如果返回版本号 >= 5.6,则无需操作
uname -r

# 安装 Ubuntu 官方硬件支持内核
sudo apt install --install-recommends linux-generic-hwe-20.04

安装项目中所有依赖:

terminal
bun install

bun install:

  • 安装所有 dependencies、devDependencies 和 optionalDependencies。Bun 默认会安装 peerDependencies。
  • 运行项目的 {pre|post}install 和 {pre|post}prepare 脚本,并在适当的时机执行。出于安全考虑,除非已将已安装的依赖项标记为可信,否则 Bun _不会执行_它们的生命周期脚本。
  • 写入一个 bun.lock 锁文件到项目根目录。

日志记录

调整日志详情级别:

terminal
bun install --verbose # 调试日志
bun install --silent  # 静默无日志

生命周期脚本

与其他 npm 客户端不同,Bun 不会执行安装依赖的任意生命周期脚本(如 postinstall)。执行任意脚本存在潜在安全风险。

若需允许 Bun 针对特定包执行生命周期脚本,请在你的 package.json 中将该包添加到 trustedDependencies 字段。

package.json
{
  "name": "my-app",
  "version": "1.0.0",
  "trustedDependencies": ["my-trusted-package"] // [!code ++]
}

然后重新安装该包。Bun 会读取此字段并运行 my-trusted-package 的生命周期脚本。

生命周期脚本会在安装期间并行运行。若要调整并发脚本的最大数量,请使用 --concurrent-scripts 标志。默认值为报告的 CPU 数量的两倍或 GOMAXPROCS。

terminal
bun install --concurrent-scripts 5

Bun 会自动优化热门包(如 esbuild 和 sharp)的 postinstall 脚本,确定哪些脚本需要运行。要禁用这些优化:

terminal
BUN_FEATURE_FLAG_DISABLE_NATIVE_DEPENDENCY_LINKER=1 bun install
BUN_FEATURE_FLAG_DISABLE_IGNORE_SCRIPTS=1 bun install

工作区(Workspaces)

Bun 支持 package.json 中的 "workspaces"。请参阅工作区。

package.json
{
  "name": "my-app",
  "version": "1.0.0",
  "workspaces": ["packages/*"], // [!code ++]
  "dependencies": {
    "preact": "^10.5.13"
  }
}

为特定包安装依赖

在 monorepo 中,可以通过 --filter 参数针对部分包安装依赖。

terminal
# 为除了 `pkg-c` 之外的所有工作区安装依赖
bun install --filter '!pkg-c'

# 仅为 `./packages/pkg-a` 中的 `pkg-a` 安装依赖
bun install --filter './packages/pkg-a'

请参阅筛选。


覆盖与解析

Bun 支持 package.json 中 npm 的 "overrides" 和 Yarn 的 "resolutions"。两者都为_元依赖_(即你的依赖项的依赖项)指定版本范围。请参阅覆盖与解析。

package.json
{
  "name": "my-app",
  "dependencies": {
    "foo": "^2.0.0"
  },
  "overrides": { // [!code ++]
    "bar": "~4.4.0" // [!code ++]
  } // [!code ++]
}

全局安装包

要全局安装包,请使用 -g/--global 标志。使用它来安装命令行工具。

terminal
bun install --global cowsay # 或 `bun install -g cowsay`
cowsay "Bun!"
Text
 ______
< Bun! >
 ------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

生产模式

要以生产模式安装(不包含 devDependencies):

terminal
bun install --production

--production 等同于 --frozen-lockfile。它只控制要安装的内容。先前安装时已经在 node_modules 中的 devDependencies 会继续保留。使用 bun prune --production 将它们移除。

如需可复现安装,请使用 --frozen-lockfile。Bun 会安装锁文件中指定的确切版本,并且不会更新锁文件。如果你的 package.json 与 bun.lock 不一致,Bun 会以错误退出。

terminal
bun install --frozen-lockfile

Bun 不会在 CI 中自动启用 --frozen-lockfile;请传入该标志或使用 bun ci。如果完全不存在锁文件,--frozen-lockfile 会从 package.json 安装,但不会写入锁文件。

--frozen-lockfile 可用于经过精简的 monorepo 检出目录(例如 turbo prune 的输出,或只复制了部分工作区文件夹的 Docker 上下文)。如果 bun.lock 中列出的工作区在磁盘上缺少 package.json,Bun 会跳过它,并显示 note:,且不会安装其专属依赖。如果剩余的工作区依赖于被跳过的工作区,安装将失败。

如需在不安装的情况下验证锁文件,请使用 bun install --frozen-lockfile --dry-run。

离线安装

使用已预热的缓存时,bun install 可以在没有网络的情况下运行:

terminal
# 无论缓存数据的时间有多旧,都使用缓存的软件包元数据;仅获取缓存中缺少的内容
bun install --prefer-offline

# 完全不访问网络(注册表、tarball URL、git);未缓存的必需依赖会导致错误
bun install --offline

--prefer-offline 也是 bunfig.toml 中 install.prefer = "offline" 所选择的选项;install.offline = true 是 --offline 的配置形式。使用完整的还原缓存时,--offline --frozen-lockfile 可让 CI 安装完全确定且无需网络;而 --prefer-offline 仍会获取缓存中缺少的内容。

安装只能确保缓存放入 node_modules 中的软件包。要为 --offline 安装预热缓存,请在同一平台上运行安装,并至少放入相同的软件包。使用 --production 或 --omit 的安装不会缓存被省略的分组。

有关 bun.lock 的更多信息,请参阅锁文件。


省略依赖

若要省略开发、对等或可选依赖,请使用 --omit 标志。

terminal
# 从安装中排除 "devDependencies"。同时适用于根包和工作区(若存在)。传递依赖不会拥有 devDependencies。
bun install --omit dev

# 仅安装 "dependencies"
bun install --omit=dev --omit=peer --omit=optional

演练模式

要执行演练而不安装任何内容:

terminal
bun install --dry-run

非 npm 依赖

Bun 支持从 Git、GitHub 以及本地或远程托管的 tarball 安装依赖。请参阅 bun add。

package.json
{
  "dependencies": {
    "dayjs": "git+https://github.com/iamkun/dayjs.git",
    "lodash": "git+ssh://github.com/lodash/lodash.git#4.17.21",
    "moment": "git@github.com:moment/moment.git",
    "zod": "github:colinhacks/zod",
    "react": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
    "bun-types": "npm:@types/bun"
  }
}

安装策略

Bun 支持两种包安装策略,决定依赖如何组织在 node_modules 中:

扁平安装(Hoisted installs)

传统 npm/Yarn 方式,将依赖扁平化合并到共享的 node_modules 目录:

terminal
bun install --linker hoisted

隔离安装(Isolated installs)

一种类似 pnpm 的方式,可创建严格的依赖隔离,以防止幻影依赖:即无需在 package.json 中声明就可以导入的包:

terminal
bun install --linker isolated

隔离安装会在 node_modules/.bun/ 创建中央包存储,并在顶层 node_modules 中使用符号链接,确保包只能访问声明的依赖。

默认策略

默认链接器策略依据是否是新项目或已有项目:

  • 新工作区/monorepo:isolated(防止幻影依赖)
  • 新单包项目:hoisted(传统 npm 行为)
  • 旧项目(v1.3.2 之前创建):hoisted(保留向后兼容)

锁文件中的 configVersion 字段会控制默认值。详细说明请参阅隔离安装。


最小发布年龄

为防范恶意软件包被快速发布所导致的供应链攻击,你可以为 npm 软件包配置最低发布时间要求。Bun 会在安装过程中筛除发布时间距今少于指定阈值(以秒为单位)的软件包版本。

terminal
# 只安装至少三天前发布的版本
bun add @types/bun --minimum-release-age 259200 # 秒

也可以在 bunfig.toml 配置:

bunfig.toml
[install]
# 最低发布时间为三天
minimumReleaseAge = 259200 # 秒

# 排除信任包绕过年龄检测
minimumReleaseAgeExcludes = ["@types/node", "typescript"]

启用最小年龄过滤时:

  • 它只影响新的软件包解析;bun.lock 中已有的软件包保持不变
  • Bun 会在解析依赖时过滤所有依赖(直接依赖和传递依赖),以满足年龄要求
  • 当年龄门槛阻止某些版本时,稳定性检查会检测快速修复缺陷的发布模式
    • 如果多个版本在刚刚超出年龄门槛时接连发布,Bun 会扩大过滤范围,跳过这些可能不稳定的版本,并选择更旧、更成熟的版本
    • 检查会在年龄门槛之后最多搜索 7 天;如果这段时间内仍有频繁发布,Bun 会忽略稳定性检查
    • 精确版本请求(如 package@1.1.1)仍会遵守年龄门槛,但会绕过稳定性检查
  • Bun 会将没有 time 字段的版本视为通过年龄检查(npm 注册表应始终提供时间戳)

如需更高级的安全扫描,包括与服务集成和自定义过滤,请参阅安全扫描器 API。


配置

通过 bunfig.toml 配置 bun install

在执行 bun install、bun remove 和 bun add 时,Bun 会在以下位置查找 bunfig.toml:

  1. $XDG_CONFIG_HOME/.bunfig.toml 或 $HOME/.bunfig.toml
  2. 当前目录下的 ./bunfig.toml

如果 Bun 找到这两个文件,就会同时加载。项目的 bunfig.toml 中设置的键会覆盖全局文件中的同名键。

通过 bunfig.toml 进行配置是可选的。以下是默认值:

bunfig.toml
[install]

# 是否安装 optionalDependencies
optional = true

# 是否安装 devDependencies
dev = true

# 是否安装 peerDependencies
peer = true

# 等同于 `--production`
production = false

# 等同于 `--save-text-lockfile` 标志
saveTextLockfile = true

# 等同于 `--frozen-lockfile`
frozenLockfile = false

# 等同于 `--dry-run`
dryRun = false

# 等同于 `--concurrent-scripts`
concurrentScripts = 16 # CPU 核心数或 GOMAXPROCS 的 2 倍

# 安装策略:"hoisted" 或 "isolated"
# 默认依赖于锁文件 configVersion 和是否使用工作区:
# - configVersion = 1:若使用工作区则为 "isolated",否则为 "hoisted"
# - configVersion = 0:"hoisted"
linker = "hoisted"

# 最小发布时间配置
minimumReleaseAge = 259200 # 秒
minimumReleaseAgeExcludes = ["@types/node", "typescript"]

通过环境变量配置

环境变量的优先级高于 bunfig.toml。

名称描述
BUN_CONFIG_REGISTRY设置 npm 注册表(默认值:https://registry.npmjs.org)
BUN_CONFIG_TOKEN为默认注册表设置身份验证令牌
BUN_CONFIG_YARN_LOCKFILE保存 Yarn v1 风格的 yarn.lock
BUN_CONFIG_SKIP_SAVE_LOCKFILE不保存锁文件
BUN_CONFIG_SKIP_LOAD_LOCKFILE不加载锁文件
BUN_CONFIG_SKIP_INSTALL_PACKAGES不安装任何软件包

Bun 会在目标平台上使用可用的最快安装方式:在 macOS 上使用 clonefile,在 Linux 和 Windows 上使用 hardlink。你可以通过 --backend 标志更改安装方式。如果 clonefile 和 hardlink 不可用或出错,则会回退到平台特定的文件复制实现。

Bun 会将从 npm 安装的软件包存储在 ~/.bun/install/cache/${name}@${version} 中。如果 semver 版本包含 build 或 pre 标签,Bun 会将其替换为该值的哈希。这可以降低因文件路径过长而导致错误的可能性,但会使确定软件包在磁盘上的安装位置变得更加复杂。

当 node_modules 文件夹存在时,Bun 会通过检查预期 node_modules 位置中的 package.json 里的 "name" 和 "version" 是否与预期的软件包名称和版本匹配,来决定是否安装软件包。Bun 使用自定义 JSON 解析器,在找到 "name" 和 "version" 后就会停止解析。

当不存在 bun.lock,或者 package.json 中的软件包依赖发生变化时,Bun 会在解析过程中立即下载并提取 tarball。

当存在 bun.lock 且 package.json 未发生变化时,Bun 会延迟下载缺失的依赖。如果 node_modules 中的预期位置已存在名称和版本匹配的软件包,Bun 就不会尝试下载 tarball。

CI/CD

在 GitHub Actions 中使用官方 oven-sh/setup-bun 动作安装 Bun:

.github/workflows/release.yml
name: bun-types
jobs:
  build:
    name: build-app
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4
      - name: Install bun
        uses: oven-sh/setup-bun@v2
      - name: Install dependencies
        run: bun install
      - name: Build app
        run: bun run build

对于要求可复现构建的 CI/CD 环境,可用 bun ci 确保 package.json 与锁文件同步,不符时构建失败:

terminal
bun ci

bun ci 等同于 bun install --frozen-lockfile。它会从 bun.lock 安装确切版本;如果 package.json 与锁文件不匹配,则会失败。若要使用 bun ci 或 bun install --frozen-lockfile,必须将 bun.lock 提交到版本控制系统。

在工作流中运行 bun ci,而不是 bun install:

.github/workflows/release.yml
name: bun-types
jobs:
  build:
    name: build-app
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4
      - name: Install bun
        uses: oven-sh/setup-bun@v2
      - name: Install dependencies
        run: bun ci
      - name: Build app
        run: bun run build

平台特定依赖?

Bun 会将 npm 中规范化的 cpu 和 os 值连同已解析的软件包存储在锁文件中。运行时会跳过为当前目标平台禁用的软件包的下载、提取和安装。这意味着即使最终安装的软件包有所变化,不同平台/架构上的锁文件也不会改变。

--cpu 和 --os 参数

你可以覆盖目标平台进行包选择:

bash
bun install --cpu=x64 --os=linux

这些标志会为指定的平台安装包,而不是当前系统。你可以在跨平台构建,或为不同环境准备部署内容时使用它们。

--cpu 的可接受值:arm、arm64、ia32、mips、mipsel、ppc、ppc64、s390、s390x、x32、x64

--os 的可接受值:aix、darwin、freebsd、linux、openbsd、sunos、win32、android

对等依赖?

Bun 像 Yarn 一样处理对等依赖:bun install 会自动安装它们。如果该依赖在 peerDependenciesMeta 中被标记为可选,Bun 会尽可能使用现有的依赖。

锁文件

bun.lock 是 Bun 的锁文件格式。请参阅我们关于文本锁文件的博客文章。

在 Bun 1.2 之前,锁文件采用二进制格式,名为 bun.lockb。要将旧锁文件升级为新格式,请运行 bun install --save-text-lockfile --frozen-lockfile --lockfile-only,然后删除 bun.lockb。

缓存

删除缓存:

bash
bun pm cache rm
# 或
rm -rf ~/.bun/install/cache

平台特定后端

为了提升性能,bun install 会根据平台使用不同的系统调用来安装依赖。你可以使用 --backend 标志强制指定后端。

hardlink 是 Linux 和 Windows 上的默认后端。基准测试表明,它在 Linux 上速度最快。

bash
rm -rf node_modules
bun install --backend hardlink

clonefile 是 macOS 默认后端,性能最好,仅 macOS 可用。

bash
rm -rf node_modules
bun install --backend clonefile

clonefile_each_dir 与 clonefile 类似,但会按目录逐个克隆文件。它仅在 macOS 上可用,运行速度通常比 clonefile 慢。与 clonefile 不同,clonefile_each_dir 不会通过一次系统调用递归克隆子目录。

bash
rm -rf node_modules
bun install --backend clonefile_each_dir

copyfile 是上述后端失败时使用的回退方案,速度最慢。在 macOS 上,它使用 fcopyfile();在 Linux 上,它使用 copy_file_range()。

bash
rm -rf node_modules
bun install --backend copyfile

symlink 通常仅在内部用于 file: 依赖(例如 file:../foo 和传递的 file: 依赖)。link: 依赖不会使用此后端;Bun 会将它们安装为指向链接目录的单个符号链接。

若用 --backend=symlink 安装,除非每个依赖都有自己的 node_modules,否则 Node.js 不会正确解析依赖的 node_modules,除非对 node 或 bun 使用 --preserve-symlinks 参数。详见 Node.js 关于 --preserve-symlinks 文档。

bash
rm -rf node_modules
bun install --backend symlink
bun --preserve-symlinks ./my-file.js
node --preserve-symlinks ./my-file.js # https://nodejs.org/api/cli.html#--preserve-symlinks

npm 注册表元数据

Bun 使用二进制格式缓存 npm 注册表响应。与 JSON 相比,这种格式的加载速度快得多,且磁盘占用通常更小。这些文件位于 ~/.bun/install/cache/*.npm。文件名格式为 ${hash(packageName)}.npm。文件名使用哈希,这样 Bun 就不需要为作用域包创建额外目录。

Bun 使用 Cache-Control 时会忽略 Age。这可以提升性能,但意味着 Bun 获取的 npm 最新软件包版本元数据可能会滞后约 5 分钟。

pnpm 迁移

Bun 会自动迁移 pnpm 项目。当 Bun 检测到 pnpm-lock.yaml 文件且不存在 bun.lock 文件时,会在安装过程中将锁文件转换为 bun.lock。原始的 pnpm-lock.yaml 文件保持不变。

terminal
bun install

仅当不存在 bun.lock 时才会运行迁移。目前没有用于禁用 pnpm 迁移的选项。

迁移内容:

锁文件迁移

  • 将 pnpm-lock.yaml(锁文件版本 7–9,包括 pnpm 11 的多文档文件)转换为 bun.lock
  • 保留已解析的版本和完整性哈希
  • 保留对等依赖范围和 peerDependenciesMeta,因此下一次 bun install 不会更改迁移后的锁文件
  • 迁移 git、GitHub、tarball URL、file: 和 npm: 别名依赖,包括传递依赖
  • 通过 pnpm-workspace.yaml 中的 namedRegistries 解析 pnpm 命名注册表(name@registry:version)
  • 将注入的工作区包(dependenciesMeta.*.injected)转换为普通工作区依赖
  • 处理已修补的依赖,将 pnpm 仅包含哈希的 patchedDependencies 条目与补丁文件进行匹配
  • 跳过 runtime: 条目(由 pnpm 管理的 Node.js 版本),并显示警告

工作区配置

检测到 pnpm-workspace.yaml 时,将工作区配置迁移至根 package.json:

pnpm-workspace.yaml
packages:
  - "apps/*"
  - "packages/*"

catalog:
  react: ^18.0.0
  typescript: ^5.0.0

catalogs:
  build:
    webpack: ^5.0.0
    babel: ^7.0.0

Bun 会将工作区包列表和 catalog 迁移至 package.json 中的 workspaces 字段:

package.json
{
  "workspaces": {
    "packages": ["apps/*", "packages/*"],
    "catalog": {
      "react": "^18.0.0",
      "typescript": "^5.0.0"
    },
    "catalogs": {
      "build": {
        "webpack": "^5.0.0",
        "babel": "^7.0.0"
      }
    }
  }
}

目录依赖

Bun 会保留使用 pnpm catalog: 协议的依赖:

package.json
{
  "dependencies": {
    "react": "catalog:",
    "webpack": "catalog:build"
  }
}

配置迁移

Bun 会从 pnpm-lock.yaml 和 pnpm-workspace.yaml 中迁移以下 pnpm 配置:

  • overrides 从 pnpm.overrides 迁移至 package.json 根级 overrides
  • patchedDependencies 从 pnpm.patchedDependencies 迁移至 package.json 根级 patchedDependencies
  • workspace overrides 应用自 pnpm-workspace.yaml 至根 package.json

要求和限制

  • 要求 pnpm 锁文件版本为 7 或更高
  • 工作区包的 package.json 中必须包含 name 字段
  • 依赖引用的所有 catalog 条目都必须存在于 catalogs 定义中
  • pnpm-lock.yaml 中的每个工作区都必须在磁盘上有对应的 package.json(在 Docker 中,请在运行 bun install 之前将其复制进去)
  • 不支持相对路径的 link: 依赖,以及带有子目录(resolution.path)的 git 依赖
  • 如果迁移因上述任一原因失败,Bun 会打印原因,并改为从头开始解析

迁移完成后,可以安全删除 pnpm-lock.yaml 和 pnpm-workspace.yaml。


CLI 用法

terminal
bun install <name>@<version>

通用配置

--configstring

指定配置文件路径(bunfig.toml)

--cwdstring

设置特定的当前工作目录

依赖范围与管理

--productionboolean

不安装 devDependencies

--no-saveboolean

不更新 package.json 也不保存锁文件

--savebooleandefault true

保存到 package.json

--omitstring

从安装中排除「dev」、「optional」或「peer」依赖

--only-missingboolean

仅当依赖不存在于 package.json 中时才添加

依赖类型与版本控制

--devboolean

添加依赖到 "devDependencies"

--optionalboolean

添加依赖到 "optionalDependencies"

--peerboolean

添加依赖到 "peerDependencies"

--exactboolean

添加确切版本,而不是使用 ^ 范围

锁文件控制

--yarnboolean

写入 yarn.lock 文件(yarn v1)

--frozen-lockfileboolean

不允许修改锁文件

--save-text-lockfileboolean

保存基于文本的锁文件

--lockfile-onlyboolean

仅生成锁文件,不安装依赖

网络与注册表设置

--castring

提供证书颁发机构(CA)签名证书

--cafilestring

证书颁发机构签名证书的文件路径

--registrystring

默认使用指定注册表,覆盖 .npmrc、bunfig.toml 和环境变量

安装过程控制

--dry-runboolean

解析依赖,但不安装软件包、不更新 package.json,也不保存锁文件(项目自身的生命周期脚本仍会运行)

--forceboolean

总是从注册表请求最新版本并重新安装所有依赖

--globalboolean

全局安装

--backendstring

平台特定的优化:"clonefile"、"hardlink"、"symlink"、"copyfile"

--filterstring

为匹配的工作区安装包

--analyzeboolean

递归分析并安装作为参数传入的文件的所有依赖

缓存选项

--cache-dirstring

从特定目录路径存储和加载缓存数据

--no-cacheboolean

完全忽略清单缓存

输出与日志记录

--silentboolean

不输出任何日志

--verboseboolean

过度详细的日志输出

--no-progressboolean

禁用进度条

--no-summaryboolean

不打印摘要

安全与完整性

--no-verifyboolean

跳过新下载包的完整性验证

--trustboolean

添加至项目 package.json 的 trustedDependencies 并安装包

并发与性能

--concurrent-scriptsnumber

生命周期脚本的最大并发任务数(默认:CPU 核心数的 2 倍)

--network-concurrencynumberdefault 48

最大并发网络请求数

生命周期脚本管理

--ignore-scriptsboolean

跳过所有软件包的生命周期脚本,包括项目的 package.json 和受信任的依赖项

帮助信息

--helpboolean

打印此帮助菜单