Agent skill

bun-runtime

Bun runtime patterns and best practices. Package management, bundling, testing, scripts. Use when working with Bun as the JavaScript runtime.

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/bun-runtime

SKILL.md

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

  1. npm commands - Use bun instead
  2. Node.js fs when Bun.file works - Use native APIs
  3. Ignoring lockfile - Always use --frozen-lockfile in CI
  4. Skipping typecheck - Run bunx tsc --noEmit

Version

  • v1.0.0 - Initial implementation based on Bun 1.x patterns

Expand your agent's capabilities with these related and highly-rated skills.

Didn't find tool you were looking for?

Be as detailed as possible for better results