Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

Bun — Administrator & Developer Guide

Generated May 2026 from oven-sh/bun at 9ed6e89

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

Note

This guide targets Bun v1.3.13 (commit 9ed6e89, 2026-05-07). It covers architecture internals, build system, configuration reference, deployment patterns, and operational concerns. For end-user installation and everyday usage, see the companion User Guide.


1. Architecture Overview

Bun is an all-in-one JavaScript/TypeScript runtime written primarily in Zig and C++, with TypeScript used for build tooling and type definitions. Unlike Node.js and Deno, Bun embeds JavaScriptCore (WebKit's JS engine) rather than V8. This choice is deliberate: JSC starts faster and uses less memory for typical server workloads, while Zig enables fine-grained control over memory layout and system calls without a GC overhead in the runtime host.

The architecture is monolithic by design — the runtime, bundler, transpiler, package manager, test runner, and shell all live in the same binary and share internal data structures. This avoids serialization overhead between tools and lets the bundler directly feed the runtime without writing intermediate files.

1.1 Component Inventory

Component Path Role
Runtime core src/ (117 files, 3.2M chars) Main Zig runtime, event loop, system calls
JavaScript engine bindings src/bun.js/ JavaScriptCore FFI layer
HTTP server/client src/http/ (29 files) HTTP/1.1, HTTP/2, WebSocket, TLS
Package manager src/install/ (29 files, 1M chars) npm-compatible package installer
Bundler src/bundler/ (16 files, 576K chars) JavaScript/TypeScript bundler
Transpiler src/ast/ (46 files, 1.6M chars), src/js_lexer/ JS/TS/JSX parser and transpiler
CLI src/cli/ (44 files, 1.5M chars) Command-line interface, argument parsing
Shell src/shell/ (15 files, 430K chars) Built-in shell for Bun.$
Module resolver src/resolver/ (6 files, 401K chars) Module resolution (ESM, CJS, package.json exports)
CSS parser src/css/ (17 files, 817K chars) CSS parsing and bundling
SQL clients src/sql/, src/sql/postgres/protocol/, src/sql/mysql/protocol/ Built-in PostgreSQL and MySQL drivers
S3 client src/s3/ (10 files, 184K chars) Built-in S3-compatible storage client
Valkey/Redis src/valkey/ (7 files, 219K chars) Built-in Redis/Valkey client
Markdown parser src/md/ (16 files, 458K chars) GFM markdown parser with HTML/ANSI/React output
Codegen src/codegen/ (23 files, 451K chars) Build-time code generation (binding gen, module bundling)
Threading src/threading/ (8 files, 91K chars) Thread pool, concurrent I/O
Async I/O src/async/ (3 files, 60K chars), src/io/ (9 files, 165K chars) Event loop, async primitives
Source maps src/sourcemap/ (9 files, 174K chars) Source map generation and consumption
Glob src/glob/ (2 files, 100K chars) Fast glob pattern matching
Semver src/semver/ (7 files, 102K chars) Semantic versioning parser
Memory allocators src/allocators/ (10 files, 64K chars) Custom memory allocators
Safety src/safety/ (4 files, 18K chars) Safety checks and debug assertions
File watcher src/watcher/ (4 files, 34K chars) File system watcher (--watch/--hot)
Node.js compat src/node-fallbacks/ (25 files, 170K chars), src/js/internal/ (21 files) Node.js API polyfills
NAPI src/napi/ (5 files, 146K chars) Node-API native addon support
Bake (SSR) src/bake/ (21 files, 402K chars) Server-side rendering framework (experimental)
Error reporting src/errno/ (3 files, 58K chars) System error handling

1.2 Engine: JavaScriptCore vs. V8

Replacing V8 with JSC touches every integration point:

  • GC: JSC uses a concurrent, generational GC with a separate MarkedBlock allocator. Bun exposes --expose-gc to make gc() callable from JS for testing purposes.
  • JIT tiers: JSC has four tiers — LLInt (interpreter), Baseline JIT, DFG JIT, and FTL JIT (LLVM-backed). Tier selection is automatic.
  • Bytecode: bun build --bytecode emits JSC bytecode that JSC can execute without reparsing — useful for reducing cold-start overhead on large bundles.
  • V8 compatibility: A V8 API compatibility shim exists for native addons (src/napi/), but coverage is partial. Addons relying on V8 internals may not work.

1.3 Package Inventory

Package Purpose
packages/bun-types (24 files, 843K chars) TypeScript type definitions for Bun APIs
packages/bun-release Release automation and npm publishing
packages/bun-vscode VS Code extension (debugger, run configurations)
packages/bun-lambda AWS Lambda runtime layer
packages/bun-native-plugin-rs Rust SDK for native bundler plugins
packages/bun-debug-adapter-protocol DAP implementation for debugger
packages/bun-inspector-protocol Chrome DevTools protocol
packages/bun-usockets / packages/bun-uws µWebSockets (C networking layer)
packages/bun-wasm WebAssembly build of Bun transpiler
packages/bun-error Error formatting and display
packages/bun-plugin-svelte Svelte plugin for bundler
packages/bun-plugin-yaml YAML loader plugin
packages/bun-build-mdx-rs MDX compiler (Rust, via NAPI)

1.4 Technology Stack

Language Usage
Zig Core runtime, event loop, parser, package manager, resolver
C++ JavaScriptCore bindings, µWebSockets
TypeScript Codegen scripts, type definitions, test suite
Rust Native bundler plugins (bun-native-plugin-rs), MDX compiler
JavaScript Node.js fallbacks, internal builtins

2. System Requirements

2.1 Runtime Requirements

Platform Minimum Version Architecture
macOS 12 (Monterey) x64, ARM64 (Apple Silicon)
Linux Kernel 5.1+ x64, ARM64
Windows Windows 10 (Build 17063+) x64

Important

On Linux, Bun requires a kernel with io_uring support (5.1+). Some container environments (particularly older Docker hosts or restrictive seccomp profiles) may block io_uring syscalls. Use BUNNOI_ORING=1 environment variable or verify your container security profile permits io_uring if you see unexpected I/O failures.

glibc requirement (Linux x64): glibc 2.17+. For older systems, use the musl-based binary.

Memory: No hard minimum; practical production minimum is 128 MB for small services. Use --smol to reduce heap size at the cost of throughput.

2.2 Building from Source

Dependency Notes
Zig compiler Vendored at vendor/zig/ — do not use a system Zig
CMake Build system driver
Clang / C++ compiler Required for JSC and µWebSockets
Node.js Required for codegen scripts (src/codegen/)
Bun (bootstrap) Needed to run package.json build scripts

Build profiles available:

Profile Flag Use Case
debug bun run build:debug Full debug symbols, ASAN enabled
release bun run build:release Optimized production build
ci-release bun run build:ci CI-specific release build
release-assertions — Release with runtime assertions
release-asan — Release with address sanitizer
debug-no-asan — Debug without ASAN overhead
# Clone and bootstrap
git clone https://github.com/oven-sh/bun
cd bun

# Debug build (faster compile, slower runtime)
bun run build:debug

# Release build (slower compile, production-optimized)
bun run build:release

# CI release (used in GitHub Actions)
bun run build:ci

Note

Always use the vendored Zig at vendor/zig/. The Zig language is not yet API-stable; the vendored version is pinned to the exact revision Bun's source was written against. Using a mismatched Zig version will produce compile errors.


3. Configuration Reference

3.1 bunfig.toml — Complete Reference

bunfig.toml is Bun's project-level configuration file. Bun reads it from the project root. A global config at ~/.bunfig.toml (or $XDG_CONFIG_HOME/.bunfig.toml) applies as a fallback for all projects.

Tip

Project-level bunfig.toml settings take precedence over the global config. You can use --config <path> to specify an alternate config file path for any command.

[install] — Package Manager

[install]
# Default registry (can be a string URL or a table with auth)
registry = "https://registry.npmjs.org"

# Equivalent per-scope registry override
[install.scopes]
"@myorg" = { token = "abc123", url = "https://npm.myorg.com" }
"@privateorg" = { password = "pw", username = "user", url = "https://npm.example.com" }

[install]
# Save packages to package.json by default (true/false/"development"/"production"/"optional")
save = true

# Auto-install missing dependencies when running scripts
auto = "auto"          # auto | fallback | force | disable

# Cache directory (default: platform-specific)
cache = "~/.bun/install/cache"

# Disable integrity verification (not recommended)
verify = true

# Run lifecycle scripts from these packages only
trustedDependencies = ["esbuild", "sharp"]

# Disable running lifecycle scripts entirely
ignoreScripts = false

# Number of concurrent install scripts (default: 5)
concurrentScripts = 5

# Number of concurrent network requests (default: 48)
networkConcurrency = 48

# Linker mode: isolated (default) or hoisted (node_modules-style)
linker = "isolated"    # isolated | hoisted

# Save a text-format lockfile alongside the binary lockfile
saveTextLockfile = false

# Omit dependency groups
omit = []              # ["dev", "optional", "peer"]

# Hardlink backend (macOS: clonefile is default)
backend = "hardlink"   # clonefile | hardlink | symlink | copyfile

[run] — Script Runner

[run]
# Default shell for bun run (bun or system)
shell = "bun"          # bun | system

# Suppress script output
silent = false

# Elide output lines beyond this count (0 = unlimited)
elidedLines = 0

[test] — Test Runner

[test]
# Root directory for test discovery
root = "."

# Timeout per test in milliseconds
timeout = 5000

# Retry count on failure
retries = 0

# Re-run each test N times
reruns = 0

# Coverage collection
coverage = false

# Coverage reporters (text, lcov, clover)
coverageReporter = ["text"]

# Coverage output directory
coverageDir = "coverage"

# Coverage threshold thresholds
coverageThreshold = { lines = 0, functions = 0, statements = 0 }

# Bail after N failures (0 = never)
bail = 0

# Randomize test order
randomize = false

# Seed for randomization
seed = 0

[bundle] / [build] — Bundler

[bundle]
# Default output directory
outdir = "dist"

# Target platform
target = "browser"     # browser | bun | node

# Source maps
sourcemap = "none"     # none | inline | linked | external

# Minification
minify = false
minifyWhitespace = false
minifySyntax = false
minifyIdentifiers = false

# Code splitting
splitting = false

# Public path for assets
publicPath = "/"

# External packages (array of patterns)
external = ["some-package"]

# Packages treatment
packages = "bundle"    # bundle | external

# Emit DCE annotations
emitDceAnnotations = false

# Bytecode compilation
bytecode = false

[debug] — Inspector

[debug]
# Inspector host:port
inspector = "localhost:6499"

[telemetry]

[telemetry]
# Disable telemetry entirely
disable = true

3.2 Environment Variables

Important

Environment variables are read at startup. Changes require a process restart. Use --env-file <path> to load from a dotenv file, or --no-env-file to suppress automatic .env loading.

Variable Purpose Source
NODE_ENV Runtime environment (development, production, test) Standard
BUN_INSPECT_NOTIFY Notification URL for debugger attach events src/js/internal/debugger.ts
TZ Timezone override (IANA tz database name) Runtime
REDIS_URL / VALKEY_URL Default connection URL for new Redis() / new Valkey() packages/bun-types/redis.d.ts
DATABASE_URL Default SQL connection URL SQL adapter
PGHOST PostgreSQL host SQL adapter
PGUSER PostgreSQL username SQL adapter
PGPASSWORD PostgreSQL password SQL adapter
POSTGRES_URL Full PostgreSQL connection URL SQL adapter
PGURL Alias for POSTGRES_URL SQL adapter
MYSQL_URL Full MySQL connection URL SQL adapter
MYSQL_HOST MySQL host SQL adapter
MYSQL_PORT MySQL port SQL adapter
MYSQL_USER MySQL username SQL adapter
MYSQL_PASSWORD MySQL password SQL adapter
MYSQL_DATABASE MySQL database name SQL adapter
AWS_SECRET_ACCESS_KEY AWS/S3 secret key for S3 client S3 client

3.3 CLI Flags — Complete Reference

Global Flags (all commands)

Flag Description
--env-file <path> Load environment variables from a dotenv file
--no-env-file Disable automatic .env file loading
--cwd <path> Set working directory before executing
-c, --config <path> Path to bunfig.toml (default: project root)
-h, --help Show help text

Runtime Flags (bun run, bun <file>)

Watch / Hot Reload

Flag Description
--watch Restart process on file changes
--hot Hot-reload modules without restarting the process
--no-clear-screen Disable screen clear on reload

Memory & Performance

Flag Description
--smol Use a smaller JSC heap (trades throughput for memory)
--expose-gc Expose gc() function to JavaScript
--zero-fill-buffers Zero-fill Buffer allocations (security)

Module Loading

Flag Description
-r, --preload <module> Execute a module before the entry point
--require <module> Alias for --preload (Node.js compat)
--import <module> ESM-style preload
--no-install Do not auto-install missing packages
--install <mode> Auto-install behavior: auto, fallback, force
-i Shorthand for --install=force

Networking

Flag Description
--port <n> Default port (sets process.env.PORT)
--fetch-preconnect <url> Warm up a TCP connection before the script starts
--max-http-header-size <bytes> Maximum HTTP header size
--dns-result-order <order> DNS result order: verbatim, ipv4first, ipv6first
--redis-preconnect Pre-connect to REDIS_URL/VALKEY_URL at startup
--sql-preconnect Pre-connect to DATABASE_URL at startup

TLS / CA

Flag Description
--use-system-ca Use the OS certificate store
--use-openssl-ca Use OpenSSL's certificate store
--use-bundled-ca Use Bun's bundled CA (default)

Debugging & Profiling

Flag Description
--inspect [host:port] Enable WebSocket debugger (default localhost:6499)
--inspect-wait [host:port] Pause execution until debugger attaches
--inspect-brk [host:port] Break on first line of script
--cpu-prof Write a CPU profile on exit
--cpu-prof-name <name> Profile file name
--cpu-prof-dir <dir> Profile output directory
--cpu-prof-md Write CPU profile as Markdown (LLM-friendly)
--cpu-prof-interval <µs> Sampling interval in microseconds (default: 1000)
--heap-prof Write a heap profile on exit
--heap-prof-name <name> Heap profile file name
--heap-prof-dir <dir> Heap profile output directory
--heap-prof-md Write heap profile as Markdown

Error Handling

Flag Description
--unhandled-rejections <mode> strict, throw, warn, none, warn-with-error-code
--no-deprecation Suppress deprecation warnings
--throw-deprecation Throw on deprecated API use

Process

Flag Description
-e, --eval <code> Evaluate a string of JavaScript
-p, --print <code> Evaluate and print result
--if-present Exit 0 if entry point does not exist
--title <string> Set process title
--user-agent <string> Override HTTP User-Agent header
--no-addons Disable native addon loading
--conditions <conditions> Conditional exports conditions (comma-separated)
--console-depth <n> Max depth for console.log object inspection
--cron-title <title> Title for cron-style scheduling
--cron-period <period> Period for cron-style scheduling

Transpiler Flags

Flag Description
--main-fields <fields> Override package.json main fields order
--preserve-symlinks Preserve symlinks during resolution
--preserve-symlinks-main Preserve symlinks for the main entry point
--extension-order <exts> Extension resolution order (comma-separated)
--tsconfig-override <path> Use alternate tsconfig.json
-d, --define <key=value> Replace an identifier with a literal value
--drop <name> Remove calls to named function
--feature <name> Enable/disable language feature
-l, --loader <ext:loader> Assign a loader to a file extension
--no-macros Disable Bun macro evaluation
--jsx-factory <expr> JSX factory function
--jsx-fragment <expr> JSX fragment factory
--jsx-import-source <pkg> JSX import source package
--jsx-runtime <mode> automatic or classic
--jsx-side-effects Prevent JSX from being tree-shaken
--ignore-dce-annotations Ignore @__PURE__ and similar annotations

bun run Script Flags

Flag Description
--silent Suppress script output
--elide-lines <n> Truncate long output
-F, --filter <pattern> Run scripts in matching workspaces
-b, --bun Force using Bun's runtime even for node shebangs
--shell <bun|system> Shell to use for script execution
--workspaces Run across all workspaces
--parallel Run matching scripts in parallel
--sequential Run matching scripts sequentially (default)
--no-exit-on-error Continue running remaining scripts after failure
-v, --version Print Bun version
--revision Print Bun revision (git commit)

bun build Flags

Flag Description
--production Production mode (sets NODE_ENV=production, enables minification)
--compile Produce a standalone executable
--compile-exec-argv <args> Extra argv for embedded binary
--compile-autoload-dotenv / --no-compile-autoload-dotenv Auto-load .env in compiled binary
--compile-autoload-bunfig / --no-compile-autoload-bunfig Auto-load bunfig.toml in compiled binary
--compile-autoload-tsconfig / --no-compile-autoload-tsconfig Auto-load tsconfig.json in compiled binary
--compile-autoload-package-json / --no-compile-autoload-package-json Auto-load package.json in compiled binary
--compile-executable-path <path> Path to a custom Bun binary to embed
--bytecode Emit JSC bytecode
--watch Rebuild on file changes
--no-clear-screen Disable screen clear on rebuild
--target <platform> Target platform: browser, bun, node
--outdir <dir> Output directory
--outfile <file> Output file (single-entry builds)
--metafile Write build metadata JSON
--metafile-md Write build metadata as Markdown
--sourcemap <mode> linked, inline, external, none
--banner <text> Prepend text to output files
--footer <text> Append text to output files
--format <fmt> Output format: esm, cjs, iife
--root <dir> Entry-point root directory
--splitting Enable code splitting
--public-path <path> Public base path for asset URLs
-e, --external <pkg> Mark package as external
--allow-unresolved Allow unresolved imports (no error)
--reject-unresolved Error on unresolved imports
--packages <mode> external or bundle
--entry-naming <pattern> Entry chunk file naming pattern
--chunk-naming <pattern> Non-entry chunk file naming pattern
--asset-naming <pattern> Asset file naming pattern
--react-fast-refresh Enable React Fast Refresh
--no-bundle Transpile only, no bundling
--emit-dce-annotations Emit @__PURE__ annotations in output
--minify Enable all minification
--minify-syntax Minify syntax (fold constants, simplify branches)
--minify-whitespace Remove whitespace
--minify-identifiers Shorten identifier names
--keep-names Preserve function/class .name properties
--css-chunking Enable CSS code splitting
--conditions <c> Conditional package export conditions
--app Enable Bake application mode (experimental)
--server-components Enable server component support (experimental)
--env <mode> Environment variable inlining: inline, prefix*, disable
--windows-hide-console Hide the console window on Windows
--windows-icon <path> Path to .ico for compiled executable
--windows-title <str> Executable title metadata
--windows-publisher <str> Publisher metadata
--windows-version <str> Version metadata
--windows-description <str> Description metadata
--windows-copyright <str> Copyright metadata

bun test Flags

Flag Description
--timeout <ms> Per-test timeout in milliseconds
-u, --update-snapshots Update stored snapshots
--rerun-each <n> Run each test N times
--retry <n> Retry count on test failure
--todo Run test.todo() tests
--only Run only test.only() tests
--pass-with-no-tests Exit 0 when no tests found
--concurrent Run test files concurrently
--randomize Randomize test execution order
--seed <n> Seed for --randomize
--coverage Collect code coverage
--coverage-reporter <reporter> Coverage format: text, lcov, clover
--coverage-dir <dir> Coverage output directory
--bail <n> Stop after N failures
-t, --test-name-pattern <pattern> Filter tests by name (alias: --grep)
--reporter <fmt> Output reporter: junit, dots
--reporter-outfile <path> Reporter output file
--dots Shorthand for --reporter=dots
--only-failures Re-run only failing tests
--max-concurrency <n> Maximum concurrent test files
--path-ignore-patterns <patterns> Glob patterns to exclude
--changed Run only tests for changed files (git-aware)

bun install / bun add / bun remove Flags

Flag Description
-c, --config <path> Path to bunfig.toml
-y, --yarn Write a Yarn v1-compatible yarn.lock
-p, --production Install production dependencies only
--no-save Do not update package.json
--save Always update package.json (default for add)
--ca <cert> Custom CA certificate (PEM string)
--cafile <path> Path to CA certificate bundle
--dry-run Show what would be installed, don't write
--frozen-lockfile Error if bun.lock would change
-f, --force Force re-install (ignore cache)
--cache-dir <dir> Package cache directory
--no-cache Disable the cache
--silent Suppress all output
--quiet Suppress non-essential output
--verbose Verbose output
--no-progress Disable progress indicators
--no-summary Suppress install summary
--no-verify Skip integrity verification (not recommended)
--ignore-scripts Do not run lifecycle scripts
--trust Add package to trustedDependencies
-g, --global Install globally
--cwd <path> Working directory
--backend <mode> Install backend: clonefile, hardlink, symlink, copyfile
--registry <url> Override registry URL
--concurrent-scripts <n> Concurrent lifecycle scripts (default: 5)
--network-concurrency <n> Concurrent network requests (default: 48)
--save-text-lockfile Save human-readable bun.lock text file
--omit <group> Omit dependency groups: dev, optional, peer
--lockfile-only Only update lockfile, do not install
--linker <mode> isolated or hoisted
-d, --dev Save to devDependencies
--optional Save to optionalDependencies
--peer Save to peerDependencies
-E, --exact Save exact version (no range)
-a, --analyze Analyze package for security information
--only-missing Install only packages not yet present
--filter <pattern> Limit to matching workspaces
--latest Install the latest version
-i, --interactive Prompt for confirmation
-r, --recursive Recurse into workspaces

4. Deployment & Scaling

4.1 Docker

Bun publishes official Docker images on Docker Hub under oven/bun.

Image Base Use Case
oven/bun:latest Debian General purpose
oven/bun:alpine Alpine Linux Minimal image size
oven/bun:debian-slim Debian slim Balance of size and compatibility
oven/bun:distroless Distroless Security-hardened, no shell

Tip

Use the distroless variant in production for a minimal attack surface. It contains only the Bun binary and its dependencies — no shell, no package manager, no extra utilities. Debug via bun --inspect over Tailscale or a sidecar.

Multi-stage production Dockerfile:

# Build stage — install dependencies with dev tools available
FROM oven/bun:latest AS deps
WORKDIR /app
COPY package.json bun.lock* ./
RUN bun install --frozen-lockfile

# Production stage — copy only what's needed
FROM oven/bun:distroless AS runner
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
USER nonroot
CMD ["bun", "run", "start"]

Build a standalone executable inside Docker:

FROM oven/bun:latest AS build
WORKDIR /app
COPY . .
RUN bun build --compile --minify --target=bun ./src/index.ts --outfile=server

FROM debian:bookworm-slim AS runner
WORKDIR /app
COPY --from=build /app/server .
EXPOSE 3000
CMD ["./server"]

4.2 Standalone Executables

bun build --compile embeds the entry point and all dependencies into a single self-contained binary. No Bun or Node.js installation is required on the target machine.

# Basic compile
bun build --compile ./src/index.ts --outfile=myapp

# With minification and production mode
bun build --compile --minify --production ./src/index.ts --outfile=myapp

# Cross-compilation (specify target binary)
bun build --compile --target=bun --compile-executable-path=/path/to/bun-linux-x64 \
  ./src/index.ts --outfile=myapp-linux

# Windows-specific metadata
bun build --compile \
  --windows-icon=assets/icon.ico \
  --windows-title="My App" \
  --windows-version="1.0.0.0" \
  --windows-description="My application" \
  ./src/index.ts --outfile=myapp.exe

Dotenv / config autoloading in compiled binaries:

By default, compiled binaries autoload .env, bunfig.toml, tsconfig.json, and package.json from the working directory at runtime. Disable selectively:

bun build --compile \
  --no-compile-autoload-dotenv \
  --no-compile-autoload-bunfig \
  ./src/index.ts --outfile=myapp

4.3 AWS Lambda

packages/bun-lambda provides a Lambda runtime layer that runs Bun-based handlers without the Lambda Node.js runtime.

# Install
bun add bun-lambda

# Handler structure
export const handler = async (event: AWSLambdaEvent) => {
  return { statusCode: 200, body: "Hello" };
};

Publish the layer via the scripts in packages/bun-lambda. The layer ARN is published in the package's README and updated per Bun release.

4.4 Workspaces and Monorepos

Bun supports npm-compatible workspaces defined in the root package.json:

{
  "workspaces": ["packages/*", "apps/*"]
}

Run scripts across workspaces:

# Run "build" in all workspaces in parallel
bun run --filter='*' build --parallel

# Run in matching workspaces only
bun run --filter='@myorg/*' test

# Run sequentially
bun run --filter='*' build --sequential

4.5 Process Management

Bun does not ship a built-in process manager (no equivalent to PM2). For production deployments:

  • systemd (Linux): create a unit file targeting the Bun binary or compiled executable
  • Docker with restart policies: --restart=unless-stopped
  • Kubernetes: treat Bun like any stateless container; liveness/readiness probes via HTTP
# /etc/systemd/system/myapp.service
[Unit]
Description=My Bun App
After=network.target

[Service]
Type=simple
User=app
WorkingDirectory=/opt/myapp
ExecStart=/usr/local/bin/bun run start
Restart=on-failure
RestartSec=5s
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target

5. Operations

5.1 Package Manager Operations

Lockfile

Bun writes bun.lock as a binary lockfile by default. Enable the human-readable text format:

bun install --save-text-lockfile

Or in bunfig.toml:

[install]
saveTextLockfile = true

CI enforcement — never drift from lockfile:

bun install --frozen-lockfile

Trusted Dependencies

Lifecycle scripts (preinstall, postinstall, etc.) run only for packages listed in trustedDependencies. This is a security feature — untrusted packages cannot execute arbitrary code during install.

{
  "trustedDependencies": ["esbuild", "sharp", "@parcel/watcher"]
}

Add trust at install time:

bun add some-package --trust

Vulnerability Audit

# Audit for known vulnerabilities
bun audit

# Machine-readable output
bun audit --json

Patch Management

# Patch a dependency
bun patch <package-name>

# Apply patches
bun patch --commit

5.2 Monitoring & Profiling

Note

CPU and heap profiles are written to the working directory by default. Specify --cpu-prof-dir or --heap-prof-dir to redirect output, especially in production where the working directory may not be writable.

CPU Profiling

# Basic CPU profile (written to <pid>.cpuprofile)
bun --cpu-prof ./server.ts

# Custom name and directory
bun --cpu-prof --cpu-prof-name=server --cpu-prof-dir=/tmp/profiles ./server.ts

# Markdown output for LLM analysis
bun --cpu-prof --cpu-prof-md ./server.ts

# Custom sampling interval (microseconds, default 1000)
bun --cpu-prof --cpu-prof-interval=500 ./server.ts

Heap Profiling

bun --heap-prof ./server.ts
bun --heap-prof --heap-prof-name=server --heap-prof-dir=/tmp/profiles ./server.ts
bun --heap-prof --heap-prof-md ./server.ts

DNS Cache Statistics

const stats = Bun.dns.getCacheStats();
console.log(stats);
// { size, hitCount, missCount, evictionCount }

5.3 Debugging

Bun's debugger is WebSocket-based (Chrome DevTools Protocol). It integrates natively with VS Code via the bun-vscode extension and works with Chrome DevTools.

# Start with inspector (connects immediately)
bun --inspect ./server.ts

# Pause until debugger attaches
bun --inspect-wait ./server.ts

# Break on first line
bun --inspect-brk ./server.ts

# Custom host:port
bun --inspect=0.0.0.0:9229 ./server.ts

VS Code launch configuration:

{
  "type": "bun",
  "request": "launch",
  "name": "Debug server",
  "program": "${workspaceFolder}/src/server.ts",
  "cwd": "${workspaceFolder}",
  "env": {}
}

The BUN_INSPECT_NOTIFY environment variable can be set to a URL that Bun will POST to when the inspector is ready — useful for programmatic debugger attachment in CI.

5.4 Shell Completions

Bun ships completions for bash, zsh, and fish in the completions/ directory (135K chars of completion data). Install them:

# Bash
bun completions >> ~/.bash_completion

# Zsh
bun completions --zsh >> ~/.zshrc

# Fish
bun completions --fish > ~/.config/fish/completions/bun.fish

5.5 File Watching

--watch restarts the process on any change to source files imported by the entry point. --hot reloads changed modules in-place without restarting the process:

# Full restart on change (good for servers with side-effectful startup)
bun --watch ./server.ts

# Module hot-reload (good for stateless handlers)
bun --hot ./server.ts

Warning

--hot does not reset module-level state. If your module stores mutable state at the top level (e.g., a singleton cache), that state persists across reloads. Use --watch if you need a clean state on every change.


6. Performance

6.1 DNS Resolution

Bun uses c-ares on Linux for asynchronous DNS resolution, enabling high concurrency without blocking the event loop. On macOS, it uses the system resolver.

  • Configure resolution order via --dns-result-order <verbatim|ipv4first|ipv6first>
  • .local and .localhost domains always fall back to the system resolver automatically
  • Pre-connect DNS resolution: Bun.dns.lookup() accepts a backend option to select the resolver

6.2 Package Installation Performance

Backend Platform Description
clonefile macOS Copy-on-write via clonefileat() — fastest on APFS
hardlink Linux/macOS Hard links to cached files — fast, saves disk
symlink All Symbolic links to cached files
copyfile All Full file copies — slowest, most compatible
# Override backend
bun install --backend=hardlink

Network concurrency defaults to 48 parallel requests. Raise for faster installs on high-bandwidth connections:

bun install --network-concurrency=96

6.3 HTTP Server

Bun's HTTP server uses µWebSockets (C layer) with direct kernel I/O. No userspace buffering — responses are written directly via writev. Benchmarks show Bun's Bun.serve() outperforming Node.js/Express and Deno on raw throughput.

Bun.serve({
  port: 3000,
  fetch(req) {
    return new Response("Hello");
  },
});

6.4 Memory Tuning

--smol flag: Configures JSC to use a smaller heap. Reduces peak RSS at the cost of more frequent GC pauses and lower throughput. Use in memory-constrained environments (Lambda, small containers):

bun --smol ./server.ts

--zero-fill-buffers: All newly allocated Buffer objects are zero-filled. Adds security at the cost of allocation throughput. Enable for handling untrusted data.

6.5 Bundler Performance Features

  • Tree shaking: Dead code elimination enabled by default. Use --emit-dce-annotations to annotate output with @__PURE__ for downstream tree shakers.
  • Bytecode: --bytecode compiles to JSC bytecode, reducing parse time on cold start.
  • Minification: --minify enables all three: syntax folding, whitespace removal, identifier shortening. Use individually with --minify-syntax, --minify-whitespace, --minify-identifiers.
  • Code splitting: --splitting generates async chunk boundaries for dynamic import().
  • --no-bundle: Transpile-only mode — transforms TypeScript/JSX without bundling. Useful for library builds.

7. Security

Caution

Several flags below weaken security guarantees. They are documented for completeness but should not be used in production without explicit justification.

7.1 TLS Configuration

Bun includes a built-in TLS stack. The CA bundle source is configurable per-process:

Flag Behavior
--use-bundled-ca Use Bun's bundled Mozilla CA bundle (default)
--use-system-ca Use the OS certificate store
--use-openssl-ca Use OpenSSL's certificate store

For mTLS, custom CAs, or self-signed certs in server/client:

const server = Bun.serve({
  tls: {
    cert: Bun.file("./cert.pem"),
    key: Bun.file("./key.pem"),
    ca: Bun.file("./ca.pem"),
  },
  fetch(req) { return new Response("secure"); },
});

7.2 CSRF Protection

Bun.CSRF provides HMAC-based CSRF token generation and verification:

// Generate a token
const token = await Bun.CSRF.generate({
  algorithm: "blake2b256",  // blake2b256 | blake2b512 | sha256 | sha384 | sha512 | sha512-256
  expiry: 3600,             // seconds
  encoding: "base64",
});

// Verify
const valid = await Bun.CSRF.verify(token);

7.3 Password Hashing

// Hash (bcrypt or argon2)
const hash = await Bun.password.hash("mysecret", {
  algorithm: "argon2id",
  memoryCost: 65536,
  timeCost: 2,
});

// Verify
const ok = await Bun.password.verify("mysecret", hash);

7.4 HTML Escaping

Bun.escapeHTML() escapes &, <, >, ", and ' for HTML contexts. The implementation is SIMD-accelerated:

const safe = Bun.escapeHTML(userInput); // 480 MB/s – 20 GB/s on M1X

7.5 Package Manager Security

  • Integrity verification: enabled by default; --no-verify disables it (not recommended)
  • Script sandboxing: lifecycle scripts only run for trustedDependencies
  • Audit: bun audit checks installed packages against the npm advisory database

7.6 Native Addon Security

  • --no-addons: disable all native addon (.node file) loading
  • NAPI compatibility shim exists for Node.js-compatible addons; V8 API coverage is partial
  • Addons have full native code execution capability — treat them the same as native binaries

7.7 Secrets Management

Do not hardcode secrets in source. Bun supports dotenv loading:

bun --env-file=.env.production ./server.ts
bun --no-env-file ./server.ts  # suppress automatic .env loading

For compiled binaries, disable dotenv autoloading if secrets should come from the environment:

bun build --compile --no-compile-autoload-dotenv ./src/index.ts --outfile=myapp

8. Developer Internals

8.1 Repository Structure

oven-sh/bun/
├── src/                  # Core Zig/C++ runtime (3.2M chars)
│   ├── cli/             # CLI argument parsing (1.5M chars)
│   ├── bun.js/          # JSC bindings (782K chars)
│   ├── bun.js/api/      # Bun.* API implementations (985K chars)
│   ├── install/         # Package manager (1M chars)
│   ├── bundler/         # JS bundler (576K chars)
│   ├── ast/             # Parser/transpiler (1.6M chars)
│   ├── http/            # HTTP stack (540K chars)
│   ├── shell/           # Shell interpreter (430K chars)
│   ├── css/             # CSS parser (817K chars)
│   ├── resolver/        # Module resolution (401K chars)
│   ├── sql/             # SQL client protocols (94K chars)
│   ├── s3/              # S3 client (184K chars)
│   ├── valkey/          # Redis client (219K chars)
│   ├── md/              # Markdown parser (458K chars)
│   ├── bake/            # SSR framework (402K chars)
│   ├── threading/       # Thread pool (91K chars)
│   ├── async/           # Async primitives (60K chars)
│   ├── io/              # I/O layer (165K chars)
│   ├── sourcemap/       # Source maps (174K chars)
│   ├── glob/            # Glob matching (100K chars)
│   ├── semver/          # Semver parser (102K chars)
│   ├── allocators/      # Custom allocators (64K chars)
│   ├── safety/          # Debug assertions (18K chars)
│   ├── watcher/         # File watcher (34K chars)
│   ├── node-fallbacks/  # Node.js polyfills (170K chars)
│   ├── napi/            # Node-API shim (146K chars)
│   ├── codegen/         # Binding codegen (451K chars)
│   └── errno/           # Error handling (58K chars)
├── packages/            # npm packages
│   ├── bun-types/       # TypeScript definitions (843K chars)
│   ├── bun-vscode/      # VS Code extension
│   ├── bun-lambda/      # Lambda runtime
│   ├── bun-uws/         # µWebSockets (373K chars)
│   ├── bun-native-plugin-rs/ # Rust plugin SDK
│   ├── bun-debug-adapter-protocol/
│   ├── bun-inspector-protocol/
│   ├── bun-wasm/        # WASM transpiler build
│   ├── bun-error/       # Error formatting
│   ├── bun-plugin-svelte/
│   ├── bun-plugin-yaml/
│   └── bun-build-mdx-rs/
├── test/                # Test suite
│   ├── js/              # JavaScript API tests
│   ├── cli/             # CLI integration tests
│   ├── bundler/         # Bundler tests
│   ├── napi/            # NAPI compatibility tests
│   ├── v8/              # V8 compat layer tests
│   ├── internal/        # Internal module tests
│   ├── bake/            # Bake SSR tests
│   ├── docker/          # Docker build tests
│   └── integration/     # End-to-end integration tests
├── bench/               # Benchmark suite
├── docs/                # Documentation (Mintlify format)
├── completions/         # Shell completions (135K chars)
├── dockerhub/           # Docker image configs
├── misctools/           # Debug tools (GDB/LLDB scripts)
├── scripts/             # Build and CI scripts
│   └── build.ts         # Build profile definitions
├── patches/             # Third-party patches (zlib, libuv, tinycc, etc.)
└── vendor/              # Vendored dependencies (Zig compiler)

8.2 Build System

Bun uses CMake as the top-level build driver, orchestrated through package.json scripts via Bun itself. The Zig compiler is vendored at vendor/zig/.

Key build scripts:

bun run build:debug       # Debug build with ASAN
bun run build:release     # Optimized production build
bun run build:ci          # CI release build
bun run watch             # Incremental zig check (fast feedback)
bun run typecheck         # TypeScript type checking
bun run fmt               # Prettier (JS/TS) + zig fmt + clang-format
bun run lint              # oxlint
bun run test              # Full test suite (requires debug build)
bun run test:release      # Full test suite (against release build)

Build profiles (defined in scripts/build.ts):

Profile Characteristics
debug Debug symbols, ASAN, assertions, no optimization
release -O3, LTO, no assertions, no ASAN
ci-release Like release, CI-specific flags
release-assertions Optimized + runtime assertions
release-asan Optimized + address sanitizer
debug-no-asan Debug symbols, assertions, no ASAN

8.3 Module System Internals

Bun's module resolver (src/resolver/) supports:

  • ESM (import/export)
  • CJS (require()/module.exports)
  • package.json exports field (conditional exports)
  • package.json imports field (package self-referencing)
  • tsconfig.json paths and compilerOptions.baseUrl

Supported loaders (file extension to processing pipeline):

Loader Extensions Description
js .js, .mjs, .cjs JavaScript
jsx .jsx JSX
ts .ts, .mts, .cts TypeScript
tsx .tsx TypeScript + JSX
json .json, .jsonc JSON (parsed, not stringified)
toml .toml TOML (parsed to object)
text .txt, .env Plain text string
file .png, .woff, etc. Asset file (returns URL string)
wasm .wasm WebAssembly module
napi .node Native addon

8.4 Codegen System

src/codegen/ contains TypeScript DSL scripts that generate Zig/C++ binding code at build time. This is how Bun keeps the JSC ↔ Zig interface in sync without handwriting FFI boilerplate.

The codegen runs during the build via Node.js (not Bun — a deliberate bootstrapping choice to avoid circular dependency). Generated files are committed to the repository so contributors without a full build environment can work on TypeScript/test code.

8.5 Internal JavaScript Modules

src/js/internal/ and src/js/builtins/ contain JavaScript modules that are bundled into the Bun binary at build time. These implement:

  • Node.js built-in module polyfills (wrapped around native implementations)
  • Bun.* API helpers
  • Debugger transport (src/js/internal/debugger.ts)
  • Stream, event, and async polyfill layers

Internal modules are loaded via a special module specifier (bun:internal/*) and are not accessible to user code.

8.6 Testing

# Run all tests
bun run test

# Run specific test file
bun test test/js/web/fetch.test.ts

# Run tests matching a pattern
bun test --grep "HTTP"

# Run with coverage
bun test --coverage --coverage-reporter=lcov

# Run only changed files (requires git)
bun test --changed

# Update snapshots
bun test --update-snapshots

# Run NAPI compat tests
bun test test/napi/

Test file locations:

Directory Contents
test/js/ JavaScript Web API tests
test/cli/ CLI command integration tests
test/bundler/ Bundler correctness tests
test/napi/ Node-API (NAPI) compatibility tests
test/napi/node-napi-tests/ Tests ported directly from Node.js
test/v8/ V8 API compatibility layer tests
test/internal/ Internal module tests
test/bake/ Bake SSR framework tests
test/docker/ Docker build validation
test/integration/ End-to-end integration tests
test/snapshots/ Snapshot fixtures (117 files)

Test runner: bun test (self-hosted). CI orchestration: node scripts/runner.node.mjs.

8.7 Contributing — Code Quality

Formatting:

bun run fmt       # Runs Prettier (JS/TS), zig fmt, clang-format

Linting:

bun run lint      # Runs oxlint (config: oxlint.json)

Type checking:

bun run typecheck # tsc --noEmit across packages/bun-types + codegen

Commit practices:

  • Keep Zig, C++, and TypeScript changes in separate commits when possible
  • Generated files in src/codegen/ are committed — do not .gitignore them
  • Large C++ changes to src/bun.js/ require reviewing JSC memory ownership rules

9. Integration Points

9.1 VS Code Extension

packages/bun-vscode provides first-class VS Code integration:

  • Debugger: communicates via Debug Adapter Protocol (DAP) and Chrome Inspector Protocol
  • Run configurations: launch scripts, tests, and the REPL from the IDE
  • package.json schema: inline validation and completion for bun-specific fields

Install from the VS Code marketplace: search for "Bun" by Oven.

The extension connects to Bun's WebSocket inspector at localhost:6499 by default. Override via bunfig.toml:

[debug]
inspector = "localhost:9229"

9.2 Native Plugins (Rust)

packages/bun-native-plugin-rs is a Rust SDK for writing native bundler plugins that integrate at the NAPI layer:

use bun_native_plugin::*;

#[bun_plugin]
fn my_plugin(builder: PluginBuilder) {
    builder.on_load(".custom", |args| {
        Ok(OnLoadResult {
            contents: "export default 42".into(),
            loader: Loader::Js,
        })
    });
}

Proc macros handle the NAPI registration boilerplate. The compiled .node file is loaded by Bun at runtime.

Note

Native plugins have full access to the Bun process's memory and file system. Only load trusted plugins. Consider using JavaScript plugins (the plugin() API) for untrusted or community plugins — they run in the same JS sandbox as user code.

9.3 Node.js Compatibility

Bun maintains extensive Node.js API compatibility via polyfills in src/node-fallbacks/ and src/js/internal/. The following Node.js built-in modules are supported:

Module Notes
process Full compatibility including process.env, process.argv, signals
Buffer Full compatibility; --zero-fill-buffers supported
fs / fs/promises Full async/sync API
path Full compatibility
http / https Backed by Bun's HTTP stack
crypto Backed by BoringSSL/WebCrypto
stream / stream/promises Node.js streams + pipeline
events EventEmitter
child_process spawn, exec, execSync, spawnSync
worker_threads Web Worker-based implementation
net / tls TCP/TLS sockets
dns / dns/promises Backed by c-ares (Linux) / system (macOS)
os System information
url / querystring URL parsing + WHATWG URL
util promisify, inspect, format, etc.
assert Node.js assertion library
zlib Compression (gzip, deflate, brotli)

V8 API compatibility: A partial V8 API shim is available for native addons that use V8 internal APIs. Coverage is not complete — addons built against Node.js internals may not load. Use --no-addons to disable addon loading if addon compatibility issues cause crashes.

9.4 Bun Shell Integration

Bun.$ provides a cross-platform shell for scripting in JavaScript/TypeScript that uses Bun's built-in shell interpreter (src/shell/):

import { $ } from "bun";

// Basic command
const result = await $`ls -la`;

// Interpolation (safe, no injection)
const dir = "./src";
const files = await $`find ${dir} -name "*.ts"`.text();

// Pipe
const count = await $`cat package.json | wc -l`.text();

// Environment
await $`echo $HOME`.env({ HOME: "/custom" });

The shell is not /bin/sh — it is Bun's own interpreter with a POSIX-compatible subset. Redirects, pipes, and basic globbing are supported. Use --shell=system with bun run to use the system shell for package.json scripts.

9.5 Built-in Database Clients

Bun includes built-in clients for PostgreSQL, MySQL, and Redis/Valkey — no npm package required.

PostgreSQL:

import { sql } from "bun";

const rows = await sql`SELECT * FROM users WHERE id = ${userId}`;

Connection is configured via DATABASE_URL, POSTGRES_URL, PGURL, or explicit PGHOST/PGUSER/PGPASSWORD environment variables.

MySQL:

import { sql } from "bun";
// Configured via MYSQL_URL or MYSQL_HOST/PORT/USER/PASSWORD/DATABASE
const rows = await sql`SELECT * FROM products LIMIT 10`;

Redis / Valkey:

import { Redis } from "bun";

const redis = new Redis();  // uses REDIS_URL or VALKEY_URL
await redis.set("key", "value");
const val = await redis.get("key");

Pre-connect at startup for reduced first-request latency:

bun --redis-preconnect --sql-preconnect ./server.ts

9.6 S3 Client

import { S3Client } from "bun";

const s3 = new S3Client({
  accessKeyId: process.env.AWS_ACCESS_KEY_ID,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  bucket: "my-bucket",
  region: "us-east-1",
});

// Write
await s3.write("path/to/file.txt", "content");

// Read
const file = s3.file("path/to/file.txt");
const text = await file.text();

9.7 Bake (Experimental SSR Framework)

src/bake/ implements Bun's experimental server-side rendering framework. Enable via:

bun build --app ./src/index.tsx

Server components support:

bun build --app --server-components ./src/index.tsx

Warning

Bake is experimental. The API surface is not stable and may change without notice between Bun releases. Do not use in production systems without pinning to a specific Bun version and auditing changes at each upgrade.

9.8 Markdown Parser

src/md/ implements a GFM-compatible markdown parser that outputs HTML, ANSI-colored terminal output, or React elements:

import { Markdown } from "bun";

const html = Markdown.toHTML("# Hello\n\n**world**");
const ansi = Markdown.toANSI("# Hello\n\n**world**");