Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/zhcndoc/bun/llms.txt

Use this file to discover all available pages before exploring further.

bunfig.toml is Bun’s configuration file for customizing runtime behavior, package management, and build settings.

Location

Bun searches for bunfig.toml in these locations (in order):
  1. Current directory: ./bunfig.toml
  2. Parent directories (walks up)
  3. User home: ~/.bunfig.toml or $BUN_CONFIG_PATH
  4. System-wide: /etc/bunfig.toml (Linux)
Project-specific bunfig.toml overrides user/system configuration.

Basic Structure

bunfig.toml
# Runtime configuration
preload = ["./setup.ts"]
logLevel = "info"

# Environment variables
[env]
file = [".env", ".env.local"]

# Package manager
[install]
registry = "https://registry.npmjs.org/"

# Development server
[dev]
port = 3000

Runtime Configuration

Log Level

Control console output verbosity:
Log level
logLevel = "debug" # debug, info, warn, error
Implementation: src/bunfig.zig:109-123 - Log level parsing

Preload Scripts

Execute scripts before main entry point:
Preload
preload = [
  "./setup.ts",
  "./polyfills.ts",
  "./instrumentation.ts"
]
Use cases:
  • Environment setup
  • Polyfills
  • Global initialization
  • Monkey-patching
Implementation: src/bunfig.zig:125-149 - Preload parsing

Environment Variables

Configure .env file loading:
Environment configuration
[env]
# Disable default .env loading
file = false

# Or specify custom files
file = [".env", ".env.custom"]
Environment object
[env]
file = { file = false }  # Disable
Implementation: src/bunfig.zig:151-186 - Env config parsing

Package Manager

Configure bun install behavior:

Registry

Custom npm registry:
Registry
[install]
registry = "https://registry.npmjs.org/"

# With authentication
registry = "https://username:password@registry.example.com/"
Registry object
[install.registry]
url = "https://registry.example.com/"
username = "user"
password = "pass"
token = "npm_xxx"
Implementation: src/bunfig.zig:45-107 - Registry parsing

Scoped Registries

Different registries per scope:
Scoped registries
[install.scopes]
"@mycompany" = "https://npm.mycompany.com/"
"@other" = { url = "https://npm.other.com/", token = "xxx" }

Cache

Configure package cache:
Cache configuration
[install]
cache = "~/.bun/install/cache" # Custom cache directory
cache = false # Disable cache

Lockfile

Lockfile behavior:
Lockfile
[install]
lockfile = true  # Generate/update lockfile (default)
lockfile = false # Disable lockfile

Production

Skip devDependencies:
Production install
[install]
production = true # Skip devDependencies

Optional Dependencies

Optional deps
[install]
optional = true  # Install optionalDependencies (default)
optional = false # Skip optionalDependencies

Exact Versions

Exact versions
[install]
exact = true # Install exact versions from lockfile

Frozen Lockfile

Frozen lockfile
[install]
frozenLockfile = true # Error if lockfile would change

Dry Run

Dry run
[install]
dryRun = true # Simulate install without writing files

Development Server

Configure bun --hot:
Dev server
[dev]
port = 3000
host = "localhost"

Test Runner

Configure bun test:
Test configuration
[test]
# Test file pattern
preload = ["./test-setup.ts"]

Build Configuration

Configure bun build:
Build config
[build]
# Loader configuration
[build.loader]
".txt" = "text"
".data" = "json"
".png" = "file"

Loader Configuration

Map file extensions to loaders:
Loaders
[loader]
".js" = "jsx"       # Treat .js as JSX
".data" = "json"    # Parse .data as JSON
".txt" = "text"     # Load .txt as text
".svg" = "text"     # SVG as text
".graphql" = "text" # GraphQL as text
See Loaders documentation for available loaders.

Macro Configuration

Configure build-time macros:
Macros
[macros]
# Import replacements
"react" = "preact/compat"

Define

Replace identifiers at build time:
Define
[define]
PROCESS_ENV_NODE_ENV = '"production"'
VERSION = '"1.0.0"'
API_URL = '"https://api.example.com"'
Usage in code:
Using defines
console.log(VERSION); // "1.0.0"
console.log(API_URL); // "https://api.example.com"

if (PROCESS_ENV_NODE_ENV === "production") {
  // Production-only code
}

External Dependencies

Mark packages as external (not bundled):
External
external = ["fsevents", "lightningcss"]

Compilation

Enable/disable features:
Compilation
[compile]
# Native compilation settings

Example Configurations

Minimal Configuration

Minimal bunfig.toml
logLevel = "info"

Development Setup

Development bunfig.toml
logLevel = "debug"
preload = ["./dev-setup.ts"]

[env]
file = [".env.development", ".env.local"]

[install]
cache = true
lockfile = true

[dev]
port = 3000

Production Setup

Production bunfig.toml
logLevel = "error"

[env]
file = ".env.production"

[install]
production = true
frozenLockfile = true
cache = "~/.bun/cache"

[define]
PROCESS_ENV_NODE_ENV = '"production"'

Monorepo Configuration

Monorepo bunfig.toml
logLevel = "info"

[install]
workspace = true
hoistPattern = ["*"]

[install.scopes]
"@myorg" = "https://npm.myorg.com/"

[loader]
".tsx" = "tsx"
".graphql" = "text"

Custom Registry

Custom registry
[install.registry]
url = "https://npm.internal.company.com/"
token = "${NPM_TOKEN}"

[install.scopes]
"@company" = "https://npm.internal.company.com/"
"@public" = "https://registry.npmjs.org/"

TOML Syntax

Bun uses standard TOML format:
TOML syntax
# Comments
# Single line comment

# Strings
string = "double quotes"
singleQuote = 'single quotes'
multiline = """
Line 1
Line 2
"""

# Numbers
integer = 42
float = 3.14

# Booleans
bool = true

# Arrays
array = [1, 2, 3]
mixed = ["a", 1, true]

# Tables (objects)
[section]
key = "value"

# Nested tables
[section.subsection]
key = "value"

# Inline tables
inline = { key = "value", another = 42 }

# Array of tables
[[items]]
name = "First"

[[items]]
name = "Second"

Environment Variable Expansion

Reference environment variables:
Environment variables
[install.registry]
url = "https://npm.company.com/"
token = "${NPM_TOKEN}" # Expands process.env.NPM_TOKEN

[define]
API_URL = '"${API_URL}"' # Expands process.env.API_URL

Configuration Validation

Bun validates bunfig.toml on startup:
Validate config
bun run app.ts
# Error: Invalid Bunfig: Unknown key "invalidKey"

Debugging Configuration

Debug config
BUN_DEBUG_QUIET_LOGS=0 bun run app.ts 2>&1 | grep -i bunfig

Check Config Location

Check config
import { bunfigPath } from "bun";
console.log(bunfigPath); // Path to loaded bunfig.toml

Implementation

Configuration parsing implementation:
  • Parser: src/bunfig.zig - TOML parsing and validation
  • Options: src/options.zig - Configuration options
  • INI parser: src/ini.zig - TOML/INI parsing utilities
Bunfig structure (src/bunfig.zig:7-18)
pub const Bunfig = struct {
    pub const OfflineMode = enum {
        online,
        latest,
        offline,
    };
    pub const Prefer = bun.ComptimeStringMap(OfflineMode, .{
        &.{ "offline", OfflineMode.offline },
        &.{ "latest", OfflineMode.latest },
        &.{ "online", OfflineMode.online },
    });
};

Common Patterns

Multi-Environment Setup

Use environment-specific configs:
Project structure
.
├── bunfig.toml          # Base config
├── bunfig.dev.toml      # Development overrides
├── bunfig.prod.toml     # Production overrides
└── package.json
package.json scripts
{
  "scripts": {
    "dev": "cp bunfig.dev.toml bunfig.toml && bun run src/index.ts",
    "prod": "cp bunfig.prod.toml bunfig.toml && bun run src/index.ts"
  }
}

Workspace Configuration

Configure for monorepos:
Workspace bunfig.toml (root)
[install]
workspace = true

[install.workspaces]
packages = ["packages/*"]

Troubleshooting

Config Not Loading

  1. Check file location: Must be in project root or home directory
  2. Check file name: Must be exactly bunfig.toml
  3. Check TOML syntax: Use TOML validator
  4. Check permissions: File must be readable

Invalid Configuration

error: Invalid Bunfig: Expected "registry" to be a URL string or an object
Solution: Check TOML syntax and field types.

Registry Authentication

For private registries:
Registry auth
[install]
registry = "https://npm.company.com/"

# Or with token
[install.registry]
url = "https://npm.company.com/"
token = "npm_xxxxxxxxxxxx"

Build docs developers (and LLMs) love