配置 Bun 的开发环境可能需要 10 到 30 分钟,具体取决于您的网络连接和计算机速度。您需要大约 10GB 的可用磁盘空间用于存储仓库和构建产物。
如果您使用的是 Windows,请参考 此指南
使用 Nix(可选方案)
提供了一个 Nix flake 作为手动安装依赖的替代方案:
nix develop
# 或显式使用纯净 shell
# nix develop .#pure
export CMAKE_SYSTEM_PROCESSOR = $( uname -m )
bun bd
这样可以在隔离且可复现的环境中提供所有依赖,无需 sudo。
安装依赖(手动)
使用系统的包管理器安装 Bun 的依赖:
macOS (Homebrew)
Ubuntu/Debian
Arch
Fedora
openSUSE Tumbleweed
brew install automake ccache cmake coreutils gnu-sed go icu4c libiconv libtool ninja pkg-config rustup-init ruby
sudo apt install curl wget lsb-release software-properties-common cmake git golang libtool ninja-build pkg-config ruby-full xz-utils
sudo pacman -S base-devel cmake git go libiconv libtool make ninja pkg-config python rustup sed unzip ruby
sudo dnf install clang21 llvm21 lld21 cmake git golang libtool ninja-build pkg-config ruby libatomic-static libstdc++-static sed unzip which libicu-devel ' perl(Math::BigInt) '
sudo zypper install go cmake ninja automake git icu rustup
Bun 使用 Rust 编写,并且需要特定的 nightly 工具链(固定在 rust-toolchain.toml 中)。请通过 rustup 安装 Rust,而不是使用发行版自带的 rust/cargo 包——构建脚本会使用 rustup 自动安装并更新固定的 nightly:
curl --proto ' =https ' --tlsv1.2 -sSf https://sh.rustup.rs | sh
开始之前,您需要已安装 Bun 的发布版本构建,因为我们使用自己的打包器来转译和压缩代码,以及用于代码生成脚本。
curl -fsSL https://bun.com/install | bash
brew tap oven-sh/bun
brew install bun
可选:安装 ccache
ccache 用于缓存编译产物,大幅加速构建过程:
# 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 21.1.8(clang 是 LLVM 的一部分)。构建系统强制要求使用此版本——版本不匹配会导致运行时内存分配失败。在大多数情况下,你可以通过系统的包管理器安装 LLVM:
macOS (Homebrew)
Ubuntu/Debian
Arch
Fedora
openSUSE Tumbleweed
# LLVM 有一个适用于所有 Ubuntu 版本的自动安装脚本
wget https://apt.llvm.org/llvm.sh -O - | sudo bash -s -- 21 all
sudo pacman -S llvm clang lld
sudo dnf install llvm clang lld-devel
sudo zypper install clang21 lld21 llvm21
如果以上解决方案都不适用,您需要手动 安装。
请确保 Clang/LLVM 21 已添加到您的路径中:
如果没有,请手动添加:
# 如果你使用 fish,请使用 fish_add_path
# 如果你使用 zsh,请使用 path+="$(brew --prefix llvm@21)/bin"
export PATH = " $( brew --prefix llvm@21)/bin: $PATH "
# 如果你使用 fish,请使用 fish_add_path
export PATH = " $PATH :/usr/lib/llvm21/bin "
⚠️ Ubuntu 发行版(版本 ≤ 20.04)可能需要单独安装 C++ 标准库。详情见故障排查章节 。
构建 Bun
克隆仓库后,运行以下命令构建。这可能需要一些时间,因为会克隆子模块和构建依赖。
生成的二进制文件位于 ./build/debug/bun-debug。建议将其添加到您的 $PATH 中。验证构建是否成功,可以打印开发版 Bun 的版本号:
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,这样就可以在终端中直接运行:
运行调试构建
bd package.json 脚本会编译并运行 Bun 的调试构建,仅在失败时打印构建过程输出。
bun bd < arg s >
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 的更改几乎可以瞬间重建。单个 Rust crate 的更改和 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 等接口,代码生成器读取这些定义并生成实现 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 的发布版本,运行:
生成的二进制位于 ./build/release/bun 和 ./build/release/bun-profile。
从 Pull Request 下载发布版本构建
为节省本地编译发布版的时间,我们提供了从 Pull Request 运行发布构建的方法。方便在合并前手动测试更改。
运行 PR 的发布版,可以使用 bun-pr npm 包:
bunx bun-pr < pr-numbe r >
bunx bun-pr < branch-nam e >
bunx bun-pr " https://github.com/oven-sh/bun/pull/1234566 "
bunx bun-pr --asan < pr-numbe r > # 仅限 Linux x64
它会从 PR 的 GitHub Actions 构建产物下载发布版本并添加到 $PATH,命名为 bun-${pr-number}。然后可以用命令 bun-${pr-number} 运行:
需要安装 gh CLI 以进行 GitHub 认证。
从终端查看 CI 失败情况
Bun 的 CI 在 BuildKite 上运行。安装 BuildKite CLI (brew install buildkite/buildkite/bk),并将 BUILDKITE_API_TOKEN 设置为只读作用域的 API token 。仓库包含一个 .bk.yaml,因此 bk 命令默认使用 bun pipeline。
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),但通常我们建议您在两次构建之间批量完成更改。
构建带 Address Sanitizer 的发布版,运行:
在 CI 中,我们至少有一个目标使用 Address Sanitizer 来运行测试套件。
本地构建 WebKit + JSC 调试模式
默认不克隆 WebKit(节约时间和空间)。要本地克隆并构建 WebKit:
# 将 WebKit 克隆到 ./vendor/WebKit
git clone https://github.com/oven-sh/WebKit vendor/WebKit
# 检出 scripts/build/deps/webkit.ts 中 WEBKIT_VERSION 指定的提交哈希
git -C vendor/WebKit checkout < commit_has h >
# 构建 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 时,Bun 会构建到 ./build/debug-local 目录(非默认 ./build/debug),需要修改以下位置:
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/,请按需修改
如果使用 JSC 调试构建且用 VSCode,务必运行 “C/C++: Select a Configuration” 以配置 IntelliSense 找到调试头文件。
修改我们 WebKit 仓库 的代码后,还需同步修改 SetupWebKit.cmake 中的提交哈希。
Note that if you make changes to our WebKit fork , you will also have to change WEBKIT_VERSION in scripts/build/deps/webkit.ts to point to the commit hash.
Ubuntu 上出现 ‘span’ 文件未找到
⚠️ 以下说明针对 Ubuntu 特有的问题,其他 Linux 发行版一般不会遇到此类问题。
Clang 编译器默认使用 libstdc++ 作为 C++ 标准库,这也是 GCC 默认提供的。虽然 Clang 可以链接 libc++,但需要显式传递 -stdlib 参数。
Bun 依赖 C++20 特性,如 std::span,GCC 11 以下版本不支持。GCC 10 不支持所有 C++20 特性,因此运行 make setup 可能会报错:
fatal error: 'span' file not found
#include <span>
^~~~~~
该错误可能出现在初次运行 bun setup 时,Clang 无法编译简单程序:
The C++ compiler
"/usr/bin/clang++-21"
is not able to compile a simple test program.
解决方法是将 GCC 更新到 11。可以先检查发行版官方仓库是否有该版本,或添加第三方仓库。通用步骤:
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 设置为默认:
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 出错时,运行:
macOS 编译时出现 library not found for -lSystem
出现此错误,运行:
找不到 libatomic.a
Bun 默认静态链接 libatomic,因非所有系统都提供静态库。如果在没有静态 libatomic 的发行版上构建,可使用动态链接:
bun run build -DUSE_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