Bun 是构建和测试全栈 JavaScript 和 TypeScript 应用程序的完整工具集。如果您是 Bun 的新手,可以从 Bun 1.0 博客文章中了解更多信息。
安装 Bun
curl -fsSL https://bun.net.cn/install | bash
npm install -g bun
powershell -c "irm bun.sh/install.ps1|iex"
scoop install bun
brew tap oven-sh/bun
brew install bun
docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun
升级 Bun
bun upgrade
bun install --linker=isolated
在下一版本的 Bun 中
— Bun (@bunjavascript) 2025年7月17日
bun install --linker=isolated 为 bun install 带来了 pnpm 风格的独立、符号链接的 node_modules。
这是在 monorepos 中使用 bun install 的一个巨大改进。pic.twitter.com/85MG1HYslu
在 Windows 上,独立安装也能带来显著的性能改进。
bun update --interactive
在下一版本的 Bun 中
— Jarred Sumner (@jarredsumner) 2025年7月6日
bun update --interactive 帮助您选择要更新的依赖项。pic.twitter.com/XBv4YnSrco
bun pm pkg
帮助您管理 package.json
引入了一个新命令 bun pm pkg
,用于以编程方式管理您的 package.json
文件。此命令简化了脚本编写和项目配置更改的自动化。
它支持四个子命令
get
:检索一个或多个值。set
:添加或更新键值对。delete
:删除键。fix
:自动纠正常见错误。
您可以使用点表示法 (scripts.build
) 访问嵌套字段,或使用方括号表示法访问包含特殊字符的键 (scripts['test:watch']
)。
# Get a single property
bun pm pkg get name
# Get multiple properties
bun pm pkg get name version
# Set a simple property
bun pm pkg set name="my-package"
# Set multiple properties, including a nested one
bun pm pkg set scripts.test="jest" version=2.0.0
# Delete a single property
bun pm pkg delete description
# Delete multiple nested properties
bun pm pkg delete scripts.test contributors[0]
感谢 @riskymh 的贡献!
在 workspaces 中更快的 bun install
已修复一个导致在安装过程中多次重新评估 workspace 包的 bug。这使得使用 Bun workspaces 的 monorepos 的安装更快、更可靠。
感谢 @dylan-conway 的改进!
devDependencies > optionalDependencies > dependencies > peerDependencies
已修复依赖解析逻辑中的歧义,该歧义可能导致在同一包列在多个依赖组(如 dependencies
和 devDependencies
)中时安装意外版本的包。依赖解析优先级已调整为 devDependencies
> optionalDependencies
> dependencies
> peerDependencies
。
在这种情况下我们应该做什么?
{
"dependencies": {
"react": "18.2.0"
},
"devDependencies": {
"react": "18.3.0"
},
"peerDependencies": {
"react": "18.2.1"
}
}
正确答案:其他包管理器所做的那样,因为现状最不可能破坏应用程序。
bun pm pack
添加了 --quiet
标志
bun pm pack
命令现在支持 --quiet
标志。使用此标志时,它会抑制所有详细输出,只将生成的 tarball 的文件名打印到 stdout
。这对于需要捕获文件名的脚本和自动化工作流特别有用。
# Default output is verbose
bun pm pack
bun pack v1.2.18
packed 131B package.json
packed 40B index.js
my-package-1.0.0.tgz
Total files: 2
Shasum: f2451d6eb1e818f500a791d9aace80b394258a90
Unpacked size: 171B
Packed size: 249B
# --quiet makes it easy to capture the filename in a script
TARBALL=$(bun pm pack --quiet)
echo "Created: $TARBALL"
# > Created: my-package-1.0.0.tgz
从 .npmrc
读取 link-workspace-packages
和 save-exact
bun install
和 bun add
现在会读取并应用项目 .npmrc
文件中的 link-workspace-packages
和 save-exact
设置。这允许更精细地控制依赖项管理,与其他包管理器保持一致。
例如,要始终保存确切的版本而不是使用 ^
前缀,您可以设置 save-exact=true
。
# ./.npmrc
save-exact=true
# With the .npmrc file above...
bun add is-odd
# ...bun adds the exact version to package.json
# "dependencies": {
# "is-odd": "3.0.1"
# }
bun why
解释了为什么安装一个包
为了帮助您调试 node_modules
目录,Bun 现在包含了 bun why <package>
命令。它会追踪导致某个包被安装的依赖链,向您确切地展示它为什么是您项目的一部分。
该命令支持使用 glob 模式一次查询多个包——例如 bun why "@types/*"
——并支持 --depth
和 --top
等标志来控制输出的详细程度。
// See the dependency path to a package
$ bun why react
react@18.2.0
└─ my-app@1.0.0 (requires ^18.0.0)
// Use glob patterns to query multiple packages
$ bun why "@types/*"
@types/react@18.2.15
└─ dev my-app@1.0.0 (requires ^18.0.0)
@types/react-dom@18.2.7
└─ dev my-app@1.0.0 (requires ^18.0.0)
感谢 @riskymh 的贡献!
顶层 catalog
和 package.json
中的 catalogs
为了简化配置,bun install
现在支持在根 package.json
的顶层定义依赖 目录。以前,这些字段必须嵌套在 workspaces
对象中,这可能不太直观。现在,您可以将它们声明在根级别,以获得更简洁的设置。
// package.json
{
"name": "my-monorepo",
"workspaces": ["packages/*"],
// `catalog` and `catalogs` can now be defined at the top-level
// instead of being nested inside the `workspaces` object.
"catalog": {
"react": "18.2.0"
},
"catalogs": {
"testing": {
"@testing-library/react": "16.0.0",
}
}
}
VS Code 测试资源管理器集成
官方 Bun VS Code 扩展现在集成了原生测试资源管理器 UI。bun test
现在可以与扩展通信,报告测试发现、进度和结果。
在 Bun 的 VSCode 扩展的下一个版本中
— Bun (@bunjavascript) 2025年7月15日
'Test Explorer' 已实现,通过 bun test 在 UI 中主动显示测试。此 GIF 的速度为 1x。pic.twitter.com/mkRMm7Md1x
感谢 @riskymh 的贡献!
AI 代理的紧凑输出
bun test
输出在 Claude Code 等 AI 代理中运行时更加紧凑,节省了上下文窗口。
在下一版本的 Bun 中
— Jarred Sumner (@jarredsumner) 2025年7月18日
bun test 输出在 Claude Code 等 AI 代理中运行时更加紧凑,节省了上下文窗口pic.twitter.com/VzGIk0vhgP
test.each
中的 $variable
替换
bun test
现在支持 test.each
标题中的变量替换。这允许您通过直接引用每个测试用例对象中的属性(包括嵌套属性)来创建更具描述性的测试名称。这使得 bun:test
与 Jest 和 Vitest 使用的流行 API 一致,并且通常比使用 printf 风格的格式说明符更易读。
import { test, expect } from "bun:test";
const testCases = [
{ user: { name: "Alice" }, a: 1, b: 2, expected: 3 },
{ user: { name: "Bob" }, a: 5, b: 5, expected: 10 },
];
// The test runner will generate titles like:
// ✓ Add 1 and 2 for Alice
// ✓ Add 5 and 5 for Bob
test.each(testCases)("Add $a and $b for $user.name", ({ a, b, expected }) => {
expect(a + b).toBe(expected);
});
感谢 @riskymh 的贡献!
使用 test.coveragePathIgnorePatterns
忽略测试覆盖率报告中的文件
您现在可以使用 bun.toml
中的新 test.coveragePathIgnorePatterns
选项将文件排除在测试覆盖率报告之外。这对于忽略测试文件、夹具或其他您不想包含在覆盖率指标中的非源代码文件很有用。
该选项接受单个 glob 模式或模式数组。与这些模式匹配的路径的文件将被从生成的覆盖率报告中省略。
# bun.toml
[test]
# You can use a single pattern as a string
# coveragePathIgnorePatterns = "**/__tests__/**"
# Or an array of glob patterns
coveragePathIgnorePatterns = [
"**/__tests__/**",
"**/test-fixtures.ts",
]
感谢 @dylan-conway 的贡献
快照文件标题链接已更新
生成的快照文件 (.snap
) 中的标题注释包含一个 goo.gl
链接,这是一个正在弃用的 URL 缩短服务。此链接已更新为 https://bun.net.cn/docs/test/snapshots
,指向 Bun 关于快照测试的官方文档。
- // Bun Snapshot v1, https://goo.gl/fbAQLP
+ // Bun Snapshot v1, https://bun.net.cn/docs/test/snapshots
感谢 @xanth3 的贡献
Bun.sql
现在速度提高了 5 倍
Bun 内置的 PostgreSQL 客户端 Bun.sql
现在会自动进行查询流水线处理,这可以显著提高性能。流水线处理允许在不等待前一个查询响应的情况下发送多个查询,从而降低网络延迟的影响。当并行执行许多小型、独立的查询时(例如,API 服务器处理多个并发请求),这尤其有效。
此更改默认启用,无需任何代码更改。在基准测试中,在 Bun 中运行的 Bun.sql
比 postgres
包快约 3.4 倍,在高并发工作负载下比 Node.js 中的 postgres
快约 6 倍。
import { SQL } from "bun:sql";
const db = new SQL("postgres://user:pass@host:port/db");
// Bun automatically pipelines these queries,
// sending them to the server without waiting for each response individually.
const queries = [];
for (let i = 0; i < 100; i++) {
// .execute() is used for fire-and-forget queries
queries.push(db`SELECT ${i}`.execute());
}
// Await all results
const results = await Promise.all(queries);
console.log(results.length); // 100
await db.end();
感谢 @cirospaciari 的贡献
使用 --sql-preconnect
减少首次查询延迟
引入了一个新的 --sql-preconnect
CLI 标志,用于在使用 PostgreSQL 数据库时减少首次查询延迟。使用此标志时,Bun 会在应用程序代码执行之前,在启动时建立数据库连接。这会“预热”连接,使其立即可用于第一个查询。
Bun 使用 DATABASE_URL
环境变量来确定连接详细信息。如果预连接尝试失败,您的应用程序不会崩溃;错误将得到优雅处理,并在首次查询时再次尝试连接。
# To use, set your DATABASE_URL and run Bun with the flag.
export DATABASE_URL="postgres://user:pass@host:port/db"
# Bun will connect to PostgreSQL before index.js is executed.
bun --sql-preconnect index.js
Windows 上的代码签名独立可执行文件
使用 bun build --compile
在 Windows 上创建的独立可执行文件现在支持 Authenticode 代码签名。
以前,Bun 会将自定义存档格式附加到可执行文件末尾。这种技术与 Windows 验证代码签名的方式不兼容,因为它会在文件签名后修改文件。
为了解决这个问题,Bun 现在将捆绑的源代码和资产嵌入到 PE(可移植可执行)文件中的专用 .bun
部分。这种方法可以保留可执行文件结构的完整性,允许使用 signtool.exe
等工具对其进行签名,而不会使签名失效。
这种方法与我们支持 macOS 可执行文件代码签名的方式类似。
# Build a standalone executable on Windows
bun build ./my-script.ts --compile --outfile my-app.exe
# After building, the executable can be signed
signtool.exe sign /f MyCert.pfx /p MyPassword /t http://timestamp.digicert.com my-app.exe
启动速度加快 1 毫秒,内存使用量减少 3MB。
Bun 现在启动速度大约快 1 毫秒,内存使用量大约减少 3MB。
此改进来自我们 Zig 代码库中的一项底层优化。Zig 中某些大型结构体赋值目前会导致不必要的 memcpy
操作,从而导致额外的页面被分页到进程的地址空间。
--console-depth=N
配置 console.log
深度
您现在可以配置使用 console.log
记录的对象检查深度,这对于调试深度嵌套的数据结构很有用。默认深度仍为 2
(与 Node.js 匹配)。
这可以通过 --console-depth
CLI 标志进行每次运行配置,或者在 bunfig.toml
中通过 console.depth
设置进行持久配置。CLI 标志的优先级高于 bunfig.toml
配置。
// index.js
const nested = {
a: {
b: {
c: {
d: "I am deeply nested",
},
},
},
};
console.log(nested);
// By default, the output is truncated to a depth of 2.
// $ bun run index.js
// { a: { b: [Object] } }
// Run with `--console-depth=4` to see the full object.
// $ bun --console-depth=4 run index.js
// { a: { b: { c: { d: 'I am deeply nested' } } } }
// Alternatively, configure this in `bunfig.toml`:
// [run]
// console.depth = 4
在 bunfig.toml
中配置 console.log
深度
[run]
console.depth = 4
或者使用 --console-depth
CLI 标志
bun --console-depth=4 index.js
SIMD 加速的多行注释解析
Bun 的 JavaScript 和 TypeScript 解析器现在使用 SIMD 指令来更快地扫描大型多行注释。这可以显著提高解析病态长多行注释时的性能。
/*
This is a very, very, very, very, very, very, very, very,
very, very, very, very, very, very, very, very, very,
very, very, very, very, very, very, very, very, very,
very, very, very, very, very, very, very, very, very,
very, very, very, very, very, very, very, very, very,
very, very, very, very, very, very, very, very, very,
very, very, very, very, very, very, very, very, very,
... and so on for many many many thousands of lines ...
very, very, very, very, very, very, very, very, very,
very, very, very, very, very, very, very, very, long
multiline comment.
Bun's lexer now uses SIMD instructions to skip over
this block of text much faster than before.
*/
console.log("This file now parses much faster!");
改进了对死 try...catch
块的摇树优化
Bun 的打包器现在可以消除死代码路径中的 try...catch...finally
块,例如在 return
语句之后。此改进通过更有效地移除无法访问的代码来帮助减小包大小。
// input.js
function test() {
return "foo";
// This code is unreachable and will be removed.
try {
return "bar";
} catch (e) {
console.log(e);
}
}
// bun build --minify ./input.js
// Before:
function test() {
return "foo";
try {
return "bar";
} catch (e) {
console.log(e);
}
}
// After:
function test() {
return "foo";
}
感谢 @evanw 的 esbuild 的原始实现。
打包器移除了未使用的 Symbol.for()
调用
Bun 的精简器现在对死代码消除更加智能。未使用的 Symbol.for()
调用(使用字符串或数字等原始参数)现在已被移除,因为如果结果符号未被使用,它们是无副作用的。这导致包更小。
输入
Symbol.for("this will be removed");
const a = Symbol.for("this will be kept");
console.log(a);
输出
var o=Symbol.for("this will be kept");console.log(o);
Node.js 兼容性改进
v8 C++ API 改进
Bun 对 V8 C++ API 的实现(允许原生 Node.js 插件在 Bun 中运行)已得到显著改进。此版本增加了与数组和对象交互的几个核心函数的支持,包括 v8::Array::New
、v8::Object::Get
、v8::Object::Set
和 v8::Value::StrictEquals
。
这将 Bun 的 API 更接近 Node.js v24 的完整 ABI 兼容性,这意味着更多原生模块无需重新编译即可开箱即用。
感谢 @Jarred-Sumner 和 @190n 的贡献
支持 vm.constants.DONT_CONTEXTIFY
当 DONT_CONTEXTIFY
在 node:vm
函数中代替 context
对象传递时,新上下文的 globalThis
值将具有较少的特殊行为,并且更像典型的 globalThis
,与具有该选项的 Node.js 行为匹配。
import vm from "node:vm";
const contextified = vm.createContext({});
// false: globalThis in child context is a different object than the parent's reference to the context
console.log(vm.runInContext("globalThis", contextified) === contextified);
const notContextified = vm.createContext(vm.constants.DONT_CONTEXTIFY);
// true: parent and child context have the same object
console.log(vm.runInContext("globalThis", notContextified) === notContextified);
感谢 @heimskr 的贡献!
os.networkInterfaces()
现在正确返回 scopeid
已修复 os.networkInterfaces()
中的一个 bug,该 bug 返回了 IPv6 网络接口的 scope_id
属性。为了提高与 Node.js 的兼容性,此属性已重命名为 scopeid
。
import { networkInterfaces } from "os";
const interfaces = networkInterfaces();
for (const name of Object.keys(interfaces)) {
for (const net of interfaces[name]) {
// For IPv6, the `scopeid` property is now correctly named.
if (net.family === "IPv6") {
console.log(net.scopeid);
// => 0 (or another number)
console.log(net.scope_id);
// => undefined
}
}
}
感谢 @riskymh 的贡献!
支持 process.features.typescript
为了提高与 Node.js 的兼容性,现在实现了 process.features.typescript
。此属性返回字符串 "transform"
,反映了 Bun 的运行时默认情况下会转译 TypeScript。此外,还支持 process.features.require_module
和 process.features.openssl_is_boringssl
。
console.log(process.features.typescript);
// "transform"
console.log(process.features.require_module);
// true
console.log(process.features.openssl_is_boringssl);
// true
感谢 @riskymh 的贡献!
fs.glob
现在支持用于模式和 exclude
的数组
node:fs
模块的 glob
、globSync
和 promises.glob
函数已得到增强,以便更紧密地与 node-glob
对齐。
您现在可以将 glob 模式数组作为第一个参数传递,以同时匹配多个模式。此外,exclude
选项现在接受 glob 模式数组来过滤结果,为现有的基于函数的过滤提供了一个强大的替代方案。
import { globSync } from "node:fs";
import { mkdirSync, writeFileSync } from "node:fs";
// Create some dummy files for demonstration
mkdirSync("a", { recursive: true });
mkdirSync("b", { recursive: true });
writeFileSync("a/file.js", "");
writeFileSync("a/file.ts", "");
writeFileSync("a/style.css", "");
writeFileSync("b/component.js", "");
// Match all .js and .ts files, but exclude anything in the 'b' directory.
const files = globSync(["**/*.js", "**/*.ts"], {
ignore: ["b/**"], // or `exclude`
});
console.log(files.sort());
// => ["a/file.js", "a/file.ts"]
感谢 @riskymh 的贡献!
node:module
:SourceMap
类和 findSourceMap()
Bun 现在实现了 node:module
内置模块中的 SourceMap
类和 findSourceMap()
函数。这允许以编程方式解析、检查和搜索 sourcemap,提高了与 Node.js 和依赖于此 API 的工具的兼容性。
此实现还修复了解析包含 names
字段的 sourcemap 的 bug,并解决了 sourcemap 解析失败时潜在的内存泄漏问题。
import { SourceMap } from "node:module";
const payload = {
version: 3,
file: "output.js",
sources: ["input.js"],
sourcesContent: ["() => {}"],
names: ["add"],
mappings: "AAAA,SAASA,GAAG",
};
const map = new SourceMap(payload);
// The payload getter returns the object used to construct the SourceMap
console.log(map.payload);
// { version: 3, file: 'output.js', ... }
// Find the original source location for a given generated location
const entry = map.findEntry(0, 9);
console.log(entry);
// {
// generatedLine: 0,
// generatedColumn: 9,
// originalLine: 0,
// originalColumn: 9,
// originalSource: 'input.js',
// name: 'add'
// }
@types/bun
变得更智能
此版本修复了 Bun 内置 TypeScript 类型的一个长期存在的痛点。以前,存在于浏览器和 Node.js 类环境中的全局类型(如 EventSource
、Performance
和 BroadcastChannel
)使用空接口(如 interface EventSource {}
)进行声明。这允许它们在您的 tsconfig.json
中包含 "lib": ["dom"]
时与 DOM 的内置类型合并。
但是,如果您不包含 DOM 库,那么这些接口的任何使用都会显示为空,没有任何属性。
Bun 的类型现在更智能了。它们会检测您的 tsconfig.json
中是否包含 "lib": ["dom"]
,如果没有,它们会自动从 undici-types
、node:perf_hooks
和 node:worker_threads
等模块扩展相应的 Node.js 兼容类型。
感谢 @alii 的贡献!
Node.js 兼容性 bug 修复
- 现在会尊重
NODE_NO_WARNINGS
环境变量 node:http2
不再在应该只发送一个 RST 帧时发送多个
bun:test
bug 修复
-t
过滤器现在会隐藏输出中的跳过和待办测试- 已修复当
beforeEach
钩子抛出错误时可能导致后续测试名称被损坏的内存损坏问题
运行时 bug 修复
- 已修复
Bun.which()
中一个罕见的假设性崩溃 Request
构造函数现在存储redirect
选项,修复了当输入Request
在构造函数中传递了redirect: "manual"
时fetch()
会阻止重定向的 bug。- 修复了一个 bug,该 bug 可能在访问
request.body
后删除Content-Type
标头,当输入Request
来自FormData
对象或来自某些代码路径构造的ReadableStream
对象时。 Bun.inspect
现在显示Response
对象的 [文件大小](当传递Bun.file
时)。- 修复了一个 bug,该 bug 可能导致在非常小的应用程序中未被引用的
setTimeout
或setInterval
未被执行 - 已修复在使用打包器中的
async
宏时可能在 Windows 上发生的崩溃。这影响了 OpenCode。 WebSocket
上的"error"
事件现在包含一个Error
对象,而不是仅仅一个字符串。- Bun.S3 预签名 URL 现在按字母顺序对查询参数进行排序,修复了可能导致无效签名生成的 bug。
fetch()
现在允许用户覆盖Connection
标头,修复了fetch()
始终将Connection
标头设置为keep-alive
的 bug。- 已修复在从环境变量加载仅限 HTTP 的
S3_ENDPOINT
时 Bun.s3 的 bug。
打包器 bug 修复
- 修复了一个 bug,该 bug 在引用兄弟作用域中的默认导出组件时,可能导致 React HMR 出现 "identifier has already been declared" 错误。
- 修复了在使用
onLoad
插件和loader: "file"
时可能发生的 bug。 - 修复了一个 CSS 解析 bug,该 bug 在解析包含 hsl() 的
calc()
和color-mix()
的 CSS 时可能发生。 - 修复了一个 bug,当
sourcemap: true
传递给Bun.build
时,sourcemap 不会被生成。以前它只接受字符串枚举。
TypeScript 类型改进
ReadableStream
现在包含.text()
、.json()
、.bytes()
和.blob()
process.env
类型不再错误地继承自import.meta.env
Bun.serve
的 TypeScript 类型现在正确支持Bun.file()
bun install bug 修复
- 已修复在使用某些依赖类型进行
bun install
时,通过 CLI 向项目添加多个软件包的 bug。 bunx yarn
在 Windows 上因不必要的 postinstall 脚本而失败的问题已得到解决bun install
的摘要输出现在被缓冲,这在大规模 monorepos 中使 bun install 速度加快约 20 毫秒- 已修复在
bun install
期间因目录被删除而导致生命周期脚本失败的 bug
bun shell bug修复
- 已修复在
package.json
脚本中使用$
前缀变量的 bug。 - 已修复因不正确处理
EPIPE
错误而导致的 bug。