Configuring a development environment for Bun usually takes 30-90 minutes depending on your operating system.
To develop on Linux/Windows, Docker is required. If using WSL on Windows, it is recommended to use Docker Desktop for its WSL2 integration.
If you're using VSCode, you'll need to have the Dev Containers extension installed.
To get started, open VS Code in the
bun repository. The first time you try to open the dev container, the extension will automatically build it for you, based on
To open the dev container, open the command palette (
P) and run:
Dev Containers: Reopen in Container. To later rebuild it (only needed when the devcontainer itself changes, not the Bun code), run:
Dev Containers: Rebuild and Reopen in Container.
Other editors and CLI
If you're using another editor or want to manually control the dev container from the command line or a script, you'll need to install the Dev Container CLI:
npm install -g @devcontainers/cli.
To create and start the dev container, in the
bun repository, locally run:
# `make devcontainer-<command>` should be equivalent # to `devcontainer <command>`, it just sets the architecture # so if you're on ARM64, it'll do the right thing
To just build the dev container image, run:
To start a shell inside the container, run:
# if it attaches to the container non-interactively, # instead use the regular docker exec command:
docker exec -it <container-name/id> zsh
You will then need to clone the GitHub repository inside that container.
# First time setup
gh auth login # if it fails to open a browser, use Personal Access Token instead
gh repo clone oven-sh/bun . -- --depth=1 --progress -j8
# Compile Bun dependencies (zig is already compiled)
# It initializes and updates all submodules except WebKit, because WebKit # takes a while and it's already compiled for you. To do it manually, use:
git -c submodule."src/bun.js/WebKit".update=none submodule update --init --recursive --depth=1 --progress
# Build Bun for development
# Run Bun
Install LLVM 15 and
brew install llvm@15 coreutils libtool cmake libiconv automake ninja gnu-sed pkg-config esbuild go rust
Bun (& the version of Zig) need LLVM 15 and Clang 15 (
clang is part of LLVM). Make sure LLVM 15 is in your
If not, run this to manually link it:
# use fish_add_path if you're using fish
export PATH="$PATH:$(brew --prefix llvm@15)/bin"
export LDFLAGS="$LDFLAGS -L$(brew --prefix llvm@15)/lib"
export CPPFLAGS="$CPPFLAGS -I$(brew --prefix llvm@15)/include"
⚠️ Warning — You must use the same version of Zig used by Bun in oven-sh/zig. Installing with
brew or via Zig's download page will not work!
zigup to install the version of Zig (
ZIG_VERSION) specified in the official
Dockerfile. For example:
To install and build dependencies:
# without --depth=1 this will take 20+ minutes on 1gbps internet # mostly due to WebKit
git submodule update --init --recursive --progress --depth=1 --checkout
make vendor identifier-cache webcrypto-debug
To compile the C++ bindings:
# without -j this will take 30+ minutes
make bindings -j12
To verify the build worked, lets print the version number on the development build of Bun.
You will want to add
packages/debug-bun-darwin-x64/ (depending on your architecture) to
$PATH so you can run
bun-debug from anywhere.
If you see an error when compiling
libarchive, run this:
brew install pkg-config
If you see an error about missing files on
zig build obj, make sure you built the headers.
When you change anything in
src/bun.js/builtins/js/*, run this:
make clean-bindings generate-builtins && make bindings -j12
Code generation scripts
Bun leverages a lot of code generation scripts.
The ./src/bun.js/bindings/headers.h file has bindings to & from Zig <> C++ code. This file is generated by running the following:
This ensures that the types for Zig and the types for C++ match up correctly, by using comptime reflection over functions exported/imported.
TypeScript files that end with
*.classes.ts are another code generation script. They generate C++ boilerplate for classes implemented in Zig. The generated code lives in:
- src/bun.js/bindings/generated_classes.zig To generate the code, run:
Lastly, we also have a code generation script for our native stream implementations. To run that, run:
You probably won't need to run that one much.
Modifying ESM core modules
Certain modules like
While Bun is in beta, you can modify them at runtime in release builds via the environment variable
BUN_OVERRIDE_MODULE_PATH. When set, Bun will look in the override directory for
<name>.exports.js before checking the files from
src/bun.js (which are now baked in to the binary). This lets you test changes to the ESM modules without needing to re-compile Bun.
If you encounter
error: the build command failed with exit code 9 during the build process, this means you ran out of memory or swap. Bun currently needs about 22 GB of RAM to compile.