Bun
Entry point
Section titled “Entry point”// server.tsimport { bunAdapter } from 'lacis/adapters'
const createServer = bunAdapter.createHandler('./routes')
createServer({ port: 3000, isDev: process.env.NODE_ENV !== 'production',})How the Bun adapter differs
Section titled “How the Bun adapter differs”- Native fetch handler — requests are handled as standard
Request/Responseobjects, wrapped in thinBunRequest/BunResponseclasses - TransformStream for SSE — Bun’s
Bun.serve()needs theResponsesynchronously, soinitSSE()must be called before the firstawaitin your handler - Faster JSON parsing — delegates directly to Bun’s native JSON parser
SSE constraint
Section titled “SSE constraint”export async function GET(req, res) { res.initSSE() // must be before any await
const data = await fetchSomething() // ...}Config options
Section titled “Config options”| Option | Type | Default | Description |
|---|---|---|---|
port | number | 3000 | Port to listen on |
isDev | boolean | false | Enables dev mode |
defaultHeaders | Record<string, string> | — | Headers added to every response |
cluster | object | — | Multi-worker via reusePort |
cors | CorsConfig | — | CORS policy |
middleware | object | — | beforeRequest, afterRequest, onError hooks |
hooks | object | — | onNotFound, onShutdown hooks |
Cluster mode
Section titled “Cluster mode”Lacis spawns worker processes with Bun.spawn() and uses reusePort: true so the OS distributes connections across workers.
createServer({ port: 3000, cluster: { enabled: true, workers: 4 },})Workers poll the primary’s PID every 2 seconds and exit cleanly if the primary is gone.
Running in production
Section titled “Running in production”-
Build:
Terminal window bun run build -
Start:
Terminal window bun dist/server.js