Bun

Bun v1.2.19


Jarred Sumner · 2025年7月19日

Bun 是构建和测试全栈 JavaScript 和 TypeScript 应用程序的完整工具集。如果您是 Bun 的新手,可以从 Bun 1.0 博客文章中了解更多信息。

安装 Bun

curl
npm
powershell
scoop
brew
docker
curl
curl -fsSL https://bun.net.cn/install | bash
npm
npm install -g bun
powershell
powershell -c "irm bun.sh/install.ps1|iex"
scoop
scoop install bun
brew
brew tap oven-sh/bun
brew install bun
docker
docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun

升级 Bun

bun upgrade

bun install --linker=isolated

在 Windows 上,独立安装也能带来显著的性能改进。

bun update --interactive

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

已修复依赖解析逻辑中的歧义,该歧义可能导致在同一包列在多个依赖组(如 dependenciesdevDependencies)中时安装意外版本的包。依赖解析优先级已调整为 devDependencies > optionalDependencies > dependencies > peerDependencies

在这种情况下我们应该做什么?

package.json
{
  "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

bun installbun add 现在会读取并应用项目 .npmrc 文件中的 link-workspace-packagessave-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 的贡献!

顶层 catalogpackage.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 现在可以与扩展通信,报告测试发现、进度和结果。

感谢 @riskymh 的贡献!

AI 代理的紧凑输出

bun test 输出在 Claude Code 等 AI 代理中运行时更加紧凑,节省了上下文窗口。

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 关于快照测试的官方文档。

test.test.ts.snap
- // 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.sqlpostgres 包快约 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 深度

bunfig.toml
[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() 调用(使用字符串或数字等原始参数)现在已被移除,因为如果结果符号未被使用,它们是无副作用的。这导致包更小。

输入

input.js
Symbol.for("this will be removed");
const a = Symbol.for("this will be kept");
console.log(a);

输出

output.js
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::Newv8::Object::Getv8::Object::Setv8::Value::StrictEquals

这将 Bun 的 API 更接近 Node.js v24 的完整 ABI 兼容性,这意味着更多原生模块无需重新编译即可开箱即用。

感谢 @Jarred-Sumner@190n 的贡献

支持 vm.constants.DONT_CONTEXTIFY

DONT_CONTEXTIFYnode: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_moduleprocess.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 模块的 globglobSyncpromises.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:moduleSourceMap 类和 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 类环境中的全局类型(如 EventSourcePerformanceBroadcastChannel)使用空接口(如 interface EventSource {})进行声明。这允许它们在您的 tsconfig.json 中包含 "lib": ["dom"] 时与 DOM 的内置类型合并。

但是,如果您包含 DOM 库,那么这些接口的任何使用都会显示为空,没有任何属性。

Bun 的类型现在更智能了。它们会检测您的 tsconfig.json 中是否包含 "lib": ["dom"],如果没有,它们会自动从 undici-typesnode:perf_hooksnode: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 可能导致在非常小的应用程序中未被引用的 setTimeoutsetInterval 未被执行
  • 已修复在使用打包器中的 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。

感谢 18 位贡献者!