跳到主要内容

Bun

Bun 是一个现代化的 JavaScript 运行时和工具包,由 Jarred Sumner 于 2021 年创建。它不仅是一个高性能的运行时,还内置了包管理器、打包器、测试运行器等工具,旨在成为 Node.js 生态的一站式替代方案。

为什么选择 Bun

Bun 的包管理器是当今最快的 JavaScript 包管理器,相比传统工具有显著优势:

极致性能

Bun 使用 Zig 语言编写,从底层优化了依赖安装过程。在标准基准测试中,Bun 安装依赖的速度比 npm 快 25 倍以上,比 pnpm 和 yarn 快 10 倍以上。这种性能提升源于以下几个方面:

  • 使用操作系统最快系统调用:macOS 上使用 clonefile,Linux 上使用 hardlink
  • 全局包缓存:已下载的包存储在全局缓存中,后续安装直接复用
  • 并行处理:依赖解析和下载并行进行
  • 延迟加载:当 bun.lock 存在且 package.json 未变化时,延迟下载缺失依赖

开箱即用

Bun 不需要额外配置就能在现有 Node.js 项目中工作。只要有 package.json,运行 bun install 即可。它完全兼容 npm 生态系统,支持:

  • package.json 中的所有字段
  • node_modules 目录结构
  • npm、yarn、pnpm 的锁文件格式(可自动迁移)
  • .npmrc 配置文件

安全优先

与 npm 不同,Bun 默认不执行依赖包的生命周期脚本(如 postinstall)。这避免了恶意代码在安装过程中执行的风险。对于需要执行脚本的包,必须显式添加到 trustedDependencies 列表中。

一体化设计

Bun 不仅是一个包管理器,还是一个完整的开发工具链:

  • 运行时:替代 Node.js,支持 TypeScript 和 JSX
  • 打包器:内置打包功能,无需 webpack 或 esbuild
  • 测试运行器:内置测试框架,兼容 Jest API
  • 包管理器:替代 npm、yarn、pnpm

安装 Bun

使用安装脚本(推荐)

# macOS 和 Linux
curl -fsSL https://bun.sh/install | bash

# Windows (PowerShell)
powershell -c "irm bun.sh/install.ps1 | iex"

使用包管理器

# 使用 npm 安装
npm install -g bun

# 使用 Homebrew (macOS)
brew install bun

# 使用 Scoop (Windows)
scoop install bun

# 使用 apt (Ubuntu/Debian)
curl -fsSL https://bun.sh/install | bash

使用 Corepack(Node.js 16.10+)

# 启用 Corepack
corepack enable

# 激活 Bun
corepack prepare bun@latest --activate

验证安装

# 查看 Bun 版本
bun --version

# 查看 Bun 安装路径
which bun

# 查看 Bun 帮助
bun --help

升级 Bun

# 升级到最新版本
bun upgrade

# 升级到指定版本
bun upgrade [email protected]

# 升级到 canary 版本
bun upgrade bun@canary

基本使用

初始化项目

# 创建 package.json
bun init

# 交互式初始化
bun init -y

# 创建特定类型的项目
bun init --help

安装依赖

# 安装所有依赖
bun install

# 简写形式
bun

# 安装生产依赖
bun add lodash

# 安装指定版本
bun add [email protected]

# 安装版本范围
bun add lodash@">=4.17.0 <5.0.0"

# 安装最新版本
bun add lodash@latest

安装不同类型的依赖

# 安装开发依赖
bun add -D jest
bun add --dev typescript

# 安装可选依赖
bun add --optional fsevents

# 安装 peer 依赖
bun add --peer react

# 安装精确版本(不使用 ^ 前缀)
bun add --exact lodash
bun add -E lodash

# 全局安装
bun add -g typescript
bun add --global prettier

删除依赖

# 删除依赖
bun remove lodash

# 删除开发依赖
bun remove -D jest

# 删除全局依赖
bun remove -g typescript

更新依赖

# 检查可更新的依赖
bun outdated

# 更新依赖
bun update

# 更新特定包
bun update lodash

# 强制更新(重新从 registry 获取最新版本)
bun update --force

平台特定依赖安装

Bun 支持覆盖原生模块的目标平台,这对于交叉编译或 CI 环境非常有用:

# 覆盖 CPU 架构
bun install --cpu=arm64
bun install --cpu=x64
bun install --cpu=ia32

# 覆盖操作系统
bun install --os=linux
bun install --os=darwin
bun install --os=win32

# 组合使用(例如为 Linux ARM64 安装依赖)
bun install --os=linux --cpu=arm64

可用值

选项接受值
--cpuarm64, x64, ia32, ppc64, s390x
--oslinux, darwin, win32, freebsd, openbsd, sunos, aix

Bun 会在锁文件中存储规范的 cpuos 值,跳过当前平台不支持的包。这意味着锁文件在不同平台/架构间保持一致,即使最终安装的包可能不同。

安全功能

最小发布年龄保护

为防止供应链攻击(恶意包快速发布),Bun 支持配置 npm 包的最小发布年龄要求:

# 要求包发布至少 1 小时后才能安装
bun install --min-release-age=3600

# 要求包发布至少 24 小时后才能安装
bun install --min-release-age=86400

或在 bunfig.toml 中配置:

[install]
minimumReleaseAge = 86400 # 24 小时

工作原理

  • 仅影响新包的解析,bun.lock 中已有的包不受影响
  • 所有依赖(直接和传递)都会被过滤
  • 当版本被年龄限制阻止时,稳定性检查会检测快速 bugfix 模式
  • 如果在年龄限制后不久发布了多个版本,会跳过这些可能不稳定的版本
  • 精确版本请求(如 [email protected])仍受年龄限制但跳过稳定性检查

可信依赖

Bun 默认不执行依赖包的生命周期脚本,这提高了安全性。对于需要执行脚本的包,必须显式声明:

{
"trustedDependencies": [
"esbuild",
"sharp",
"bcrypt"
]
}

添加可信依赖的快捷方式:

# 安装包并自动添加到 trustedDependencies
bun add --trust my-package

跳过生命周期脚本

# 跳过项目中的生命周期脚本
bun install --ignore-scripts

依赖安装策略

Bun 支持两种依赖安装策略,决定了 node_modules 的组织方式。

提升安装(Hoisted)

这是传统 npm/Yarn 的方式,将所有依赖扁平化到共享的 node_modules 目录:

# 使用提升安装策略
bun install --backend=hardlink

优点

  • 兼容性最好,大多数工具都能正常工作
  • 与现有项目无缝迁移

缺点

  • 可能出现"幽灵依赖"问题
  • 可以访问未在 package.json 中声明的依赖

隔离安装(Isolated)

这是 pnpm 风格的方式,创建严格的依赖隔离:

# 使用隔离安装策略
bun install --backend=symlink

优点

  • 防止幽灵依赖
  • 只能访问 package.json 中声明的依赖
  • 更严格的依赖管理

缺点

  • 某些工具可能不兼容

默认策略

Bun 根据项目类型自动选择默认策略:

  • 新建的 monorepo:使用 isolated 策略
  • 新建的单包项目:使用 hoisted 策略
  • 现有项目:使用 hoisted 策略(保持向后兼容)

锁文件

Bun 使用 bun.lock 作为锁文件格式。从 Bun 1.2 开始,锁文件采用文本格式,便于版本控制和差异比较。

锁文件结构

# bun.lock 示例
lockfileVersion: "1.2"
packages:
[email protected]:
resolution: {integrity: sha512-v3k...}
version: 4.17.21

历史版本

  • Bun 1.2 之前:使用二进制格式 bun.lockb
  • Bun 1.2+:使用文本格式 bun.lock

迁移旧锁文件

# 将旧的二进制锁文件迁移到新格式
bun install --save-text-lockfile --frozen-lockfile --lockfile-only

# 然后删除旧锁文件
rm bun.lockb

CI/CD 环境使用

# 使用冻结锁文件模式
bun install --frozen-lockfile

# 或使用 bun ci 命令
bun ci

工作区(Workspaces)

Bun 原生支持 monorepo 管理,通过 workspaces 字段配置。

配置工作区

{
"name": "my-monorepo",
"private": true,
"workspaces": [
"packages/*",
"apps/*",
"!**/test/**"
]
}

Glob 语法支持:Bun 支持完整的 glob 语法,包括否定模式。

目录结构

my-monorepo/
├── package.json
├── bun.lock
├── packages/
│ ├── core/
│ │ ├── package.json
│ │ └── src/
│ └── utils/
│ ├── package.json
│ └── src/
└── apps/
└── web/
├── package.json
└── src/

workspace 协议

在工作区内引用其他包:

{
"dependencies": {
"@myorg/core": "workspace:*",
"@myorg/utils": "workspace:^"
}
}
协议说明
workspace:*使用精确版本
workspace:^使用兼容版本
workspace:~使用近似版本

过滤安装

在 monorepo 中安装特定包的依赖:

# 安装特定工作区的依赖
bun install --filter @myorg/core

# 安装匹配模式的工作区
bun install --filter "./packages/*"

# 排除特定工作区
bun install --filter "!./apps/web"

运行工作区脚本

# 在特定工作区运行脚本
bun run --filter @myorg/core build

# 在所有工作区运行脚本
bun run --workspaces test

# 并行运行
bun run --workspaces --parallel test

Catalogs(目录)

当多个包需要相同的依赖版本时,Catalogs 允许在根 package.json 中定义一次版本,然后在所有工作区中引用。

配置 Catalogs

{
"catalogs": {
"default": {
"react": "^18.2.0",
"typescript": "^5.0.0",
"jest": "^29.5.0"
},
"react19": {
"react": "^19.0.0",
"react-dom": "^19.0.0"
}
}
}

使用 Catalogs

{
"dependencies": {
"react": "catalog:",
"typescript": "catalog:"
}
}

使用命名 catalog:

{
"dependencies": {
"react": "catalog:react19"
}
}

生命周期脚本

与 npm 的区别

Bun 对生命周期脚本的处理与 npm 有重要区别:

行为npmBun
执行 postinstall✗(除非在 trustedDependencies)
执行 preinstall
执行 postinstall

trustedDependencies

要允许特定包执行生命周期脚本:

{
"trustedDependencies": [
"esbuild",
"sharp",
"my-native-package"
]
}

跳过脚本

# 跳过项目中的生命周期脚本
bun install --ignore-scripts

# 依赖包的生命周期脚本永远不会执行(除非在 trustedDependencies 中)

从其他工具迁移

从 npm 迁移

Bun 完全兼容 package.jsonpackage-lock.json

# 直接运行即可
bun install

# Bun 会自动处理 package-lock.json

从 pnpm 迁移

Bun 可以自动迁移 pnpm 项目:

# Bun 检测到 pnpm-lock.yaml 时会自动迁移
bun install

# 会生成 bun.lock,原 pnpm-lock.yaml 保持不变

迁移时会处理:

  • 锁文件格式转换
  • pnpm-workspace.yaml 转换为 package.json 中的 workspaces
  • catalog: 协议保留
  • pnpm.overrides 转换为 overrides
  • pnpm.patchedDependencies 转换为 patchedDependencies

从 yarn 迁移

# Bun 可以读取 yarn.lock
bun install

# 生成 yarn.lock(可选)
bun install --yarn-lock

配置管理

bunfig.toml

Bun 使用 bunfig.toml 进行配置:

# bunfig.toml

[install]
# 设置镜像源
registry = "https://registry.npmmirror.com"

# 生产模式
production = false

# 并发设置
concurrentScripts = 10
concurrentNetwork = 48

# 锁文件设置
saveLockfile = true
frozenLockfile = false

# 生命周期脚本
ignoreScripts = false

# 安装策略
backend = "hardlink" # clonefile, hardlink, symlink, copyfile

[install.lockfile]
# 保存文本格式锁文件
save = true
print = "yarn" # 打印格式

[install.cache]
# 缓存目录
dir = "~/.bun/install/cache"
disable = false

环境变量

变量说明
BUN_CONFIG_REGISTRY设置 npm 镜像源
BUN_CONFIG_TOKEN设置认证令牌
BUN_CONFIG_YARN_LOCKFILE保存 yarn.lock
BUN_CONFIG_SKIP_SAVE_LOCKFILE不保存锁文件
BUN_CONFIG_SKIP_LOAD_LOCKFILE不加载锁文件
BUN_CONFIG_SKIP_INSTALL_PACKAGES不安装包

配置优先级

配置读取优先级从高到低:

  1. 命令行参数
  2. 环境变量
  3. 项目级 bunfig.toml
  4. 用户级 ~/.bunfig.toml
  5. 默认值

常用命令速查

命令说明
bun init初始化项目
bun install安装所有依赖
bun安装所有依赖(简写)
bun add <pkg>安装依赖
bun add -D <pkg>安装开发依赖
bun add --peer <pkg>安装 peer 依赖
bun add -g <pkg>全局安装
bun remove <pkg>删除依赖
bun update更新依赖
bun outdated检查过期依赖
bun run <script>运行脚本
bun <script>运行脚本(简写)
bun link创建本地链接
bun unlink移除本地链接
bun pm cache管理缓存
bun pm ls查看已安装依赖
bun pm bin查看可执行文件路径
bun pm hash计算依赖哈希
bun pm hash-string打印依赖哈希字符串
bun pm migrate迁移锁文件

与其他工具命令对比

操作npmpnpmyarnBun
安装依赖npm installpnpm installyarnbun install
添加依赖npm install <pkg>pnpm add <pkg>yarn add <pkg>bun add <pkg>
添加开发依赖npm install -D <pkg>pnpm add -D <pkg>yarn add -D <pkg>bun add -D <pkg>
全局安装npm install -g <pkg>pnpm add -g <pkg>yarn global add <pkg>bun add -g <pkg>
删除依赖npm uninstall <pkg>pnpm remove <pkg>yarn remove <pkg>bun remove <pkg>
更新依赖npm updatepnpm updateyarn upgradebun update
运行脚本npm run <script>pnpm run <script>yarn <script>bun <script>
执行包命令npx <cmd>pnpm dlx <cmd>yarn dlx <cmd>bunx <cmd>
CI 安装npm cipnpm install --frozen-lockfileyarn install --immutablebun install --frozen-lockfile

最佳实践

1. 使用冻结锁文件

在 CI/CD 环境中,始终使用冻结锁文件模式:

# .github/workflows/ci.yml
- name: Install dependencies
run: bun install --frozen-lockfile

2. 配置 trustedDependencies

只信任必要的包:

{
"trustedDependencies": [
"esbuild",
"sharp"
]
}

3. 使用 Catalogs 管理版本

在 monorepo 中统一管理依赖版本:

{
"catalogs": {
"default": {
"react": "^18.2.0",
"typescript": "^5.0.0"
}
}
}

4. 选择合适的安装策略

  • 新项目:使用默认策略即可
  • 严格依赖管理:使用 --backend=symlink 隔离模式
  • 兼容性要求高:使用 --backend=hardlink 提升模式

5. 配置镜像源

在国内使用镜像源加速:

# bunfig.toml
[install]
registry = "https://registry.npmmirror.com"

或使用环境变量:

BUN_CONFIG_REGISTRY=https://registry.npmmirror.com bun install

6. 安全审计

# Bun 会自动跳过可疑的生命周期脚本
# 检查已信任的依赖
bun pm ls

性能对比

以下是在相同环境下安装一个中型项目的依赖所需时间:

工具首次安装有缓存
npm~30s~10s
pnpm~15s~5s
yarn~20s~5s
Bun~1s~0.5s

Bun 的速度优势主要来自:

  1. 全局缓存:已下载的包直接复用
  2. 系统调用优化:使用操作系统最快的文件操作
  3. 并行处理:依赖解析和下载并行进行
  4. 懒加载:只在需要时下载缺失依赖

了解更多