Open-Source Wikis

/

Bun

/

Bun

/

Getting started

oven-sh/bun

Getting started

This page is for engineers who want to build, run, and modify Bun itself. For installing the published bun binary, see bun.com/docs/installation.

Prerequisites

  • ~10 GB of free disk space
  • A release build of bun already on $PATH (Bun bootstraps with itself)
  • LLVM 21.1.8 — the build is pinned to this exact version
  • CMake, Ninja, Go, Rust, Ruby, libtool, automake, pkg-config, autoconf
  • macOS, Linux (x64/arm64), or Windows (x64/arm64). Linux kernel ≥ 5.6 recommended.

A Nix flake is provided as an alternative:

nix develop
export CMAKE_SYSTEM_PROCESSOR=$(uname -m)
bun bd

For per-distro install lists, see CONTRIBUTING.md. The Zig compiler is downloaded automatically by the build scripts; do not install it yourself.

Cloning

git clone https://github.com/oven-sh/bun
cd bun

The vendor/WebKit/ directory is not a submodule. The build downloads a prebuilt JSC archive matching the WEBKIT_VERSION pin in scripts/build/deps/webkit.ts. To compile JSC locally instead (8+ GB), see the "Building WebKit locally" section in CONTRIBUTING.md.

First build

bun run build         # alias for build:debug
# or, equivalently
bun bd

This:

  1. Runs scripts/build.ts which configures CMake under build/debug/.
  2. CMake invokes zig build against build.zig for the Zig compilation unit.
  3. CMake compiles the C++ side and links against vendored static libraries.
  4. The output is ./build/debug/bun-debug.

The first build takes 10–30 minutes depending on the machine. The Zig step is a single compilation unit and can take ~2.5 minutes by itself; C++ is incremental.

Add ./build/debug to your $PATH so you can call bun-debug directly.

Build-then-exec

bun bd accepts trailing arguments, builds, and then immediately executes:

bun bd run script.ts            # debug build then `bun run script.ts`
bun bd test foo.test.ts         # debug build then `bun test foo.test.ts`
bun bd -e 'console.log(Bun.version)'
bun run build:release -p 'Bun.version'

When trailing args are present, build output is suppressed unless the build fails. This is the recommended workflow — never run ./build/debug/bun-debug directly.

Common build profiles

Command Profile Output dir
bun bd debug (ASan on by default) build/debug/
bun run build:debug:noasan debug-no-asan build/debug/
bun run build:release release build/release/
bun run build:release:lto release with LTO build/release-lto/
bun run build:asan release-asan build/release-asan/
bun run build:assert release-assertions build/release-assert/
bun run build:smol release MinSizeRel build/release-smol/
bun run build:local debug-local (uses local WebKit) build/debug-local/

All profiles flow through scripts/build.ts. See the file's header for argument routing rules.

Running tests

The test suite lives under test/. Run it with the debug build:

bun bd test test/js/bun/http/serve.test.ts             # exact path
bun bd test http/serve.test.ts                         # fuzzy match
bun bd test test/js/bun/http/serve.test.ts -t "should handle"

Never run bun test directly on a Bun source change — it will use the system bun, not your debug build. Same for bun foo.ts. See Testing.

The exception is type-only changes under packages/bun-types/**/*.d.ts, which can be verified by running bun test test/integration/bun-types/bun-types.test.ts directly.

Lint, format, typecheck

bun run typecheck    # tsc --noEmit on the workspace and tests
bun run lint         # oxlint with the repo's oxlint.json
bun run lint:fix     # oxlint --fix
bun run fmt          # prettier (also runs prettier-plugin-organize-imports)
bun run fmt:cpp      # clang-format
bun run fmt:zig      # zig fmt src/ build.zig
bun run zig:check    # type-check the Zig code without producing a binary
bun run zig:check-all # zig check across all supported targets (slow)

The CI runs all of these. Submitting a PR with prettier or clang-format violations will fail lint.yml / format.yml.

Environment variables for development

Variable Effect
BUN_DEBUG_QUIET_LOGS=1 Suppress all Output.scoped debug logs
BUN_DEBUG_<scope>=1 Enable Output.scoped(.<scope>, .hidden) for a single scope
BUN_DEBUG=/path/to/file.log Tee debug logs to a file
BUN_JSC_validateExceptionChecks=1 Verify JS exception scope balance (slow)
BUN_JSC_dumpSimulatedThrows=1 Print stacks for simulated throws
USE_SYSTEM_BUN=1 Make bun test ... invoke the system bun (used to verify a regression test actually fails on main)

The transpiled view of any file Bun runs is dumped to /tmp/bun-debug-src/...path/to/file in debug builds.

Editor setup

VS Code is the recommended editor. Open the workspace via workspace.code-workspace. The Extensions: Show Recommended Extensions command will offer the Zig and C++ packs. ZLS is auto-configured to use vendor/zig/zig.exe (despite the .exe suffix it works on macOS / Linux).

Other editors should point ZLS at the same vendor/zig/zig.exe. The .clangd config expects compile commands at build/debug/compile_commands.json; switch to build/debug-local/... if you build against local WebKit.

CI helpers

bun run ci:status     # one-screen progress summary for the current branch's build
bun run ci:errors     # rendered test failures, tagged [new] vs [also on main]
bun run ci:logs       # save full failed-job logs to ./tmp/ci-<build>/
bun run ci:watch      # tail until completion
bun run ci:find       # print the build number

These wrap the BuildKite CLI (bk). Install it with brew install buildkite/buildkite/bk and set BUILDKITE_API_TOKEN to a read-scoped token. The repo's .bk.yaml makes -p bun unnecessary.

For PR feedback, prefer bun run pr:comments over gh pr view --comments — the former fetches issue, review, and inline comments together.

Where to go next

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Getting started – Bun wiki | Factory