npx skills add ...
npx skills add bun.sh/bun
Use when building, testing, and deploying JavaScript/TypeScript applications. Reach for Bun when you need to run scripts, manage dependencies, bundle code, or test applications with a unified toolkit that replaces Node.js, npm, and other tools.
npx skills add bun.sh/bun
Bun is an all-in-one JavaScript/TypeScript toolkit written in Rust and powered by JavaScriptCore. It replaces Node.js, npm, and other tools with a single binary. Key components:
.js, .ts, .jsx, .tsx files directly with native transpilation (4x faster startup than Node.js)bun install is 25x faster than npm with global caching and workspace supportbun test with TypeScript, snapshots, mocks, and watch modebun build for browser and server bundles with code splitting and pluginsKey files: bunfig.toml (configuration), package.json (scripts and dependencies), bun.lock (lockfile)
Primary docs: https://bun.com/docs
Reach for Bun when:
bun run script.ts)bun install in any Node.js projectbun test and run them in parallelbun buildpackage.json scripts 28x faster than npm (bun run dev)--watch or --hot for file watching and hot reloadingbun install --filter and workspace commandsDo not use Bun for: type checking (use tsc separately), generating type declarations, or projects requiring Node.js-only APIs not yet implemented in Bun.
| Task | Command |
|---|---|
| Run a file | bun run script.ts or bun script.ts |
| Run a script | bun run dev (from package.json) |
| Install dependencies | bun install or bun i |
| Add a package | bun add react or bun add -d @types/node |
| Remove a package | bun remove react |
| Run tests | bun test |
| Build a bundle | bun build ./index.ts --outdir ./dist |
| Watch files | bun --watch run script.ts or bun build --watch |
| Hot reload | bun --hot run server.ts |
| Execute a package | bunx cowsay "Hello" |
| File | Purpose |
|---|---|
bunfig.toml | Bun-specific settings (runtime, test, install, bundler) |
package.json | Scripts, dependencies, workspaces, metadata |
tsconfig.json | TypeScript compiler options (Bun reads this) |
.env | Environment variables (auto-loaded) |
bun.lock | Lockfile (text-based, replaces package-lock.json) |
| Scenario | Use | Reason |
|---|---|---|
| New monorepo/workspace | isolated | Prevents phantom dependencies, strict isolation |
| New single-package project | hoisted | Traditional npm behavior, simpler |
| Existing project (pre-v1.3.2) | hoisted | Backward compatibility |
| Migrating from pnpm | isolated | Similar to pnpm's approach |
Set with: bun install --linker isolated or in bunfig.toml under [install].
| Use Case | Flag | Behavior |
|---|---|---|
| File changes trigger re-run | --watch | Full process restart, clean state |
| HTTP server development | --hot | Soft reload, preserves global state, faster |
| Test development | --watch | Better isolation between runs |
| Library bundling | bun build --watch | Incremental rebuilds |
| Scenario | Command | Why |
|---|---|---|
Run a script from package.json | bun run dev | Respects lifecycle hooks (pre/post) |
| Run a file directly | bun script.ts | Faster, no script lookup |
| Run a local CLI tool | bun run eslint | Resolves from node_modules/.bin |
| Run a system command | bun run ls | Only works with bun run |
This creates package.json, tsconfig.json, index.ts, and .gitignore.
Bun creates bun.lock (text-based lockfile) and node_modules/.
Lifecycle scripts disabled by default: Bun doesn't run postinstall scripts for security. Add packages to trustedDependencies in package.json to allow them.
Flags go after bun, not after the command: Use bun --watch run dev, not bun run dev --watch. Flags at the end are passed to the script itself.
bun run prefers scripts over files: If both a script and file have the same name, bun run runs the script. Use bun run ./file.ts to force file execution.
Environment variables must be literal: process.env.FOO works in bundler, but const env = process.env; env.FOO does not. Use process.env.FOO directly.
Auto-install only works without node_modules: If node_modules exists, Bun uses it. Delete node_modules to enable auto-install from global cache.
Bun.lock is text-based by default: Prior to v1.2, lockfiles were binary (bun.lockb). Upgrade with bun install --save-text-lockfile --frozen-lockfile --lockfile-only.
TypeScript 6+ requires explicit types: Add "types": ["bun"] to tsconfig.json compilerOptions if using TypeScript 6 or later.
Phantom dependencies in hoisted mode: With linker: "hoisted", packages can import undeclared dependencies. Use linker: "isolated" to prevent this.
Test files must match patterns: Bun only discovers *.test.ts, *_test.ts, *.spec.ts, *_spec.ts. Adjust with pathIgnorePatterns in bunfig.toml.
Bundler doesn't type-check: Use tsc --noEmit separately for type checking. Bun's bundler only transpiles.
Before submitting work with Bun:
bun install runs without errorsbun run <script> executes correctlybun test shows all tests passingtsc --noEmit if type checking is neededbun build completes without errors.env file exists with required variablesbun.lock is in version controlbun --watch run dev detects file changesbun --hot run server.ts updates without restartComprehensive navigation: https://bun.com/docs/llms.txt
Critical pages:
For additional documentation and navigation, see: https://bun.com/docs/llms.txt
bun init my-app
# Choose template: Blank, React, or Library
cd my-appbun install
# or add specific packages
bun add react
bun add -d typescript @types/node# Create index.ts with TypeScript/JSX (no compilation needed)
bun run index.ts
# Or add to package.json scripts
# "scripts": { "dev": "bun run index.ts" }
bun run dev# Create math.test.ts
import { test, expect } from "bun:test";
test("2 + 2 = 4", () => {
expect(2 + 2).toBe(4);
});
# Run tests
bun test
bun test --watch
bun test --coverage# Build for browser
bun build ./index.tsx --outdir ./dist --target browser
# Build for Node.js
bun build ./server.ts --outdir ./dist --target node --format cjs
# Build with minification
bun build ./index.ts --outdir ./dist --minify[install]
linker = "isolated"
[test]
coverage = true
coverageThreshold = 0.8
[serve]
port = 3000