Bun

SKILL.md

Bun Skill

Product summary

Bun is an all-in-one JavaScript/TypeScript toolkit that replaces Node.js, npm, and bundlers with a single fast binary. It includes a runtime (powered by JavaScriptCore), package manager, test runner, and bundler—all optimized for speed. Key files: bunfig.toml (configuration), bun.lock (lockfile), package.json (scripts and dependencies). Primary CLI commands: bun run, bun install, bun test, bun build. Bun is a drop-in replacement for Node.js in most projects and works with existing npm packages. See https://bun.com/docs for comprehensive documentation.

When to use

  • Running scripts and files: Execute .ts, .tsx, .js, .jsx files directly without compilation overhead. Use bun run <file> or bun <file>.
  • Package management: Install dependencies 25x faster than npm with bun install. Manage workspaces, registries, and lockfiles.
  • Testing: Run Jest-compatible tests with bun test. Supports TypeScript, snapshots, mocking, watch mode, and concurrent execution.
  • Bundling: Bundle TypeScript, JSX, React, and CSS for browsers or servers with bun build. Supports code splitting, minification, and sourcemaps.
  • Migrating from Node.js: Drop-in replacement for Node.js projects. Supports CommonJS and ESM, Node.js APIs, and npm packages.
  • Performance-critical workflows: Startup is 4x faster than Node.js; bun run is 28x faster than npm run.

Quick reference

Essential commands

Task Command
Run a file bun run index.ts or bun index.ts
Run a script bun run dev (from package.json)
Install dependencies bun install
Add a package bun add react
Add dev dependency bun add -d typescript
Remove a package bun remove react
Run tests bun test
Build/bundle bun build ./index.ts --outdir ./out
Watch mode bun --watch run index.ts or bun build --watch
Execute npm package bunx cowsay "Hello"

File types supported (no compilation needed)

  • .js, .jsx, .ts, .tsx — transpiled on the fly
  • .json, .jsonc, .toml, .yaml — imported as objects
  • .css — bundled together
  • .html — processed with asset bundling
  • .wasm, .node — supported by runtime, treated as assets in bundler

Configuration file: bunfig.toml

Located at project root or ~/.bunfig.toml (global). Optional; Bun works without it.

[install]
dev = true                    # install devDependencies
optional = true               # install optionalDependencies
peer = true                   # install peerDependencies
production = false            # production mode (no devDeps)
linker = "hoisted"            # "hoisted" or "isolated"
registry = "https://registry.npmjs.org"

[test]
root = "."                    # test directory
coverage = false              # enable coverage
coverageThreshold = 0.9       # fail if below threshold
preload = ["./setup.ts"]      # run before tests

[run]
shell = "system"              # "system" or "bun"
bun = true                    # alias `node` to `bun` in scripts
silent = false                # suppress command output

[define]
"process.env.API_URL" = "'https://api.example.com'"

Package.json scripts

{
  "scripts": {
    "dev": "bun run src/index.ts",
    "build": "bun build ./src/index.ts --outdir ./dist",
    "test": "bun test",
    "start": "bun run dist/index.js"
  }
}

Run with bun run dev (28x faster than npm run dev).

Decision guidance

Scenario Use Why
Module format ESM (default) Recommended for new projects; Bun supports both ESM and CommonJS
Installation strategy hoisted (default for single packages) Traditional npm behavior; use isolated for monorepos to prevent phantom dependencies
Bundler target browser (default) For client-side code; use bun for server code, node for Node.js compatibility
Bundler format esm (default) Standard module format; use cjs for CommonJS, iife for browser globals
Test execution Sequential (default) Safer for tests with shared state; use --concurrent for independent tests
Lockfile format bun.lock (text, default since v1.2) Human-readable; use --save-text-lockfile to migrate from binary bun.lockb
Registry npm (default) Use private registries via bunfig.toml [install.scopes] for org packages

Workflow

1. Initialize a project

bun init my-app
cd my-app

Creates package.json, tsconfig.json, .gitignore, and index.ts.

2. Install dependencies

bun install

Reads package.json, creates bun.lock, installs to node_modules/. 25x faster than npm.

3. Add packages

bun add react
bun add -d @types/react typescript

Updates package.json and bun.lock.

4. Write and run code

# Create index.ts with TypeScript/JSX
bun run index.ts
# or
bun index.ts

No compilation step needed; Bun transpiles on the fly.

5. Define scripts in package.json

{
  "scripts": {
    "dev": "bun run src/index.ts",
    "build": "bun build ./src/index.ts --outdir ./dist"
  }
}

6. Run scripts

bun run dev
bun run build

7. Write tests

// math.test.ts
import { test, expect } from "bun:test";

test("2 + 2 = 4", () => {
  expect(2 + 2).toBe(4);
});

8. Run tests

bun test                    # run all tests
bun test --watch            # watch mode
bun test --coverage         # with coverage
bun test -t "2 + 2"         # filter by name

9. Bundle for production

bun build ./src/index.ts --outdir ./dist --minify

Outputs optimized bundles with sourcemaps.

10. Verify and commit

Check bun.lock is committed, node_modules/ is in .gitignore, and tests pass before pushing.

Common gotchas

  • Lifecycle scripts disabled by default: Bun does not run postinstall scripts for security. Add trusted packages to trustedDependencies in package.json to allow them.
  • bun run flag placement: Put Bun flags immediately after bun, not at the end: bun --watch run dev ✓, not bun run dev --watch ✗.
  • Module resolution order: bun run <script> prioritizes package.json scripts over files. Use bun run ./file.ts (with ./) to run a file instead.
  • Phantom dependencies in hoisted mode: With linker = "hoisted", packages can access undeclared dependencies. Use linker = "isolated" in monorepos to prevent this.
  • TypeScript types: Install @types/bun as a dev dependency for type hints on the Bun global: bun add -d @types/bun.
  • Lockfile format: Old projects may have binary bun.lockb. Migrate to text format with bun install --save-text-lockfile --frozen-lockfile --lockfile-only.
  • Auto-install disabled in production: Set install.auto = "disable" in bunfig.toml for CI/CD to prevent unexpected package installations.
  • Node.js compatibility incomplete: Not all Node.js APIs are implemented. Check the compatibility page before relying on specific modules.
  • Bundler does not typecheck: Use tsc separately for type checking; bun build only transpiles.
  • Test files must match patterns: Tests are discovered by filename: *.test.ts, *_test.ts, *.spec.ts, *_spec.ts. Files outside these patterns are ignored.

Verification checklist

Before submitting work with Bun:

  • bun install runs without errors and bun.lock is created
  • bun run <script> executes the intended script
  • bun test passes all tests (or bun test --coverage meets threshold)
  • bun build produces output in the specified --outdir
  • TypeScript files have no type errors (run tsc --noEmit separately if needed)
  • bunfig.toml is present if custom configuration is needed
  • package.json has correct "scripts" and dependencies
  • bun.lock is committed to version control
  • node_modules/ is in .gitignore
  • No postinstall scripts are required, or they are in trustedDependencies
  • Tests run in CI/CD with bun ci (equivalent to bun install --frozen-lockfile)

Resources


For additional documentation and navigation, see: https://bun.com/docs/llms.txt

Weekly Installs
97
First Seen
14 days ago
Installed on
opencode96
gemini-cli95
amp95
cline95
cursor95
kimi-cli95