Node Server
@miiajs/node-server provides a high-performance Node.js HTTP server adapter for MiiaJS.
Installation
bun add @miiajs/node-server
Usage
import { Miia } from '@miiajs/core'
import { serve } from '@miiajs/node-server'
const app = new Miia().register(AppModule)
await app.listen(3000, serve)
With custom hostname:
await app.listen(3000, 'localhost', serve)
How it works
The serve function bridges Node.js's http.IncomingMessage/http.ServerResponse and the Web Standard Request/Response API that MiiaJS uses internally.
Performance modes
The adapter supports two modes:
Optimized mode (default)
Minimizes allocations on the hot path:
- Lazy Request Proxy — lightweight object instead of
new Request(). Method, URL, headers, and body are resolved only on first access. - Lightweight Headers — linear scan over raw header pairs instead of constructing a
Headersobject. Covers.get(),.has(),.forEach(), and iterators. - Body Buffering — small POST bodies (Content-Length ≤
bufferThreshold) are buffered and parsed directly, bypassingReadableStreamandRequestcreation. Large or chunked bodies fall back to streaming viaReadable.toWeb(). - LightResponse Cache — simple responses (string, null, Uint8Array) store a
[status, body, headers]tuple without creating a realResponseobject. - Sync Fast Path — synchronous handlers bypass
Promiseallocation entirely.
Native mode
Full Web API compliance with standard Request and Response objects:
import { serve } from '@miiajs/node-server'
const server = await serve({
fetch: app.fetch,
port: 3000,
mode: 'native',
})
Use native mode when you need strict instanceof Response checks or run multiple frameworks in the same process.
Standalone usage
The adapter can be used without the MiiaJS framework:
import { serve } from '@miiajs/node-server'
const server = await serve({
fetch: (req) => new Response('Hello, World!'),
port: 3000,
hostname: '0.0.0.0',
})
// Later...
await server.close()
Options
interface ServeOptions {
fetch: (req: Request) => Response | Promise<Response> // Required
port?: number // Default: 3000
hostname?: string // Default: '0.0.0.0'
mode?: 'optimized' | 'native' // Default: 'optimized'
bufferThreshold?: number // Default: 102400 (100KB)
}
The bufferThreshold controls the body buffering optimization in optimized mode. POST/PUT/PATCH bodies with a known Content-Length up to this size are buffered in memory for fast json()/text() access. Bodies without Content-Length or larger than the threshold use streaming via Readable.toWeb().
ServerHandle
The serve function returns a ServerHandle with a close() method:
const server = await serve({ fetch: handler, port: 3000 })
// Graceful shutdown
await server.close()