2.1 为什么 bun install 这么快
- 并行下载——用 Zig 的 async IO 同时发起几十个 HTTPS 连接。
- 全局缓存 + binlink——包只下载一次,全系统共享;项目的 node_modules 里用 hardlink/symlink 引用,不复制文件。
- 优化过的 JSON 解析器——npm 花大量时间解析大 package-lock.json;Bun 用 Zig 原生 JSON 解析快得多。
- 跳过无用工作——检测到锁文件没变就不重新求解依赖图。
效果对比(中等项目 500 依赖)
npm install 30s
pnpm install 8s
yarn install 12s
bun install 1.2s
2.2 基础命令
$ bun install # 安装 package.json 全部依赖
$ bun i # 别名
$ bun add react # 加依赖
$ bun add react@19 # 指定版本
$ bun add -d vitest # devDependencies
$ bun add -g typescript # 全局安装
$ bun add --peer react # peerDependencies
$ bun add --optional fsevents # optionalDependencies
$ bun remove react # 移除
$ bun update # 按 semver 范围升级
$ bun update react # 只升一个
$ bun outdated # 查看有更新的包
2.3 锁文件:bun.lock / bun.lockb
Bun 有两种锁文件:
- bun.lock(v1.1.33+ 默认)
- JSON 文本格式,人类可读、diff 友好、审计方便。推荐。
- bun.lockb(早期默认)
- 二进制格式,压缩后体积小、解析更快,但 git diff 不可读。旧项目里常见。
新项目会默认生成 bun.lock。从 lockb 迁过来:
$ bun install --save-text-lockfile # 产出 bun.lock 并删除 .lockb
2.4 CI 推荐:--frozen-lockfile
$ bun install --frozen-lockfile
等价 npm 的 npm ci:
- lockfile 与 package.json 不一致就报错退出
- 不更新 lockfile
- 适合 CI 保证"锁文件即真理"
2.5 Workspace(Monorepo)
Bun 原生支持 pnpm 风格的 workspace。根目录 package.json:
{
"name": "my-monorepo",
"private": true,
"workspaces": ["packages/*", "apps/*"]
}
my-monorepo/
├── package.json # 根(上面那份)
├── bun.lock # 整个 monorepo 一份锁文件
├── packages/
│ ├── ui/
│ │ └── package.json # "name": "@myorg/ui"
│ └── utils/
│ └── package.json # "name": "@myorg/utils"
└── apps/
└── web/
└── package.json # 依赖 "@myorg/ui": "workspace:*"
# apps/web/package.json
{
"dependencies": {
"@myorg/ui": "workspace:*"
}
}
workspace:* 协议告诉 Bun"用本 monorepo 内的版本"——符号链接而非从 npm 下载。
跨 workspace 命令
$ bun install # 根目录跑,装所有 workspace
$ bun --filter '@myorg/*' run build # 跑匹配 workspace 的 build
$ bun --filter web run dev # 只跑 web 的 dev
2.6 trustedDependencies:postinstall 脚本白名单
默认情况下,Bun 不会执行依赖包里的 postinstall 脚本——这是供应链安全考量(恶意包可能利用 postinstall 搞事)。
需要某些包的 postinstall(如 esbuild、sharp、Electron 原生模块)时,在 package.json 里显式授权:
{
"trustedDependencies": [
"esbuild",
"sharp",
"electron"
]
}
为何这是安全的默认
2021 年 ua-parser-js、2022 年 colors/faker 事件都是通过 postinstall 执行恶意代码。Bun 逆转默认:除非你明确信任,否则所有 postinstall 都被跳过。
2.7 私服与 scope
# bunfig.toml 或 ~/.bunfig.toml
[install]
registry = "https://registry.npmmirror.com" # 国内镜像
[install.scopes]
"@my-org" = { url = "https://npm.company.com", token = "$NPM_TOKEN" }
"@internal" = "https://npm.company.com"
[install.cache]
dir = "~/.bun/install/cache"
disable = false
[install.lockfile]
save = true
print = "yarn" # 同时输出一份 yarn.lock 便于兼容
2.8 Peer Dependency 处理
Bun 默认:
- 安装 peerDependencies(与 npm 7+ 一致)
- 版本冲突时警告而不中止
不想自动安装 peerDeps:
[install]
peer = false
2.9 bun pm:补充工具
$ bun pm ls # 列出已安装包的树
$ bun pm ls --all # 含间接依赖
$ bun pm cache # 缓存目录
$ bun pm cache rm # 清缓存
$ bun pm trust <pkg> # 添加到 trustedDependencies
$ bun pm trust --default # 信任所有(危险)
$ bun pm untrusted # 列出被阻止的 postinstall 脚本
$ bun pm why lodash # 解释为什么装了这个包
2.10 与 npm/pnpm 的兼容性
| 项 | bun |
|---|---|
| package.json | 100% 兼容 |
| npm registry | ✅ |
| .npmrc | 部分(建议迁到 bunfig.toml) |
| pnpm-workspace.yaml | 不支持(用 package.json 的 workspaces 字段) |
| pnpm overrides | 支持 overrides 字段 |
| yarn.lock / package-lock.json | 首次 bun install 会读一次然后生成 bun.lock |
2.11 小结
- bun install 比 npm 快 25 倍,100% 兼容 package.json 和 npm registry。
- bun.lock(文本)推荐——新项目默认、diff 友好。
- workspace 用
workspaces+workspace:*协议 +--filter。 - postinstall 默认禁用,用
trustedDependencies白名单;这是默认的安全边界。 - CI 用
--frozen-lockfile;国内镜像改 bunfig.toml。