运行时包管理器打包器测试运行器代码检查格式化指南参考博客反馈

贡献

贡献给 Bun

配置 Bun 的开发环境可能需要 10 到 30 分钟,具体取决于您的网络连接和计算机速度。您需要大约 10GB 的可用磁盘空间用于存储仓库和构建产物。

如果您使用的是 Windows,请参阅构建 Windows。

使用 Nix(可选方案)

该仓库包含一个 Nix flake,可作为手动安装依赖的替代方案:

bash
nix develop
bun bd

nix develop 会在无需 sudo 的情况下,在隔离且可复现的环境中提供所有依赖。

安装依赖(手动)

使用系统的包管理器安装 Bun 的依赖:

macOS
brew install automake ccache cmake coreutils gnu-sed go icu4c libiconv libtool ninja pkg-config rustup-init ruby
Ubuntu/Debian
sudo apt install curl wget lsb-release software-properties-common cmake git golang libtool ninja-build pkg-config ruby-full xz-utils
Arch
sudo pacman -S base-devel cmake git go libiconv libtool make ninja pkg-config python rustup sed unzip ruby
Fedora
sudo dnf install clang23 llvm23 lld23 cmake git golang libtool ninja-build pkg-config ruby libatomic-static libstdc++-static sed unzip which libicu-devel 'perl(Math::BigInt)'
openSUSE
sudo zypper install go cmake ninja automake git icu rustup

Bun 使用 Rust 编写,需要特定的 nightly 工具链(已固定在 rust-toolchain.toml 中)。请使用 rustup 安装 Rust,而不是使用发行版提供的 rust/cargo 软件包——构建脚本会使用 rustup 自动安装并更新已固定的 nightly 工具链:

bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

开始之前,请安装 Bun 的发布版本:构建过程会使用 Bun 的打包器来转换和压缩代码,并运行代码生成脚本。

Native
curl -fsSL https://bun.sh/install | bash
npm
npm install -g bun
Homebrew
brew tap oven-sh/bun
brew install bun

可选:安装 ccache

ccache 会缓存编译产物,从而加快重新构建的速度:

bash
# macOS
brew install ccache

# Ubuntu/Debian
sudo apt install ccache

# Arch
sudo pacman -S ccache

# Fedora
sudo dnf install ccache

# openSUSE
sudo zypper install ccache

如果 ccache 可用,构建脚本会自动检测并使用它。使用 ccache --show-stats 检查缓存统计信息。

安装 LLVM

Bun 需要 LLVM 23.1.1(clang 是 LLVM 的一部分)。构建系统会强制使用此版本:版本不匹配会导致运行时内存分配失败。在大多数情况下,您可以通过系统包管理器安装 LLVM:

macOS
brew install llvm@23
Ubuntu/Debian
# LLVM has an automatic installation script that is compatible with all versions of Ubuntu
wget https://apt.llvm.org/llvm.sh -O - | sudo bash -s -- 23 all
Arch
sudo pacman -S llvm clang lld
Fedora
sudo dnf install llvm clang lld-devel
openSUSE
sudo zypper install clang23 lld23 llvm23

如果以上方法都不起作用,请手动安装。

确保 Clang/LLVM 23 位于您的路径中:

bash
which clang-23

如果没有,请手动添加:

macOS
# use fish_add_path if you're using fish
# use path+="$(brew --prefix llvm@23)/bin" if you are using zsh
export PATH="$(brew --prefix llvm@23)/bin:$PATH"
Arch
# use fish_add_path if you're using fish
export PATH="$PATH:/usr/lib/llvm23/bin"

构建 Bun

克隆仓库后,运行以下命令进行构建。此过程可能需要一段时间:它会下载并构建依赖项。

bash
bun run build

二进制文件位于 ./build/debug/bun-debug。建议将其添加到 $PATH 中。要验证构建是否成功,请输出其版本:

bash
build/debug/bun-debug --version
x.y.z_debug

VSCode

VSCode 是用于开发 Bun 的推荐 IDE;仓库中已包含相应配置。打开仓库后,运行 Extensions: Show Recommended Extensions 以安装 Rust 和 C++ 的推荐扩展。rust-analyzer 会自动识别工作区中的 Cargo.toml,并使用 rust-toolchain.toml 中固定的工具链进行分析,因此诊断结果会与构建结果一致。

如果您使用其他编辑器,请将 rust-analyzer(或编辑器的 Rust 插件)指向仓库根目录——Cargo 工作区和 rust-toolchain.toml 会自动被识别。

推荐将 ./build/debug 添加到您的 $PATH,这样就可以在终端中直接运行:

shell
bun-debug

运行调试构建

bd package.json 脚本会编译并运行 Bun 的调试构建,仅在失败时打印构建过程输出。

shell
bun bd <args>
bun bd test foo.test.ts
bun bd ./foo.ts

完整的调试构建在 Rust 或 C++ 发生更改时可能需要几分钟;cargo 的增量编译会让后续仅 Rust 的重建快得多。如果您的开发流程是“改一行、保存、重建”,您仍然会在等待链接步骤上花费太多时间。相反:

  • 批量进行更改
  • 使用 cargo check -p <crate>(或对整个工作区使用 bun run rust:check)在不链接的情况下对 Rust 更改进行类型检查。bun run watch 会在每次保存时运行 cargo check。
  • 确保 rust-analyzer 正在运行,以获取行内诊断信息(推荐的 VSCode 扩展集会自动完成设置)
  • 优先使用调试器(VSCode 中的“CodeLLDB”)逐步执行代码。
  • 使用调试日志。BUN_DEBUG_<scope>=1 会为相应的 declare_scope!(<scope>, ...) / scoped_log!(<scope>, ...) 日志启用调试记录。设置 BUN_DEBUG_QUIET_LOGS=1 可禁用所有未明确启用的调试日志。要将调试日志转储到文件中,请设置 BUN_DEBUG=<path-to-file>.log。发布构建会移除调试日志。
  • src/js/**/*.ts 的更改几乎会立即完成重建。单 crate 的 Rust 更改和 C++ 更改都支持增量构建;只有最终链接无法避免。

代码生成脚本

当某些文件发生变化时,Bun 的构建流程会自动运行多个代码生成脚本:

  • ./src/codegen/generate-jssink.ts -- 生成 build/debug/codegen/JSSink.cpp、build/debug/codegen/JSSink.h,用于实现与 ReadableStream 交互的各种类。这些代码是 FileSink、ArrayBufferSink、"type": "direct" 流以及其他流相关代码在内部的实现方式。
  • ./src/codegen/generate-classes.ts -- 为用 Rust 实现的 JavaScriptCore 类生成 Rust 和 C++ 绑定。**/*.classes.ts 文件定义类、方法、原型以及 getter/setter 的接口;代码生成器读取这些接口,生成用于在 C++ 中实现 JavaScript 对象并将其与 Rust 连接起来的样板代码。
  • ./src/codegen/cppbind.ts -- 扫描标记有导出属性的 C++ 绑定,并为它们生成自动的 Rust FFI 包装器(cpp.rs)。
  • ./src/codegen/bundle-modules.ts -- 将 node:fs、bun:ffi 等内置模块打包到最终二进制文件所包含的文件中。在开发过程中,这些模块可以在不重新构建原生代码的情况下重新加载(仍然需要运行 bun run build,但之后它会重新从磁盘读取转译后的文件)。在发布版本中,这些模块会嵌入二进制文件。
  • ./src/codegen/bundle-functions.ts -- 将用 JavaScript/TypeScript 实现的全局可访问函数(如 ReadableStream 和 WritableStream)打包。这些函数的使用方式与内置模块类似,但其输出更贴近 WebKit/Safari 对 Safari 内置函数的处理方式,因此可以将实现从 WebKit 复制粘贴过来作为起点。

修改 ESM 模块

某些模块如 node:fs、node:stream、bun:sqlite 和 ws 用 JavaScript 实现,位于 src/js/{node,bun,thirdparty},并由 Bun 预打包。

发布版本构建

编译 Bun 的发布版本,运行:

bash
bun run build:release

二进制文件位于 ./build/release/bun 和 ./build/release/bun-profile。

从 Pull Request 下载发布版本构建

你可以直接运行来自 Pull Request 的发布版本构建,而无需在本地构建,这对于在合并更改之前手动测试非常有用。

使用 bun-pr npm 包:

shell
bunx bun-pr <pr-number>
bunx bun-pr <branch-name>
bunx bun-pr "https://github.com/oven-sh/bun/pull/1234566"
bunx bun-pr --asan <pr-number> # 仅限 Linux x64

bun-pr 会从 Pull Request 的 GitHub Actions 构建产物中下载发布版本构建,并将其以 bun-${pr-number} 的名称添加到 $PATH,因此你可以直接运行它:

shell
bun-1234566 --version

你可能需要安装 gh CLI 才能通过 GitHub 身份验证。

从终端查看 CI 失败情况

Bun 的 CI 在 BuildKite 上运行。安装 BuildKite CLI(brew install buildkite/buildkite/bk),并将 BUILDKITE_API_TOKEN 设置为只读作用域的 API token。仓库包含一个 .bk.yaml,因此 bk 命令默认使用 bun pipeline。

shell
bun run ci:status         # 当前分支最新构建的进度摘要
bun run ci:errors         # 渲染后的测试失败输出,标记 [new] 与 [also on main]
bun run ci:logs           # 将每个失败任务的完整日志保存到 ./tmp/ci-<build>/
bun run ci:watch          # 监视直到构建完成
bun run ci:find           # 打印构建编号(可与原始 `bk` 组合使用)

以上所有命令都接受一个目标:#1234(PR 编号)、PR URL、分支名或构建编号。如果不指定,则使用当前 git 分支。

AddressSanitizer

AddressSanitizer 有助于发现内存问题,并且在 Linux 和 macOS 上 Bun 的调试构建中默认启用。它覆盖 Rust 代码、C++ 绑定以及所有依赖项。这会让构建时间大约增加 2 倍;如果这影响到您的效率,您可以使用 bun run build:debug:noasan 禁用它(或者向 scripts/build.ts 传递 --asan=off),但通常我们建议您在两次构建之间批量完成更改。

要使用 AddressSanitizer 构建发布版本,请运行:

bash
bun run build:asan

CI 会运行测试套件,其中至少有一个目标是使用 AddressSanitizer 构建的。

本地构建 WebKit + JSC 调试模式

默认不克隆 WebKit(节约时间和空间)。要本地克隆并构建 WebKit:

bash
# 将 WebKit 克隆到 ./vendor/WebKit
git clone https://github.com/oven-sh/WebKit vendor/WebKit

# 检出 scripts/build/deps/webkit.ts 中 WEBKIT_VERSION 指定的版本
# (可以是提交 SHA 或 autobuild-* 发布标签;两者都支持)
bun sync-webkit-source

# 构建 JSC 的调试版本,产物在 ./vendor/WebKit/WebKitBuild/Debug
# 可选:用 `bun run jsc:build` 构建发布版
bun run jsc:build:debug && rm vendor/WebKit/WebKitBuild/Debug/JavaScriptCore/DerivedSources/inspector/InspectorProtocolObjects.h

# 初次运行 `make jsc-debug` 后,可以用下面命令重建 JSC:
cmake --build vendor/WebKit/WebKitBuild/Debug --target jsc && rm vendor/WebKit/WebKitBuild/Debug/JavaScriptCore/DerivedSources/inspector/InspectorProtocolObjects.h

# 用本地 JSC 构建 Bun
bun run build:local

bun run build:local 会处理所有事项:配置 JSC、构建 JSC 和构建 Bun。后续运行时,如果任何 WebKit 源码发生更改,JSC 都会增量重建。

  • src/js/builtins.d.ts 第一行

  • .clangd 配置中的 CompilationDatabase 路径改为 build/debug-local

  • build.zig 中的 codegen_path 改为 build/debug-local/codegen

  • .vscode/launch.json 中相应配置的路径改为 ./build/debug-local/

  • src/js/builtins.d.ts 第一行

  • .clangd 配置中的 CompilationDatabase 行应为 CompilationDatabase: build/debug-local

  • .vscode/launch.json 中,许多配置使用了 ./build/debug/,请按需修改

WebKit 文件夹(包括构建产物)大小超过 8GB。

如果你在 VSCode 中使用 JSC 调试版本,请运行 C/C++: Select a Configuration 命令,以便 IntelliSense 找到调试头文件。

如果你修改了 Bun 的 WebKit fork,还必须修改 scripts/build/deps/webkit.ts 中的 WEBKIT_VERSION,使其指向你的提交哈希或发布标签。

Ubuntu 上出现 'span' 文件未找到

Clang 默认使用 libstdc++,这是由 GNU Compiler Collection(GCC)提供的 C++ 标准库实现。Clang 也可以改为链接 libc++,但这需要显式传递 -stdlib 标志。

Bun 依赖 std::span 等 C++20 特性,而这些特性在低于 11 的 GCC 版本中不可用。因此,运行 bun run build 可能会失败,并出现以下错误:

Text
fatal error: 'span' file not found
#include <span>
         ^~~~~~

首次运行 bun run build 时也可能出现此问题,此时 Clang 无法编译一个简单的程序:

Text
The C++ compiler

  "/usr/bin/clang++-23"

is not able to compile a simple test program.

要修复此错误,请将 GCC 更新到 11 版本。你的发行版官方仓库中可能已提供该版本;否则,请添加提供 GCC 11 软件包的第三方仓库:

bash
sudo apt update
sudo apt install gcc-11 g++-11
# 如果报错找不到包,需添加 APT 仓库
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
# 再试安装
sudo apt install gcc-11 g++-11

然后将 GCC 11 设置为默认编译器:

bash
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 100
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 100

libarchive

macOS 上编译 libarchive 出错时,运行:

bash
brew install pkg-config

macOS 编译时出现 library not found for -lSystem

出现此错误,运行:

bash
xcode-select --install

找不到 libatomic.a

Bun 默认静态链接 libatomic,因为并非所有系统都提供该库。如果你在没有静态版 libatomic 的发行版上构建,请使用以下命令启用动态链接:

bash
bun run build --static-libatomic=off

但这样构建的 Bun 可能无法在其他系统运行。

使用 bun-debug

  • 禁用日志:BUN_DEBUG_QUIET_LOGS=1 bun-debug ...(禁用所有调试日志)
  • 为特定作用域启用日志:BUN_DEBUG_EventLoop=1 bun-debug ...(启用 scoped_log!(EventLoop, ...) 输出)
  • Bun 会转译运行的每个文件。要在调试构建中查看实际执行的源代码,请在 /tmp/bun-debug-src/...path/to/file 中查找。例如,/home/bun/index.ts 的转译版本位于 /tmp/bun-debug-src/home/bun/index.ts

贡献文档

文档是 Bun 仓库 docs/ 目录中的 MDX 文件。bun.com/docs 根据这些文件构建。

文风

文档页面介绍 Bun 的功能以及你可以用它做什么。写作时应让刚接触 Bun 的开发者读一遍页面后就能采取行动。以下指南改编自 Next.js 文档贡献指南:

  • 写简短的句子,每句话只表达一个要点。如果一句话需要多个逗号或括号,请拆分句子或改为列表。
  • 使用简单的词语:用“使用”代替“利用”,用“为了”代替“以便”。删去“请注意”和“请”等填充语。
  • 使用主动语态并指出动作主体:“Bun 读取 bunfig.toml”,而不是“bunfig.toml 被读取”。以“是”和“被”构成的句子通常是被动语态。
  • 用现在时描述当前行为:“Bun 安装该软件包”,而不是“Bun 将安装该软件包”。
  • 如果“这”或“它”可能指代多个对象,请明确说出主体:“--isolate 是 Jest 的默认行为”,而不是“这是 Jest 的默认行为”。
  • 用“你”称呼读者,并让 Bun(或具体工具)作为另一个动作主体:“Bun 缓存压缩包”,而不是“我们缓存压缩包”或“让我们缓存压缩包”。
  • 不要使用“容易”“简单”“只是”和“快速”。当任务很容易时,这些词没有意义;当任务并不容易时,它们会让读者气馁。请明确说明具体特性:“一条命令”“无需配置”。
  • 说明应该做什么,而不是应该避免什么:“使用 port: 0,让操作系统选择一个可用端口”,而不是“不要将端口写死”。直接说明限制;限制是事实,不是对读者的警告。
  • 使用性别中立的表达:“开发者”“用户”“他们”。
  • 让链接文本明确指出其目标:“请参阅 bun install”,而不是“请参阅此处”。
  • 发布前运行每个代码示例,并根据 main 上的实现检查选项名称和默认值。