oven-sh/bun
Development workflow
How a change goes from "I want to fix this" to "merged in main".
Branch and commit
- Branch name must start with
claude/. The CI gates on the prefix; it won't run otherwise. (Yes, this is true for human contributors too.) - Keep commits focused. Squash on merge is the norm. The PR description does the bulk of the explaining.
- The default branch is
main.
Build the debug binary
bun bdbd is a package.json script that calls scripts/build.ts, which configures CMake, runs codegen, then builds Zig. The output is ./build/debug/bun-debug.
bun bd <args> builds, then runs the freshly-built binary with <args>. Always use this instead of ./build/debug/bun-debug directly — it suppresses build noise on success and gives you a clean error if the build broke.
Do not set a timeout on
bun bd. First builds and post-codegen rebuilds can take several minutes.
Useful flavors:
| Command | Purpose |
|---|---|
bun bd test test/js/bun/http/serve.test.ts |
Build + run a test. |
bun bd run script.ts |
Build + run a script. |
bun run build:release -p 'Bun.version' |
Release build, then bun -p. |
bun run build:local run script.ts |
Debug build with locally-built WebKit. |
bun run build --build-dir=build/baseline |
Park a build directory to compare later. |
Iterate
Most edits touch one of three areas:
- Zig. Triggers a Zig recompile. Usually 5–60 s.
- C++. Triggers a C++ recompile. Slower than Zig.
src/js/*.ts. Triggers a quickbundle-modules.tsregeneration. Often tens of seconds.
Pure TypeScript-type changes under packages/bun-types/ don't need a rebuild — run bun test test/integration/bun-types/bun-types.test.ts directly.
Test
bun bd test test/js/bun/http/serve.test.ts
bun bd test http/serve.test.ts # fuzzy match
bun bd test test/js/bun/http/serve.test.ts -t "should handle"Verify your test:
- Fails on
mainwithUSE_SYSTEM_BUN=1 bun test <file>. - Passes on your branch with
bun bd test <file>.
If the test passes with USE_SYSTEM_BUN=1, it isn't actually exercising your fix.
Debug-log scopes
Bun has thousands of bun.Output.scoped(.MyScope, ...) log sites that fire when the matching env var is set:
BUN_DEBUG_HTTP=1 bun bd run server.ts
BUN_DEBUG_QUIET_LOGS=1 bun bd test ... # silence everythingThe list of scopes is the Output.scoped(...) declarations in the source. Grep for them.
Special debug envs:
| Variable | Effect |
|---|---|
BUN_DEBUG_QUIET_LOGS=1 |
Disable debug logging. |
BUN_JSC_validateExceptionChecks=1 |
Strict exception-scope checks (catches unchecked exceptions). |
BUN_JSC_dumpSimulatedThrows=1 |
Print where simulated throws originate. |
BUN_DEBUG_<scope>=1 |
Enable a specific scope. |
Open the PR
Push to your claude/... branch and open a PR against main. Include:
- A clear description of the change and why it's needed.
- Links to any related issue(s).
- Honest test status. Don't claim "tested" if you didn't run the tests.
CI
The CI runs on BuildKite. Use the helper scripts:
bun run ci:errors # rendered test failures for current branch
bun run ci:errors '#26173' # by PR / build number
bun run ci:status # progress summary
bun run ci:logs # save logs for failed jobs
bun run ci:watch # tail until doneSetup: brew install buildkite/buildkite/bk and set BUILDKITE_API_TOKEN.
Reading PR feedback
gh pr view --comments only shows issue-stream comments — review summaries and line-level review comments are silently omitted. Use:
bun run pr:comments # current branch's PR
bun run pr:comments 28838 # by number
bun run pr:comments --include-resolved
bun run pr:comments --json | jq '...'This script hits all three GitHub endpoints (issues, reviews, pulls/comments), prints them chronologically, and labels each entry with its real type.
Reviewer expectations
Pulled from CLAUDE.md's "Code Review Self-Check":
- Before writing a non-obvious change, ask "why this and not the alternative?". Research until you can answer.
- Don't take a reporter's suggested fix at face value. Verify it's the right layer.
- If neighbouring code does something differently than you're about to, find out why before deviating. Its choices are often load-bearing.
Commit / PR honesty
Be humble & honest. NEVER overstate what you got done or what actually works in commits, PRs or in messages to the user. —
CLAUDE.md
If something is incomplete, say so in the PR.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.