@ereo/runtime-bun
Bun runtime adapter for the EreoJS framework. This is the default runtime, optimized for Bun's performance.
Import
import {
BunRuntime,
createBunRuntime,
serve
} from '@ereo/runtime-bun'Overview
The @ereo/runtime-bun package provides a high-level adapter for running EreoJS applications on Bun. It wraps the core application and server components, providing a simplified API for common use cases while exposing Bun-specific utilities for optimal performance.
Quick Start
import { serve } from '@ereo/runtime-bun'
// Start a server with default configuration
const runtime = await serve()
// Your app is now running at http://localhost:3000API Reference
createBunRuntime
Creates a new Bun runtime instance.
Signature
function createBunRuntime(options?: BunRuntimeOptions): BunRuntimeOptions
interface BunRuntimeOptions {
// Server configuration
server?: ServerOptions
// Framework configuration
config?: FrameworkConfig
}Example
import { createBunRuntime } from '@ereo/runtime-bun'
const runtime = createBunRuntime({
server: {
port: 3000,
hostname: 'localhost'
},
config: {
routesDir: 'app/routes'
}
})serve
Quick start helper that creates and starts a runtime in one call.
Signature
async function serve(options?: BunRuntimeOptions): Promise<BunRuntime>Example
import { serve } from '@ereo/runtime-bun'
// Start with default configuration
const runtime = await serve()
// Or with custom options
const runtime = await serve({
server: { port: 8080 }
})BunRuntime Class
The main runtime class that manages the application lifecycle.
Methods
| Method | Signature | Description |
|---|---|---|
getApp() | () => EreoApp | Returns the EreoJS app instance |
use(plugin) | (plugin: Plugin) => this | Register a plugin (chainable) |
start() | () => Promise<Server> | Start the server, returns Bun server instance |
stop() | () => void | Stop the server |
handle(request) | (request: Request) => Promise<Response> | Handle a request directly |
Example
import { createBunRuntime } from '@ereo/runtime-bun'
import tailwind from '@ereo/plugin-tailwind'
const runtime = createBunRuntime({
server: { port: 3000 }
})
// Register plugins (chainable)
runtime
.use(tailwind())
.use(anotherPlugin())
// Start the server
const server = await runtime.start()
console.log(`Server running on port ${server.port}`)
// Handle a request directly (useful for testing)
const response = await runtime.handle(
new Request('http://localhost/api/users')
)
console.log(await response.json())
// Stop the server when done
runtime.stop()Testing with handle()
The handle() method is useful for testing without starting a real server:
import { describe, test, expect } from 'bun:test'
import { createBunRuntime } from '@ereo/runtime-bun'
describe('API', () => {
const runtime = createBunRuntime()
test('GET /api/health returns ok', async () => {
const response = await runtime.handle(
new Request('http://localhost/api/health')
)
expect(response.status).toBe(200)
const data = await response.json()
expect(data.status).toBe('ok')
})
})Bun-Specific Utilities
The runtime package exports several utilities that leverage Bun's native APIs for optimal performance.
File Operations
import { readFile, writeFile, readJSON } from '@ereo/runtime-bun'
// Read a file as text
const content = await readFile('./config.json')
// Write content to a file
await writeFile('./output.txt', 'Hello, World!')
// Read and parse JSON (with TypeScript generics)
const config = await readJSON<Config>('./config.json')Error Handling
File operations can throw errors. Always handle them appropriately:
import { readFile, readJSON, requireEnv } from '@ereo/runtime-bun'
// File not found
try {
const content = await readFile('./missing-file.txt')
} catch (error) {
// Error: ENOENT - file not found
console.error('File not found:', error.message)
}
// JSON parse error
try {
const config = await readJSON('./invalid.json')
} catch (error) {
// Error: JSON Parse error or ENOENT
console.error('Failed to read JSON:', error.message)
}
// Missing environment variable
try {
const apiKey = requireEnv('MISSING_VAR')
} catch (error) {
// Error: Missing required environment variable: MISSING_VAR
console.error(error.message)
}Compression
import { gzip, gunzip } from '@ereo/runtime-bun'
// Compress string data (returns Uint8Array)
const compressed = gzip('Hello, World!')
// Compress ArrayBuffer
const buffer = new TextEncoder().encode('Hello, World!')
const compressedBuffer = gzip(buffer)
// Decompress data (returns Uint8Array)
const decompressed = gunzip(compressed)
// Convert back to string
const text = new TextDecoder().decode(decompressed)
console.log(text) // "Hello, World!"Full Compression Workflow
import { gzip, gunzip } from '@ereo/runtime-bun'
// Compress for storage or transmission
const originalData = JSON.stringify({ users: [...] })
const compressed = gzip(originalData)
// Store or send compressed bytes...
// Later: decompress and parse
const decompressed = gunzip(compressed)
const data = JSON.parse(new TextDecoder().decode(decompressed))Password Hashing
import { hashPassword, verifyPassword } from '@ereo/runtime-bun'
// Hash a password
const hash = await hashPassword('mysecretpassword')
// Verify a password
const isValid = await verifyPassword('mysecretpassword', hash)Database
Access Bun's native SQLite database:
import { getDatabase } from '@ereo/runtime-bun'
// Get a SQLite database instance (uses bun:sqlite)
const db = await getDatabase('./data.db')
// Use Bun's SQLite API
db.run('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)')
// Prepared statements for better performance
const insert = db.prepare('INSERT INTO users (name) VALUES (?)')
insert.run('Alice')
// Query data
const users = db.query('SELECT * FROM users').all()
console.log(users) // [{ id: 1, name: 'Alice' }]
// Close when done
db.close()Note:
getDatabase()uses dynamic import internally to avoid bundling issues in non-Bun environments. For full SQLite documentation, see Bun's SQLite docs.
Environment Variables
import { env, requireEnv } from '@ereo/runtime-bun'
// Get environment variable with optional default
const port = env('PORT', '3000')
// Get required environment variable (throws if missing)
const apiKey = requireEnv('API_KEY')Utilities
import {
isBun,
getBunVersion,
randomUUID,
sleep,
spawn
} from '@ereo/runtime-bun'
// Check if running in Bun
if (isBun()) {
console.log('Running on Bun', getBunVersion())
}
// Generate a UUID
const id = randomUUID()
// Sleep for a duration
await sleep(1000) // 1 second
// Spawn a shell command
const proc = spawn(['ls', '-la'], { cwd: './src' })
// The returned Subprocess has these properties:
// proc.stdout - ReadableStream for stdout
// proc.stderr - ReadableStream for stderr
// proc.exited - Promise<number> that resolves to exit code
// Example: Capture output
const result = spawn(['echo', 'hello'])
const output = await new Response(result.stdout).text()
console.log(output) // "hello\n"
// Wait for process to complete
const exitCode = await result.exitedConfiguration
Server Options
The server configuration accepts ServerOptions from @ereo/server:
import { serve } from '@ereo/runtime-bun'
const runtime = await serve({
server: {
port: 3000,
hostname: '0.0.0.0',
development: true,
logging: true,
cors: true, // or CorsOptions object
security: true, // or SecurityHeadersOptions object
tls: {
cert: './certs/cert.pem',
key: './certs/key.pem',
},
}
})See BunServer documentation for full ServerOptions reference.
Framework Configuration
Pass framework configuration to customize the EreoJS application:
import { createBunRuntime } from '@ereo/runtime-bun'
const runtime = createBunRuntime({
config: {
routesDir: 'app/routes',
plugins: []
}
})Full Example
import { createBunRuntime } from '@ereo/runtime-bun'
import tailwind from '@ereo/plugin-tailwind'
import { createAuthPlugin } from '@ereo/auth'
import { createDevInspector } from '@ereo/dev-inspector'
const isDev = Bun.env.NODE_ENV !== 'production'
const runtime = createBunRuntime({
server: {
port: parseInt(Bun.env.PORT || '3000'),
hostname: '0.0.0.0',
},
config: {
routesDir: 'app/routes',
}
})
// Register plugins
runtime.use(tailwind())
runtime.use(createAuthPlugin({
session: { secret: Bun.env.AUTH_SECRET! },
providers: [/* your providers */],
}))
// Add dev inspector in development
if (isDev) {
runtime.use(createDevInspector({
mountPath: '/__ereo'
}))
}
// Start the server
await runtime.start()
console.log(`Server running at http://localhost:${Bun.env.PORT || 3000}`)Re-exports
For convenience, the package re-exports commonly used functions from core packages:
import {
createApp,
createServer
} from '@ereo/runtime-bun'
// These are re-exported from @ereo/core and @ereo/server