- Try to keep things in one function unless composable or reusable
- DO NOT do unnecessary destructuring of variables
- DO NOT use
elsestatements unless necessary - DO NOT use
try/catchif it can be avoided - AVOID
try/catchwhere possible - AVOID
elsestatements - AVOID using
anytype - AVOID
letstatements - PREFER single word variable names where possible
- Use as many bun apis as possible like Bun.file()
Tools must be designed for agents, not humans. Build few high-impact tools that match natural workflows, return only high-signal context, and optimize for token efficiency. More tools ≠ better outcomes.
- Use Bun as the primary package manager and runtime for development (not npm)
- All scripts and development workflows are optimized for Bun's performance
File Operations
- Use
Bun.file()for reading files instead offs.readFile() - Use
Bun.write()for writing files instead offs.writeFile() - Leverage
Bun.file().text(),.json(),.arrayBuffer(),.stream()for different data formats - Use
Bun.stdin,Bun.stdout,Bun.stderrfor stream operations
HTTP & Networking
- Use
Bun.serve()for high-performance HTTP servers instead of Express/Fastify - Leverage native
fetch()for HTTP requests - Use
Bun.spawn()for child processes instead ofchild_process.spawn() - Utilize WebSocket support via
new WebSocket()andBun.serve()websocket handlers
TypeScript & JSX
- Execute TypeScript files directly with
bun run- no transpilation needed - Use
bunfig.tomlfor TypeScript configuration instead of separatetsconfig.jsonwhen possible - Leverage native JSX support without Babel
Async Operations
- Use
async/awaitfor all I/O operations - never block the event loop - Use
Promise.all()for concurrent operations when possible - Use
Bun.sleep()for non-blocking delays instead ofsetTimeout() - Avoid synchronous file operations - always use async variants
Memory Management
- Use
Bun.gc()to manually trigger garbage collection when needed - Prefer streaming large files instead of loading entirely into memory
- Use
Bun.file()lazy loading - files aren't read until accessed - Monitor memory usage with
process.memoryUsage()
Bundle & Build
- Use
bun buildfor production bundling with--minifyand--target=bun - Leverage tree shaking - import only what you need:
import debounce from "lodash/debounce" - Use
--compileto create single-file executables for deployment - Enable source maps in production with
--sourcemap
Dependencies
- Use
bun installinstead ofnpm install- 20x faster installation - Use
bun addfor adding dependencies,bun removefor removal - Leverage
bun.lockbbinary lockfile for faster dependency resolution - Use
bunxfor executing packages without installation
Scripts & Workflow
- Use
bun --hotfor development with hot reloading - Use
bun testfor Jest-compatible testing - 100x faster than Jest - Use
bun runfor package.json scripts - Enable watch mode with
--watchflag
SQLite Integration
- Use
bun:sqlitefor built-in SQLite database operations - Leverage in-memory databases with
new Database(':memory:') - Use prepared statements for performance:
db.prepare('SELECT * FROM users WHERE id = ?') - Close database connections:
db.close()
Environment Configuration
- Use
.envfiles - Bun loads them automatically intoprocess.env - Access environment via
Bun.envinstead ofprocess.envwhen possible - Use
bunfig.tomlfor runtime configuration
Testing
- Use
bun:testfor Jest-compatible testing without external dependencies - Use
test.concurrent()for parallel test execution - Use
--watchmode for test-driven development - Use
--coveragefor code coverage reporting
Development Tools
- Use
bun fmtfor code formatting - Use
bun lintfor linting (when available) - Use
--inspectfor debugging with VS Code or browser devtools - Leverage
import.metafor module metadata:import.meta.main,import.meta.path
Error Patterns
- Use structured error handling with meaningful error messages
- Leverage Bun's improved stack traces for debugging
- Use
console.time()andconsole.timeEnd()for performance profiling - Use
Bun.peek()for inspecting objects without triggering getters
Production Deployment
- Use
bun build --compilefor creating standalone executables - Set
NODE_ENV=productionfor production optimizations - Use
--smolflag to reduce memory usage in production - Monitor performance with built-in metrics
bunfig.toml Setup
[install]
# Use isolated installs for better dependency management
linker = "isolated"
# Enable auto-install for missing dependencies
auto = "auto"
[test]
# Enable coverage reporting
coverage = true
# Set coverage threshold
coverageThreshold = 0.8
[run]
# Use Bun shell for cross-platform compatibility
shell = "bun"
# Auto-alias node to bun for compatibility
bun = trueAPI Replacements
- Replace
fs.readFile()withBun.file().text() - Replace
require()with ES6importstatements - Replace
process.envwithBun.envwhere possible - Replace
child_process.spawn()withBun.spawn() - Replace
http.createServer()withBun.serve()
Compatibility Notes
- Most Node.js APIs work natively in Bun
- Test native modules compatibility before migration
- Use
node:prefix for Node.js-specific modules when needed - Some npm packages may need polyfills - test thoroughly
Input Validation
- Use Bun's built-in security features
- Validate all inputs before processing
- Use parameterized queries for database operations
- Leverage
Bun.password()for secure password hashing
Performance Monitoring
- Use
performance.now()for precise timing - Monitor memory usage with
process.memoryUsage() - Use
Bun.nanoseconds()for high-resolution timing - Profile applications with built-in debugging tools
Plugins hook into OpenCode events using TypeScript modules in .opencode/plugin directory. Export async functions that receive context ({ project, client, $, directory, worktree }) and return hooks for events like "session.created", "tool.execute.after", etc.
- Build evaluation-driven: test tools with real agent tasks before shipping
- Clear tool descriptions: write for a new hire, not an expert
- High-signal responses: return only what agents need, not everything
- Token efficiency: use pagination, filtering, truncation with defaults
- Error guidance: errors must tell agents how to fix, not just fail
- Natural workflows: tools should match how humans solve problems
- Response formats: use enums for concise/detailed output options
- Namespacing: group related tools with clear prefixes
- Type safety: use TypeScript types from @opencode-ai/plugin
- Context awareness: leverage project, client, $ shell, directory, worktree
- Event-driven: hook into lifecycle events, don't poll
- Error handling: throw meaningful errors that guide agents
- Minimal state: avoid complex state management in plugins
- Performance: tools should be fast, agents are impatient
- Clean, minimal brutalist design inspired by opencode.ai and shadcn/ui
- Simple color schemes with lots of white space and clear typography
- Focus on functionality over decoration - no unnecessary visual elements
- Geometric simplicity with structured layouts and content-first approach
- High-signal, low-noise interfaces that prioritize clarity and usability
Cross-Platform Shell
- Use
$template literal tag for shell commands:await $echo "Hello"`` - Leverage built-in commands:
ls,cd,rm,mkdir,cat,touch - Use redirection operators:
>,>>,<,2>,&> - Chain commands with pipes:
await $cat file.txt | grep "pattern" | wc -l``
Process Management
- Use
Bun.spawn()for advanced process control - Leverage
Bun.spawnSync()for synchronous operations - Use
$.nothrow()to prevent non-zero exit codes from throwing - Access stdout/stderr:
const { stdout, stderr } = await $command.quiet()
Environment & Working Directory
- Set environment variables:
await $FOO=bar bun -e 'console.log(process.env.FOO)'`` - Change working directory:
await $pwd.cwd("/tmp") - Use string interpolation safely:
await $echo ${userInput}`` (auto-escaped)
Binary Data Handling
- Use
Bun.file()for efficient binary file operations - Convert between formats:
buffer.toArrayBuffer(),blob.stream() - Use
Uint8Arrayfor binary manipulation - Leverage
Bun.gzipSync()andBun.gunzipSync()for compression
Web Standards
- Use native
fetch(),Response(),Request()objects - Leverage
Headers,URL,URLSearchParamsAPIs - Use
FormDatafor multipart form data - Implement WebSocket servers with
Bun.serve()websocket handlers
Utilities & Helpers
- Use
Bun.deepEquals()for object comparison - Use
Bun.randomUUIDv7()for UUID generation - Use
Bun.which()to find executable paths - Use
Bun.escapeHTML()for HTML escaping
Multi-stage Builds
# Build stage
FROM oven/bun:1-alpine AS builder
WORKDIR /app
COPY package.json bun.lockb ./
RUN bun install --frozen-lockfile
COPY . .
RUN bun run build
# Production stage
FROM oven/bun:1-alpine AS runtime
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package.json ./
EXPOSE 3000
CMD ["bun", "run", "start"]Performance Tuning
- Use
--smolflag for reduced memory usage - Enable production mode:
NODE_ENV=production - Use worker threads for CPU-intensive tasks
- Implement proper error handling and logging
Performance Metrics
- Monitor startup time with
console.time() - Track memory usage:
process.memoryUsage() - Use
performance.now()for precise timing - Implement health checks with
Bun.serve()
Error Handling
- Use structured error logging
- Implement graceful shutdown with
process.on('SIGTERM') - Use try/catch for async operations where necessary
- Monitor unhandled promise rejections
Pre-Migration
- Test all npm packages for Bun compatibility
- Identify native modules that may need replacement
- Review build scripts and CI/CD pipelines
- Backup existing Node.js configuration
Migration Steps
- Replace
npm installwithbun install - Update package.json scripts to use
bun - Replace Node.js APIs with Bun equivalents
- Update Dockerfile to use
oven/bunbase image - Test all functionality thoroughly
- Update CI/CD pipelines for Bun
Post-Migration
- Monitor performance improvements
- Update documentation
- Train team on Bun-specific features
- Implement Bun-specific optimizations
Fully Supported
- ✅ ES Modules and CommonJS
- ✅ TypeScript and JSX
- ✅ Most npm packages
- ✅ Node.js core APIs (fs, path, crypto, etc.)
- ✅ Web APIs (fetch, Response, Request)
Partial Support
- 🟡 Some native modules
- 🟡 Advanced Node.js features
- 🟡 Specific npm packages with native addons
Not Supported
- ❌ V8-specific APIs
- ❌ Some Node.js internals
- ❌ Certain native addons
- HTTP servers: 3x faster than Node.js
- Package installation: 20x faster than npm
- Test runner: 100x faster than Jest
- Startup time: 4x faster than Node.js
- Discord: bun.sh/discord
- GitHub Issues: github.com/oven-sh/bun/issues
- Twitter: @bunjavascript