Bun Runtime - Fast JavaScript Runtime
Purpose
Expert guidance for Bun:
- •Package Management - Fast installation
- •Bundling - Built-in bundler
- •Testing - Vitest-compatible runner
- •Scripts - Task runner
- •APIs - Bun-specific features
Package Management
Install Dependencies
bash
# Install all dependencies bun install # Add dependency bun add zod mongoose # Add dev dependency bun add -D typescript @types/node # Add exact version bun add react@18.2.0 # Add from GitHub bun add github:user/repo # Remove dependency bun remove lodash # Update dependencies bun update # Update specific package bun update react
bunfig.toml
toml
# bunfig.toml [install] # Disable postinstall scripts for security ignorescripts = true # Registry configuration registry = "https://registry.npmjs.org" # Install settings frozen-lockfile = true [run] # Shell for scripts shell = "bash"
Script Commands
package.json Scripts
json
{
"scripts": {
"dev": "bun run --hot src/index.ts",
"start": "bun run src/index.ts",
"build": "bun build src/index.ts --outdir dist",
"typecheck": "bunx tsc --noEmit",
"lint": "bunx eslint . --ext .ts,.tsx",
"lint:fix": "bunx eslint . --ext .ts,.tsx --fix",
"test": "bun test",
"test:watch": "bun test --watch",
"test:coverage": "bun test --coverage"
}
}
Running Scripts
bash
# Run script bun run dev bun run build # Shorthand (without "run") bun dev bun build # Run TypeScript directly bun run src/index.ts # Hot reload bun run --hot src/index.ts # Watch mode bun run --watch src/index.ts
Bundling
Basic Bundle
bash
# Bundle for browser bun build ./src/index.ts --outdir ./dist # Minify bun build ./src/index.ts --outdir ./dist --minify # Source maps bun build ./src/index.ts --outdir ./dist --sourcemap # Target bun build ./src/index.ts --outdir ./dist --target=browser bun build ./src/index.ts --outdir ./dist --target=node bun build ./src/index.ts --outdir ./dist --target=bun
Build API
typescript
// build.ts
const result = await Bun.build({
entrypoints: ['./src/index.ts'],
outdir: './dist',
target: 'browser',
minify: true,
sourcemap: 'external',
splitting: true,
format: 'esm',
define: {
'process.env.NODE_ENV': '"production"',
},
external: ['react', 'react-dom'],
});
if (!result.success) {
console.error('Build failed:');
for (const log of result.logs) {
console.error(log);
}
process.exit(1);
}
Testing (Vitest-compatible)
Test Configuration
typescript
// bunfig.toml [test]; preload = ['./tests/setup.ts']; coverage = true;
Test File
typescript
// tests/example.test.ts
import { describe, test, expect, beforeEach, afterEach } from 'bun:test';
describe('Feature', () => {
beforeEach(() => {
// Setup
});
afterEach(() => {
// Cleanup
});
test('should work correctly', () => {
const result = 1 + 1;
expect(result).toBe(2);
});
test('async operations', async () => {
const data = await fetchData();
expect(data).toBeDefined();
});
});
Mocking
typescript
import { mock, spyOn } from 'bun:test';
// Mock function
const mockFn = mock((x: number) => x * 2);
mockFn(5);
expect(mockFn).toHaveBeenCalledWith(5);
expect(mockFn).toHaveReturnedWith(10);
// Spy on existing function
const spy = spyOn(console, 'log');
console.log('test');
expect(spy).toHaveBeenCalledWith('test');
Bun APIs
File System
typescript
// Read file
const text = await Bun.file('path/to/file.txt').text();
const json = await Bun.file('path/to/file.json').json();
const buffer = await Bun.file('path/to/file.bin').arrayBuffer();
// Write file
await Bun.write('output.txt', 'Hello, World!');
await Bun.write('output.json', JSON.stringify({ hello: 'world' }));
// File info
const file = Bun.file('file.txt');
console.log(file.size);
console.log(file.type);
HTTP Server
typescript
// Simple server
Bun.serve({
port: 3000,
fetch(request) {
const url = new URL(request.url);
if (url.pathname === '/api/hello') {
return Response.json({ message: 'Hello!' });
}
return new Response('Not Found', { status: 404 });
},
});
// With WebSocket
Bun.serve({
port: 3000,
fetch(request, server) {
if (server.upgrade(request)) {
return;
}
return new Response('Upgrade failed', { status: 500 });
},
websocket: {
open(ws) {
console.log('Client connected');
},
message(ws, message) {
ws.send(`Echo: ${message}`);
},
close(ws) {
console.log('Client disconnected');
},
},
});
Subprocess
typescript
// Run command
const result = Bun.spawn(['echo', 'Hello']);
await result.exited;
// Capture output
const proc = Bun.spawn(['git', 'status'], {
stdout: 'pipe',
});
const output = await new Response(proc.stdout).text();
// With stdin
const proc = Bun.spawn(['cat'], {
stdin: 'pipe',
stdout: 'pipe',
});
proc.stdin.write('Hello from stdin!');
proc.stdin.end();
Password Hashing
typescript
// Hash password
const hash = await Bun.password.hash('my-password', {
algorithm: 'bcrypt',
cost: 10,
});
// Verify password
const isValid = await Bun.password.verify('my-password', hash);
Environment Variables
typescript
// Access env vars const apiKey = Bun.env['API_KEY']; const nodeEnv = Bun.env['NODE_ENV'] ?? 'development'; // Set env vars Bun.env['CUSTOM_VAR'] = 'value';
Performance Tips
Use Native APIs
typescript
// Prefer Bun APIs over Node.js equivalents
// File reading
// Node.js way (slower)
import { readFile } from 'fs/promises';
const content = await readFile('file.txt', 'utf-8');
// Bun way (faster)
const content = await Bun.file('file.txt').text();
Import Optimization
typescript
// Use namespace imports for tree-shaking
import * as z from 'zod';
// Avoid dynamic imports in hot paths
// Bad:
async function validate(data: unknown) {
const { z } = await import('zod');
return z.object({}).parse(data);
}
// Good:
import { z } from 'zod';
function validate(data: unknown) {
return z.object({}).parse(data);
}
Bundle for Production
bash
# Compile to single executable bun build --compile ./src/index.ts --outfile myapp # Run compiled binary ./myapp
Docker Integration
dockerfile
# Use Bun official image FROM oven/bun:1-alpine AS base # Install dependencies FROM base AS deps WORKDIR /app COPY package.json bun.lockb ./ RUN bun install --frozen-lockfile # Build FROM base AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . RUN bun run build # Runtime FROM base AS runner WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/package.json ./ EXPOSE 3000 CMD ["bun", "run", "dist/index.js"]
Agent Integration
This skill is used by:
- •bun-runtime-expert agent
- •quality-checker for running tests
- •build-error-fixer for build issues
- •dockerfile-optimizer for Docker builds
FORBIDDEN
- •
npmcommands - Usebuninstead - •Node.js fs when Bun.file works - Use native APIs
- •Ignoring lockfile - Always use
--frozen-lockfilein CI - •Skipping typecheck - Run
bunx tsc --noEmit
Version
- •v1.0.0 - Initial implementation based on Bun 1.x patterns