Skip to content

Instantly share code, notes, and snippets.

@mimoo
Created October 31, 2025 21:17
Show Gist options
  • Save mimoo/b7987301e16cb234dfcbf6273047c58a to your computer and use it in GitHub Desktop.
Save mimoo/b7987301e16cb234dfcbf6273047c58a to your computer and use it in GitHub Desktop.
Bun succinct documentation for agents

Bun is an all-in-one JavaScript/TypeScript runtime and toolkit designed as a drop-in replacement for Node.js. It's 4x faster startup than Node.js, powered by JavaScriptCore engine, written in Zig. Single executable with no dependencies.

Installation: curl -fsSL https://bun.com/install | bash (macOS/Linux), powershell -c "irm bun.sh/install.ps1|iex" (Windows). Upgrade: bun upgrade. Docker: docker pull oven/bun.

Running code: bun run file.ts or just bun file.ts. Supports TypeScript, JSX, TSX out of the box with native transpiler (no typechecking). Watch mode: bun --watch run file.ts. Run package.json scripts: bun run scriptname (28x faster than npm run).

Package manager: bun install (25x faster than npm), bun add pkg, bun remove pkg. Uses global cache at ~/.bun/install/cache/ with hardlinks/copy-on-write for disk efficiency. Lockfile: bun.lock. Workspaces supported in package.json. For CI: bun ci (frozen lockfile). Installation strategies: hoisted (default) or isolated (--linker isolated). Trust lifecycle scripts via trustedDependencies in package.json. Global installs: bun install -g pkg.

Testing: bun test - Jest-compatible runner. Test files: *.test.{js,jsx,ts,tsx} or *_test.* or *.spec.* or *_spec.*. Uses test(), expect(), describe() from bun:test. Lifecycle hooks: beforeAll, beforeEach, afterEach, afterAll. Supports mocks (mock() or jest.fn()), snapshots (toMatchSnapshot()), watch mode (--watch), filters (-t pattern), timeouts (--timeout ms), concurrent execution (--concurrent), JUnit reports (--reporter=junit). AI-friendly quiet mode with CLAUDECODE=1 or AGENT=1. Always import from bun:test, use bunEnv and bunExe() from harness, prefer normalizeBunSnapshot() for snapshots, use tempDir() for temp dirs, never hardcode ports (use port: 0), verify tests fail with USE_SYSTEM_BUN=1.

HTTP server: Bun.serve({ routes: {...}, fetch(req) {...} }) - returns Server object. Routes support static responses, dynamic params (/users/:id), per-method handlers (GET/POST/etc), wildcards (/api/*). Request has req.params and req.cookies. Hot reload: server.reload(). TLS via tls: { key, cert }. WebSocket upgrade: server.upgrade(req). Unix sockets: unix: "/path.sock". Ports: default 3000, or $BUN_PORT/$PORT/$NODE_PORT, or port: 0 for random. Error handling: error(error) callback. Development mode: development: true. Metrics: server.pendingRequests, server.pendingWebSockets. Per-request timeout: server.timeout(req, seconds). Client IP: server.requestIP(req). Cookies via req.cookies.get/set/delete() with CookieMap. Export default syntax supported. File streaming uses sendfile(2) for zero-copy. 2.5x more requests/sec than Node.js.

File I/O: Bun.file(path) returns BunFile (lazy-loaded). Read: await file.text(), await file.arrayBuffer(), await file.bytes(), await file.stream(), await file.json(). Write: await Bun.write(dest, data) - dest can be path/URL/BunFile, data can be string/Blob/ArrayBuffer/TypedArray/Response. Incremental writes: file.writer() returns FileSink with .write(), .flush(), .end(). Delete: await file.delete(). Check exists: await file.exists(). Use node:fs for directories: import { readdir, mkdir } from "node:fs/promises". stdin/stdout/stderr available as Bun.stdin/stdout/stderr.

SQLite: import { Database } from "bun:sqlite". Open: new Database("file.db") or new Database(":memory:"). Query: db.query(sql) returns Statement. Execute: stmt.all(params) (array of objects), stmt.get(params) (first row), stmt.run(params) (returns {lastInsertRowid, changes}), stmt.values(params) (array of arrays), stmt.iterate() (iterator). Parameters: named ($name, :name, @name) or positional (?1). Bind: pass object or values. Transactions: db.transaction(fn) returns wrapped function. WAL mode: db.exec("PRAGMA journal_mode = WAL;"). Map to class: stmt.as(Class). Strict mode: { strict: true } allows binding without prefixes, throws on missing params. SafeIntegers: { safeIntegers: true } returns bigint for integers. 3-6x faster than better-sqlite3.

Bundler: bun build ./entry.ts --outdir ./out or await Bun.build({ entrypoints: ['./entry.ts'], outdir: './out' }). Target: browser (default), bun, node. Format: esm (default) or cjs. Minify: --minify. Sourcemaps: --sourcemap=external|inline|none. Code splitting: --splitting. Watch: --watch. External packages: --external react. Plugins supported. Assets auto-copied with hash. Dead code elimination and tree shaking built-in. Supports TS, JSX, JSON, TOML, text files. Fastest bundler (faster than esbuild). For Bun target: can create executables with --compile.

Core features: Native TypeScript/JSX (transpiled, not typechecked). Web APIs: fetch, Response, Request, Headers, WebSocket, ReadableStream, WritableStream, TransformStream, Blob, URL, URLSearchParams, crypto, TextEncoder/Decoder, atob/btoa, setTimeout/Interval, console, performance, EventTarget. Node.js compatibility: most packages work, implements node:fs, node:path, node:http, etc. Module resolution: Node-style with node_modules. Import JSON/TOML/YAML directly. Top-level await. Hot module reloading with --hot. Environment variables auto-load from .env to process.env and Bun.env. JSX: configurable via tsconfig.json or bunfig.toml.

Configuration bunfig.toml (optional): [install] for package manager (optional, dev, peer, production, frozenLockfile, linker, minimumReleaseAge). [test] for test runner (root, preload, coverage, coverageThreshold). Runtime settings: preload scripts, jsx config, smol mode, logLevel, define (constant replacement), loader (file extension mapping), telemetry, console.depth. Supports global (~/.bunfig.toml) and local (./bunfig.toml) with shallow merge.

Additional APIs: DNS (bun:dns), FFI (bun:ffi for C bindings), Hashing (Bun.hash, Bun.CryptoHasher), Transpiler (Bun.Transpiler), Process spawning (Bun.spawn, Bun.spawnSync with bunEnv), TCP (Bun.listen, Bun.connect), Glob (import { Glob } from "bun"), HTML Rewriter, Shell (Bun.$), Workers, Semver, Redis client, S3 client, Secrets vault, WebSocket client with deflate support.

Environment: import.meta.env for env vars, import.meta.dir for directory, import.meta.file for filename, import.meta.path for absolute path, import.meta.url for file:// URL. Check Bun runtime: typeof Bun !== "undefined".

Best practices: Use Bun APIs over Node.js when available for performance. Enable WAL mode for SQLite. Use port: 0 for random ports in tests. Prefer Bun.serve routes over manual URL parsing. Use Bun.file for file operations. Configure bunfig.toml for project-wide settings. Use using statement for auto-cleanup. Trust dependencies explicitly for lifecycle scripts. Use strict mode for SQLite parameter validation. Enable safeIntegers for big number handling. Use temp directories with using dir = tempDir() pattern. Avoid setTimeout in tests, await conditions instead.

Common CLI flags: --watch (watch mode), --hot (hot reload), --bun (force Bun runtime for Node scripts), --smol (reduce memory), --inspect (debugger), --port=N (default port), --filter (monorepo filtering), --production (skip dev deps), --frozen-lockfile (fail on mismatch).

Debugging: Built-in debugger with --inspect or --inspect-brk. VSCode debugging supported. Development mode error pages in Bun.serve. Debug logs: BUN_DEBUG_QUIET_LOGS=1 to disable, BUN_DEBUG_scopeName=1 to enable specific scopes.

GitHub Actions: Use oven-sh/setup-bun@v2 action. CI command: bun ci for frozen lockfile installs.

Performance tips: Bun.serve is 2.5x faster than Node http. Bun install is 25x faster than npm. Bun run is 28x faster startup than npm run. SQLite driver is 3-6x faster than better-sqlite3. Bundler faster than esbuild. File operations use optimal syscalls (sendfile, copy_file_range, etc).

TypeScript: No typechecking during runtime/bundling. Use tsc or editor for type errors. tsconfig.json affects runtime: jsx settings, paths, baseUrl, module resolution. Types: Install @types/bun for Bun global types.

Common patterns: HTTP JSON API with routes + SQLite. Full-stack apps with HTML imports (import "./app.html"). Monorepo with workspaces + filters. Tests with tempDir + Bun.spawn. CLI tools with bunx or global install. Docker deploys with oven/bun image. Single-file executables with bun build --compile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment