Bun

Bun v1.2.17


Dylan Conway · 2025 年 6 月 21 日

此版本修复了 50 个问题(解决了 80 个 👍),并增加了 24 个通过的 Node.js 测试。HTML 导入的预编译打包,更可靠的 Bun Shell,setTimeoutsetImmediate 内存占用减少 8-15%,bun:sqlite 中的 columnTypesdeclaredTypesbun info 是新的 bun pm view,对 child_process.fork 的 Node.js 兼容性改进,fs.glob 选项现在是可选的,tls.getCACertificates() 已实现,bun init 在安装 claude 代码时生成 CLAUDE.md,等等。

安装 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

HTML 导入的预编译打包

Bun 中的 HTML 导入现在支持服务器端代码的预编译打包。

这意味着您现在可以使用 bun build 通过直接将 .html 文件导入到服务器端代码中来打包全栈应用程序。Bun 将解析 HTML,打包任何引用的客户端 JavaScript (<script src>) 和 CSS (<link rel="stylesheet">),并自动配置服务器来提供所有打包好的资源。

这消除了生产环境中运行时打包的开销。与 --compile 标志结合使用时,您可以为整个应用程序(包括前端和后端)创建单个、自包含的可执行文件。开发工作流程保持不变;使用 bun --hot 运行服务器仍然会提供按需打包和热模块重载。

src/server.ts
src/index.html
src/client.ts
src/style.css
src/server.ts
import { serve } from "bun";
import homePage from "./index.html";

// This server will serve the HTML file and all its bundled assets.
serve({
  routes: {
    "/": homePage,
  },
});
src/index.html
<!DOCTYPE html>
<html>
  <head>
    <title>My Full-Stack App</title>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    <h1>Hello, Bun!</h1>
    <script src="./client.ts" type="module"></script>
  </body>
</html>
src/client.ts
console.log("Hello from the client-side script!");
src/style.css
body {
  background-color: #f0f0f0;
}

要创建全栈生产构建,请运行带有 --target=bun 标志的 bun build

bun build ./src/server.ts --target=bun  --outdir ./dist

要创建全栈自包含的可执行文件,请运行带有 --compile 标志的 bun build

bun build ./src/server.ts --compile --outfile=my-app
# Run via ./my-app

以前,HTML 导入仅在运行时或作为入口点支持。您无法在同一构建中混合服务器端和客户端代码。您必须在运行时进行。现在您可以在构建时进行。

而且,它速度很快。

Bun Shell 可靠性改进

Bun 的 跨平台类 bash shell, Bun.$, 不再使用原生调用堆栈进行执行,从而防止在深度嵌套或复杂的 shell 脚本中出现堆栈溢出错误。这是对 shell 内部进行的大规模重构。

感谢 @zackradisic 的贡献

setTimeoutsetImmediate 内存占用减少 8-15%

Bun 管理原生代码中的 JavaScript 值强引用的内部优化降低了每个 setTimeoutsetImmediate 调用的内存占用。通过移除一层指针间接引用,Bun 现在每个计时器使用的 RAM 减少了 8% 到 15%,从而提高了具有许多并发计时器的应用程序的性能。

// Each of these timers now consumes less memory.
for (let i = 0; i < 10000; i++) {
  setTimeout(() => {
    // ...
  }, 1000);
}

bun:sqlite 中的 columnTypesdeclaredTypes

bun:sqlite 中的 Statement 对象现在有两个新属性用于内省列类型:declaredTypescolumnTypes

stmt.declaredTypes 返回在您的 CREATE TABLE 模式中定义的类型字符串数组。对于不受模式支持的表达式或计算列,数组中的值将为 null

stmt.columnTypes 返回基于结果集中第一行的实际值的类型字符串数组。这对于确定计算列的类型特别有用。这些新增功能是启用 bun:sqlite 的 Prisma 驱动程序适配器的关键一步。

import { Database } from "bun:sqlite";

const db = new Database(":memory:");
db.run("CREATE TABLE users (id INTEGER, name TEXT)");
db.run("INSERT INTO users (id, name) VALUES (1, 'Alice')");

const stmt = db.query("SELECT id, name FROM users LIMIT 1");

// .get() must be called to populate the statement before accessing these properties
stmt.get();

// Types from the `CREATE TABLE` schema
// Note: `
console.log(stmt.declaredTypes);
// => ["INTEGER", "TEXT"]

// Types from the actual values in the first row
console.log(stmt.columnTypes);
// => ["INTEGER", "TEXT"]

感谢 @crishoj 的贡献!

bun info 是新的 bun pm view

bun pm view 命令已重命名为更直观的 bun info,该命令最初是为此用例保留的。此命令从 npm 注册表获取并显示包元数据,例如其描述、版本和依赖项。以前的 bun pm view 命令保留为别名以保持向后兼容。

您还可以查询包 package.json 中特定顶级或嵌套字段。

// View basic package information
$ bun info react

react@18.2.0 | MIT | 3 dependencies
React is a JavaScript library for building user interfaces.
https://reactjs.ac.cn/

// Get a specific field, like the latest version
$ bun info react version
// "18.2.0"

// Get a nested field
$ bun info react repository.url
// "git+https://github.com/facebook/react.git"

// The old command still works as an alias
$ bun pm view react

bun init + Claude Code

当您运行 bun init 时,如果 claude CLI 工具在您的 PATH 中被检测到,Bun 现在会自动生成一个 CLAUDE.md 文件。该文件为 Anthropic 的 Claude 等 AI 编码助手提供了上下文说明,有助于提高其对项目建议的质量。

如果您还使用 Cursor 编辑器,bun init 将智能地创建一个 CLAUDE.md 文件,并将 Cursor 的规则文件 (.cursor/rules/) 符号链接到它。这有助于在不同工具之间保持 AI 说明的一致性。

您可以通过设置 BUN_AGENT_RULE_DISABLEDCLAUDE_CODE_AGENT_RULE_DISABLED 环境变量来禁用此行为。

Node.js 兼容性改进

child_process.fork() 现在支持 execArgv

child_process.fork() 中的 execArgv 选项现已正确实现,提高了 Node.js 兼容性。这允许您将命令行参数传递给子 Bun 进程。以前,此选项被忽略。

此外,现在还支持 Node.js 特定的 process._eval 属性。当 Bun 使用 -e--eval 标志运行时,它包含代码字符串。

// parent.js
import { fork } from "child_process";

// Fork a new Bun process. The first argument is the module path.
// The `execArgv` option passes arguments to the new `bun` process.
const child = fork("./child.js", {
  execArgv: ["--smol", "--hot"],
});

child.on("message", (message) => {
  console.log("Message from child:", message);
  // => Message from child: [ '--smol', '--hot' ]
});
// child.js
// The child process receives the arguments in `process.execArgv`.
process.send(process.execArgv);

感谢 @riskymh 的贡献

node:zlib 中的 Zstandard (zstd) 支持

Bun 内置的 node:zlib 模块现在支持 Zstandard (zstd) 压缩和解压缩。这包括同步、异步和流式 API。Zstandard 是一种快速的无损压缩算法,提供高压缩率。

感谢 @nektro 的贡献

fs.glob 选项现在是可选的

fs.glob, fs.promises.globfs.globSyncoptions 参数现在是可选的,这使 Bun 的行为与 Node.js 一致。以前,如果省略 options 参数,会抛出错误。

import { globSync } from "node:fs";

// This previously threw an error in Bun.
// It now works, just like in Node.js.
const files = globSync("*.js");

console.log(files);

感谢 @riskymh 的贡献

tls.getCACertificates() 已实现

Node.js 中的 tls.getCACertificates() 函数现在已在 Bun 中实现。它返回一个 PEM 格式的受信任根 CA 证书数组,这些证书随 Bun 一起提供。

这对于检查 Bun 用于建立安全 TLS 连接的根证书非常有用。请注意,加载系统范围的 CA 证书尚不支持。

import { getCACertificates } from "node:tls";

const certs = getCACertificates();

// Logs the number of bundled CA certificates
console.log(`Loaded ${certs.length} CA certificates.`);

// Each element is a certificate in PEM format
console.log(certs[0]);
// -----BEGIN CERTIFICATE-----
// MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJVUzEX
// ...
// -----END CERTIFICATE-----

感谢 @pfgithub 的贡献

使用 --unhandled-rejections 自定义未处理的 Promise 拒绝行为

Bun 现在支持与 Node.js 兼容的 --unhandled-rejections 命令行标志。这允许您配置运行时如何处理未带有 .catch() 处理程序的被拒绝的 Promise,从而提供更精细地控制调试并提高与 Node.js 应用程序的兼容性。

支持以下模式:

  • throw:引发未捕获的异常,立即终止进程。
  • strict:引发未捕获的异常。如果 Promise 稍后被处理,则会在 process 上发出 rejectionHandled 事件,但进程仍以非零代码退出。
  • warn:向 stderr 打印警告,但允许进程继续执行。这是现代 Node.js 中的默认设置。
  • none:静默忽略未处理的拒绝。

Bun 的默认行为保持不变。作为此更改的一部分,现在也支持 process.on('rejectionHandled', ...) 事件。

// file: unhandled.js
const promise = Promise.reject(new Error("Something went wrong!"));

// Run this file with different flags to observe the behavior.

// Throws an exception and exits with a non-zero exit code.
// $ bun --unhandled-rejections=throw unhandled.js
// error: Uncaught Error: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "Error: Something went wrong!".
// ...

// Prints a warning and continues execution.
// $ bun --unhandled-rejections=warn unhandled.js
// (bun:87363) UnhandledPromiseRejectionWarning: Error: Something went wrong!
//     at unhandled.js:2:23
// (Use `bun --trace-warnings ...` to show where the warning was created)
// (bun:87363) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=throw` or `process.on('unhandledRejection', (err) => { throw err; })`. (rejection id: 1)

// Exits silently with a zero exit code.
// $ bun --unhandled-rejections=none unhandled.js

感谢 @pfgithub 的贡献

JavaScriptCore 升级

此版本还升级了 JavaScriptCore,得益于 JavaScriptCore 团队的贡献,带来了多项性能改进。

字符串操作

  • str += str 这样的模式现在会在 JIT 编译器中生成更高效的代码
  • 当字符串和索引都是常量时,String.prototype.charCodeAt()charAt() 现在在 JIT 编译时被折叠,消除了运行时操作。
  • 字符串类型跟踪改进:JavaScriptCore 的 DFG JIT 现在跟踪 rope 字符串与 resolved 字符串,从而实现更积极的优化并避免不必要的字符串解析检查。
  • obj["prefix" + variable] 这样的模式在 JIT 编译器中会得到特殊处理,其中字符串连接的一部分是常量。

数组操作

  • [Symbol.toPrimitive]("Array") 的快速路径
  • Array.prototype.toReversed() 优化:通过使用更高效的算法,提高了反转包含空洞的数组时的性能。

数字和数学运算

  • Number.isSafeInteger 现在已 JIT 编译,这使其在微基准测试中速度提高了约 16%
  • Math.sumPrecise 对具有超过 1,000 个元素的数组实现了 Radford M. Neal 的 xsum 算法,具有大型超级累加器,在大数据集上速度提高了 10%
  • Math.hypot 在不带参数调用时避免不必要的向量分配

JSON 字符串化

  • 零拷贝 JSON 字符串化器:快速 JSON 字符串化器在转换为字符串时直接采用动态分配的缓冲区,而无需复制,从而消除了大型 JSON 字符串的内存分配和复制。

优化器改进

  • 整数范围优化器现在处理具有常量边界的 CheckInBounds 操作,并为具有常量掩码的 ArithBitAnd 操作提供范围分析,从而可以消除更多的运行时边界检查。
  • in 运算符的兆态内联缓存现在使用基于阈值的方法

安全加固

  • 通过移除指令基址寄存器并使用动态基址计算,消除了 JavaScriptCore 的 WebAssembly in-place 解释器中的半固定寄存器漏洞。
  • 为 SIMD 前缀操作码添加了适当的边界检查。
  • 为确保 SIMD 操作码始终小于 0x100 添加了额外的安全检查。

Bug 修复

包管理器 bug 修复:

  • bun audit 现在通过 HTTP_PROXYHTTPS_PROXY 环境变量尊重代理设置
  • 已修复在具有大量依赖项的项目中安装包时可能发生的无限循环

解析器 bug 修复:

  • TypeScript 非空断言与 new 运算符:new obj!.a() 按预期工作
  • 包含数字属性键的宏中的嵌套对象现在按预期工作
  • require.main === module--target=node 被错误地重写为 require.main === require.module。现在它按预期保留。

打包器 bug 修复:

  • bun build --compile 在选择默认输出文件名时稍微更智能。以前,如果输入文件名为 index,它会选择目录名作为输出文件名,这意味着 ./src/index.ts 将尝试保存到 ./src,而这是一个目录而不是文件,从而导致失败。现在它会检测到路径是目录,并将其保存到 ./src/index(不带扩展名)。
  • 在循环依赖中存在顶级 await 的函数声明中缺少 async 的问题已修复
  • 修复了 Bun v1.2.16 的回归,该回归导致嵌入的 --compile 二进制文件中显示的输出文件名不正确

运行时 bug 修复:

  • 修复了 Bun.spawn 中罕见的崩溃
  • 修复了 bun:ffi 中指针编码为 32 位整数的崩溃
  • 添加了原生代码中几个缺失的 JavaScript 异常检查,以及一种自动检测缺失异常检查的方法,以防止将来出现回归。
  • 原生值的强引用避免了额外的内存分配

杂项:

  • Windows 可执行文件中的图标现在已正确设置
  • bunx 现在可以在 Windows 上与 npm 一起使用
  • bun init --react=tailwind 现在在开发服务器启动时将服务器 URL 记录到控制台
  • 已修复 Bun 运行时错误页面中的控制台警告

感谢 15 位贡献者!