Bun Fundamentals
Bun runtime overview: all-in-one JavaScript runtime, bundler, test runner, and package manager. Installation, project initialization, Node.js compatibility, performance characteristics, and guidance on when to choose Bun vs Node.
You are an expert in Bun, the high-performance JavaScript and TypeScript runtime built on JavaScriptCore (Safari's engine) and written in Zig. ## Key Points - CommonJS `require()` and ES modules `import` -- Bun supports both, even mixed in the same file - `__dirname`, `__filename` -- work in both ESM and CJS (unlike Node where they are CJS-only) - `process.env`, `process.argv`, `process.cwd()`, `process.exit()` - Most npm packages work without modification - Native Node.js addons (`.node` files built with node-gyp) -- Bun has partial support via its N-API implementation, but complex addons may fail - `node:vm` -- partially implemented, some edge cases differ - `node:inspector` and `node:v8` -- not available (different engine) - Some `node:cluster` features - Packages that rely on V8-specific behavior or internal Node.js APIs 1. **Startup time**: Bun starts 4-5x faster than Node.js because JavaScriptCore has faster initialization and Bun skips the V8 startup overhead 2. **Package installation**: `bun install` is 10-30x faster than npm because it uses a binary lockfile, hardlinks from a global cache, and parallel downloads 3. **File I/O**: Bun's `Bun.file()` and `Bun.write()` use optimized system calls (io_uring on Linux, kqueue on macOS) ## Quick Example ```bash bun --version # 1.2.x ``` ```bash # Set memory limit BUN_JSC_MAX_HEAP_SIZE=4096 bun run server.ts # Enable garbage collection logging BUN_JSC_logGC=1 bun run app.ts ```
skilldb get bun-skills/Bun FundamentalsFull skill: 219 linesBun Fundamentals — The All-in-One JavaScript Toolkit
You are an expert in Bun, the high-performance JavaScript and TypeScript runtime built on JavaScriptCore (Safari's engine) and written in Zig.
What Bun Is
Bun is four tools in one binary: a JavaScript/TypeScript runtime, a package manager, a bundler, and a test runner. It aims to replace Node.js, npm, webpack, and Jest with a single fast tool. Bun natively executes TypeScript, JSX, and TSX files without a separate compilation step. It uses JavaScriptCore (the engine behind Safari) rather than V8, which gives it different performance characteristics -- generally faster startup and lower memory usage for many workloads.
Bun is not a thin wrapper around Node.js. It is a ground-up implementation of the JavaScript runtime with its own event loop, HTTP server, file I/O, and module resolution. It implements most of the Node.js API surface for compatibility, but the internals are entirely different.
Installation
# macOS and Linux (recommended)
curl -fsSL https://bun.sh/install | bash
# Homebrew
brew install oven-sh/bun/bun
# Windows (native support since Bun 1.1)
powershell -c "irm bun.sh/install.ps1 | iex"
# npm (works but defeats the purpose for most use cases)
npm install -g bun
# Docker
FROM oven/bun:1
WORKDIR /app
COPY package.json bun.lockb ./
RUN bun install --frozen-lockfile
COPY . .
CMD ["bun", "run", "start"]
Verify installation:
bun --version
# 1.2.x
Project Initialization
# Create a new project
bun init
# This creates:
# - package.json (with "type": "module" by default)
# - tsconfig.json (TypeScript configured out of the box)
# - index.ts (entry point)
# - README.md
# Create with specific options
bun init --yes # accept all defaults
The generated tsconfig.json uses Bun's recommended settings including "moduleResolution": "bundler" and "types": ["bun-types"] for full API autocompletion.
Running Code
# Run a TypeScript file directly -- no tsc needed
bun run index.ts
# Run a JSX file
bun run app.tsx
# Run a script from package.json
bun run dev
# Use --watch for auto-restart on file changes
bun --watch run index.ts
# Use --hot for hot reloading (preserves state)
bun --hot run server.ts
# Run with environment file
bun --env-file=.env.local run index.ts
The difference between --watch and --hot: watch mode restarts the entire process on file changes (like nodemon). Hot mode reloads modules in-place without restarting, preserving global state and open connections. Use hot mode for HTTP servers during development; use watch mode for CLI tools and scripts.
Node.js Compatibility
Bun implements most Node.js built-in modules. Import them exactly as you would in Node:
import { readFile } from "node:fs/promises";
import { createServer } from "node:http";
import { join } from "node:path";
import { EventEmitter } from "node:events";
// These all work as expected
const data = await readFile("config.json", "utf-8");
What Works
node:fs,node:path,node:os,node:crypto,node:url,node:util,node:events,node:stream,node:buffer,node:http,node:https,node:net,node:tls,node:child_process,node:worker_threads,node:assert,node:zlib,node:string_decoder,node:querystring,node:readline,node:dns- CommonJS
require()and ES modulesimport-- Bun supports both, even mixed in the same file __dirname,__filename-- work in both ESM and CJS (unlike Node where they are CJS-only)process.env,process.argv,process.cwd(),process.exit()- Most npm packages work without modification
What May Not Work
- Native Node.js addons (
.nodefiles built with node-gyp) -- Bun has partial support via its N-API implementation, but complex addons may fail node:vm-- partially implemented, some edge cases differnode:inspectorandnode:v8-- not available (different engine)- Some
node:clusterfeatures - Packages that rely on V8-specific behavior or internal Node.js APIs
// Check if running in Bun
if (typeof Bun !== "undefined") {
console.log("Running in Bun", Bun.version);
} else {
console.log("Running in Node.js", process.version);
}
Performance Characteristics
Bun's performance advantages come from several architectural decisions:
- Startup time: Bun starts 4-5x faster than Node.js because JavaScriptCore has faster initialization and Bun skips the V8 startup overhead
- Package installation:
bun installis 10-30x faster than npm because it uses a binary lockfile, hardlinks from a global cache, and parallel downloads - File I/O: Bun's
Bun.file()andBun.write()use optimized system calls (io_uring on Linux, kqueue on macOS) - HTTP server:
Bun.serve()handles more requests per second than Node'shttp.createServerfor most workloads - TypeScript: No transpilation step -- Bun strips types at parse time rather than running tsc or swc first
Where Node.js may still win:
- Long-running computation-heavy tasks where V8's JIT optimizer has time to fully optimize hot paths
- Workloads that depend on V8's highly-tuned garbage collector for large heaps
- Specific native addon ecosystems (e.g., some ML libraries with V8-specific bindings)
When to Use Bun vs Node.js
Choose Bun when:
- Starting a new project without legacy constraints
- Developer experience and iteration speed matter (instant TypeScript, fast installs)
- Building HTTP APIs where startup time and request throughput matter
- Writing scripts, CLI tools, or automation (fast startup is critical)
- You want fewer tools in your toolchain (no separate bundler, test runner, or package manager)
Choose Node.js when:
- You depend on native addons that are not yet Bun-compatible
- Your production environment requires LTS-level stability guarantees
- You need V8-specific debugging tools (Chrome DevTools integration,
--inspect) - Your team or organization has deep Node.js operational expertise
- You use frameworks with known Bun incompatibilities (check framework docs)
Anti-Patterns
- Assuming Bun is a drop-in Node.js replacement for all projects: While compatibility is high, test your specific dependencies before committing. Run your test suite under Bun early to catch issues.
- Using
bun runfor everything instead of directbunexecution: For your own files,bun index.tsis sufficient. Usebun runfor package.json scripts. - Ignoring the bun.lockb file: The binary lockfile should be committed to version control. It ensures reproducible installs across machines.
- Mixing package managers: Do not alternate between npm, yarn, and bun install in the same project. Pick one and stick with it. Delete
node_modulesand the old lockfile when switching. - Not using Bun-native APIs: If you are running on Bun, use
Bun.file()instead offs.readFile()andBun.serve()instead ofhttp.createServer(). The native APIs are faster and more ergonomic. - Expecting identical behavior in edge cases: Bun's module resolution, error stack traces, and timing behavior can differ from Node.js in subtle ways. Write tests rather than assuming parity.
Configuration
Bun reads configuration from bunfig.toml at the project root:
# bunfig.toml
[install]
# Registry configuration
registry = "https://registry.npmjs.org/"
[install.cache]
# Global cache directory
dir = "~/.bun/install/cache"
[test]
# Test configuration
coverage = true
coverageReporter = ["text", "lcov"]
[run]
# Shell to use for bun run scripts
shell = "bash"
Environment variables can also configure Bun:
# Set memory limit
BUN_JSC_MAX_HEAP_SIZE=4096 bun run server.ts
# Enable garbage collection logging
BUN_JSC_logGC=1 bun run app.ts
Quick Reference
bun init # new project
bun run file.ts # run a file
bun run script-name # run package.json script
bun install # install dependencies
bun add package # add dependency
bun test # run tests
bun build ./src/index.ts # bundle for production
bun --watch run file.ts # restart on changes
bun --hot run server.ts # hot reload on changes
bun upgrade # upgrade bun itself
bun repl # interactive REPL
Install this skill directly: skilldb add bun-skills
Related Skills
Bun Bundler
Bun's built-in bundler: Bun.build() API, entry points, output formats (esm, cjs, iife), plugins, loaders, tree shaking, code splitting, CSS bundling, HTML entries, and compile-time macros.
Bun HTTP Server
Building HTTP servers with Bun: Bun.serve() API, routing patterns, WebSocket support, streaming responses, static file serving, TLS configuration, hot reloading, and integration with frameworks like Hono and Elysia.
Bun Node.js Migration
Migrating from Node.js to Bun: compatibility checklist, node:* module imports, native addon handling, environment variable differences, Docker setup, CI/CD pipeline changes, and common migration pitfalls.
Bun Package Manager
Bun as a package manager: bun install, bun add, bun remove, the binary lockfile (bun.lockb), workspace support, overrides, patching, publishing packages, global cache, and comparison to npm, pnpm, and yarn.
Bun Production Patterns
Production patterns for Bun: Docker deployments, TypeScript configuration, shell scripting with Bun.$, monorepo setup, database access patterns, and deployment to Fly.io and Railway.
Bun Runtime APIs
Bun-native runtime APIs including Bun.serve(), Bun.file(), Bun.write(), Bun.spawn(), Bun.sleep(), Bun.env, FFI for calling native libraries, built-in SQLite, S3 client, glob, and semver utilities.