### Start an HTTPS Server with Hono Source: https://github.com/honojs/node-server/blob/main/_autodocs/INDEX.md This example shows how to start an HTTPS server using Hono. It requires the 'createServer' function from 'node:https' and certificate files (key.pem, cert.pem). ```typescript import { serve } from '@hono/node-server' import { createServer } from 'node:https' import fs from 'node:fs' serve({ fetch: app.fetch, port: 8443, createServer: createServer, serverOptions: { key: fs.readFileSync('key.pem'), cert: fs.readFileSync('cert.pem'), }, }) ``` -------------------------------- ### Install and Run Benchmark Source: https://github.com/honojs/node-server/blob/main/benchmarks/fetch/README.md Installs project dependencies and executes the benchmark script. Ensure Node.js and bombardier are installed beforehand. ```bash npm install npm run benchmark ``` -------------------------------- ### serve() Source: https://github.com/honojs/node-server/blob/main/_autodocs/01-serve.md Starts an HTTP server and begins listening on the specified port. It accepts configuration options and an optional callback for when the server starts listening. ```APIDOC ## serve() ### Description Starts an HTTP server and begins listening on the specified port. ### Signature ```typescript serve( options: Options, listeningListener?: (info: AddressInfo) => void ): ServerType ``` ### Parameters #### options - **Type**: `Options` - **Required**: yes - **Description**: Server configuration options including fetch callback and port. #### listeningListener - **Type**: `(info: AddressInfo) => void` - **Required**: no - **Default**: `undefined` - **Description**: Optional callback invoked when the server begins listening. Receives address information including port and family. ### Return Type `ServerType` — A Node.js HTTP server instance (may be `Server`, `Http2Server`, or `Http2SecureServer` depending on options). ### Options Reference #### fetch - **Type**: `FetchCallback` - **Required**: yes - **Description**: The Hono application handler; called for each HTTP request. #### port - **Type**: `number` - **Required**: no - **Default**: `3000` - **Description**: Port to listen on. #### hostname - **Type**: `string` - **Required**: no - **Default**: `undefined` - **Description**: Hostname to bind to. If omitted, accepts connections on any interface. #### overrideGlobalObjects - **Type**: `boolean` - **Required**: no - **Default**: `true` - **Description**: Replace global `Request` and `Response` with lightweight implementations for better performance. Set `false` to use native web API objects. #### autoCleanupIncoming - **Type**: `boolean` - **Required**: no - **Default**: `true` - **Description**: Automatically drain unconsumed request bodies to prevent connection hangs. Disable for trusted-client-only environments. #### websocket - **Type**: `{ server: WebSocketServerLike }` - **Required**: no - **Default**: `undefined` - **Description**: WebSocket server instance to enable WebSocket upgrade handling. Must be created with `{ noServer: true }`. #### createServer - **Type**: `Function` - **Required**: no - **Default**: `createServer` - **Description**: Custom server factory (e.g., `createSecureServer` from `node:https` for HTTPS). #### serverOptions - **Type**: `Object` - **Required**: no - **Default**: `{}` - **Description**: Options passed to the server factory (e.g., SSL certificates for HTTPS). ### Throws - `Error` — If WebSocket server is not created with `{ noServer: true }` option. ### Example: Basic HTTP Server ```typescript import { serve } from '@hono/node-server' import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.text('Hello World')) serve(app, (info) => { console.log(`Server running on http://localhost:${info.port}`) }) ``` ### Example: HTTPS Server ```typescript import { serve } from '@hono/node-server' import { createServer } from 'node:https' import fs from 'node:fs' import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.text('Secure')) serve({ fetch: app.fetch, port: 8443, createServer: createServer, serverOptions: { key: fs.readFileSync('./key.pem'), cert: fs.readFileSync('./cert.pem'), }, }, (info) => { console.log(`HTTPS server on port ${info.port}`) }) ``` ### Example: With WebSocket ```typescript import { serve, upgradeWebSocket } from '@hono/node-server' import { WebSocketServer } from 'ws' import { Hono } from 'hono' const app = new Hono() const wss = new WebSocketServer({ noServer: true }) app.get('/ws', upgradeWebSocket(() => ({ onMessage(event, ws) { ws.send(`Echo: ${event.data}`) }, }))) serve({ fetch: app.fetch, websocket: { server: wss }, }) ``` ``` -------------------------------- ### Basic Hono App on Node.js Source: https://github.com/honojs/node-server/blob/main/README.md Run a basic Hono application on Node.js. This example demonstrates the core setup and how to start the server. ```ts import { serve } from '@hono/node-server' import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.text('Hono meets Node.js')) serve(app, (info) => { console.log(`Listening on http://localhost:${info.port}`) // Listening on http://localhost:3000 }) ``` -------------------------------- ### Complete Chat Server with Hono WebSocket Source: https://github.com/honojs/node-server/blob/main/_autodocs/03-websocket.md This example sets up a full chat server using Hono's `upgradeWebSocket` function. It manages multiple chat rooms, broadcasting messages to clients within a room, and handling join/leave events. Ensure the `ws` library is installed. ```typescript import { serve, upgradeWebSocket } from '@hono/node-server' import { WebSocketServer } from 'ws' import { Hono } from 'hono' const app = new Hono() const wss = new WebSocketServer({ noServer: true }) const rooms = new Map() app.get('/chat/:room', upgradeWebSocket((c) => { const roomName = c.req.param('room') if (!rooms.has(roomName)) { rooms.set(roomName, new Set()) } const room = rooms.get(roomName) return { onOpen(event, ws) { room.add(ws) room.forEach(client => { if (client.readyState === 1) { client.send(JSON.stringify({ type: 'join' })) } }) }, onMessage(event, ws) { room.forEach(client => { if (client.readyState === 1) { client.send(event.data) } }) }, onClose(event, ws) { room.delete(ws) }, onError(event, ws) { console.error('WS error:', event.error) }, } })) serve({ fetch: app.fetch, websocket: { server: wss }, }, (info) => { console.log(`Chat server on port ${info.port}`) }) ``` -------------------------------- ### Minimal Hono Server with Node.js Adapter Source: https://github.com/honojs/node-server/blob/main/_autodocs/00-START-HERE.md This is the most basic setup for a Hono server on Node.js. Import `serve` from '@hono/node-server' and your Hono app, then call `serve(app)` to start the server. ```typescript // Minimal server import { serve } from '@hono/node-server' import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.text('Hello')) serve(app) ``` -------------------------------- ### Install @hono/node-server with npm Source: https://github.com/honojs/node-server/blob/main/README.md Install the Node.js adapter for Hono using npm. ```sh npm install @hono/node-server ``` -------------------------------- ### Simplest Hono Node.js Server Source: https://github.com/honojs/node-server/blob/main/_autodocs/README.md Starts a basic Hono server with automatic listener. Ensure Hono is installed. ```typescript import { serve } from '@hono/node-server' import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.text('Hello World')) serve(app) ``` -------------------------------- ### Install @hono/node-server with yarn Source: https://github.com/honojs/node-server/blob/main/README.md Install the Node.js adapter for Hono using yarn. ```sh yarn add @hono/node-server ``` -------------------------------- ### Start a Basic HTTP Server with Hono Source: https://github.com/honojs/node-server/blob/main/_autodocs/INDEX.md Use this snippet to start a basic HTTP server with Hono. It requires importing the 'serve' function and your Hono application instance. ```typescript import { serve } from '@hono/node-server' import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.text('Hello')) serve(app, (info) => { console.log(`Listening on http://localhost:${info.port}`) }) ``` -------------------------------- ### Start HTTPS Server with Hono Source: https://github.com/honojs/node-server/blob/main/_autodocs/00-START-HERE.md To start an HTTPS server, provide `fetch` and `createServer` options to the `serve` function, along with `serverOptions` for certificate and key. ```typescript // Start HTTPS server serve({ fetch: app.fetch, createServer, serverOptions: { cert, key } }) ``` -------------------------------- ### Express Application Example Source: https://github.com/honojs/node-server/blob/main/_autodocs/11-integration-patterns.md An example of a basic Express application with API and file download routes. This serves as a baseline for migration. ```typescript import express from 'express' import { createReadStream } from 'node:fs' const app = express() app.use(express.json()) app.get('/api/data', (req, res) => { res.json({ message: 'hello' }) }) app.get('/download', (req, res) => { res.setHeader('Content-Type', 'application/octet-stream') createReadStream('./file.bin').pipe(res) }) app.listen(3000, () => { console.log('Express listening on port 3000') }) ``` -------------------------------- ### Start HTTP Server with Hono Source: https://github.com/honojs/node-server/blob/main/_autodocs/00-START-HERE.md Use the `serve` function from `@hono/node-server` to start an HTTP server. Ensure the `app` object is correctly defined. ```typescript // Start HTTP server import { serve } from '@hono/node-server' serve(app) ``` -------------------------------- ### Example: UNIX Domain Socket Server Source: https://github.com/honojs/node-server/blob/main/_autodocs/01-serve.md Demonstrates creating a server that listens on a UNIX domain socket. Ensure the socket path is accessible. ```typescript import { createAdaptorServer } from '@hono/node-server' import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.text('Hello')) const server = createAdaptorServer({ fetch: app.fetch, }) const socketPath = '/tmp/hono.sock' server.listen(socketPath, () => { console.log(`Server listening on ${socketPath}`) }) ``` -------------------------------- ### Simplest Server Source: https://github.com/honojs/node-server/blob/main/_autodocs/README.md Starts a basic Hono server with an automatic listener on the default port. ```APIDOC ## serve() ### Description Starts a Hono application as a Node.js server with an automatic listener. ### Method `serve(app: Hono, options?: ServerOptions)` ### Parameters - `app` (Hono): The Hono application instance. - `options` (ServerOptions, optional): Configuration options for the server. ### Request Example ```typescript import { serve } from '@hono/node-server' import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.text('Hello World')) serve(app) ``` ``` -------------------------------- ### Range Requests Example Source: https://github.com/honojs/node-server/blob/main/_autodocs/04-serve-static.md Shows an example of an HTTP Range request and the corresponding server response for partial content. ```http // Client request: // GET /large.bin // Range: bytes=1000-2999 // Response: // 206 Partial Content // Content-Range: bytes 1000-2999/1000000 // Content-Length: 2000 ``` -------------------------------- ### Example FetchCallback Implementation Source: https://github.com/honojs/node-server/blob/main/_autodocs/07-types.md Provides an example of implementing the FetchCallback type. This callback logs the request method and URL before returning a simple 'OK' Response. ```typescript const fetchCallback: FetchCallback = (request, env) => { console.log(request.method, request.url) return new Response('OK') } serve({ fetch: fetchCallback }) ``` -------------------------------- ### Request Example Source: https://github.com/honojs/node-server/blob/main/_autodocs/06-request-response.md Example demonstrating how to access JSON data and headers from the request object within a Hono application's POST route. ```APIDOC ## Request Example ### Description This example shows how to use the `req.json()` method to parse a JSON request body and `req.headers.get()` to retrieve a specific header within a Hono application. ### Code ```typescript import { Hono } from 'hono' const app = new Hono() app.post('/api/data', async (c) => { const json = await c.req.json() const contentType = c.req.headers.get('content-type') return c.json({ received: json, contentType: contentType }) }) // Assuming 'serve' is a function to start the server // serve(app) ``` ### Usage Send a POST request to `/api/data` with a JSON body. The server will respond with the parsed JSON data and the value of the 'content-type' header. ``` -------------------------------- ### Serve Functions Source: https://github.com/honojs/node-server/blob/main/_autodocs/INDEX.md Functions for starting and configuring an HTTP/HTTPS/HTTP2 server. ```APIDOC ## serve ### Description Starts an HTTP(S) server and begins listening for incoming connections. ### Function Signature `serve(options?, callback?)` ### Parameters - `options` (object) - Optional. Server configuration options. - `callback` (function) - Optional. A callback function to be executed when the server starts listening. ### Returns This function does not return a value directly, but starts the server. ``` ```APIDOC ## createAdaptorServer ### Description Creates an HTTP server instance without starting the listener. This allows for manual control over the server lifecycle. ### Function Signature `createAdaptorServer(options)` ### Parameters - `options` (object) - Required. Server configuration options. ### Returns An instance of the server. ``` ```APIDOC ## getRequestListener ### Description Retrieves the raw request listener function. This is a low-level API for manual server setup. ### Function Signature `getRequestListener(fetch, options?)` ### Parameters - `fetch` (function) - Required. The fetch handler for requests. - `options` (object) - Optional. Server configuration options. ### Returns A request listener function. ``` -------------------------------- ### Custom HTTP Server Setup Source: https://github.com/honojs/node-server/blob/main/_autodocs/02-request-listener.md Demonstrates how to set up a basic HTTP server using Node.js's `createServer` and passing the listener created by `getRequestListener`. This allows for manual control over the server lifecycle. ```typescript import { createServer } from 'node:http' import { getRequestListener } from '@hono/node-server' import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.text('Hello')) const listener = getRequestListener(app.fetch) const server = createServer(listener) server.listen(3000, () => { console.log('Server ready') }) ``` -------------------------------- ### Custom Directory Index Example Source: https://github.com/honojs/node-server/blob/main/_autodocs/04-serve-static.md Demonstrates how to configure a custom index filename for serving directory requests. ```typescript serveStatic({ root: '.', index: 'index.htm' }) ``` -------------------------------- ### Example: Custom Listener Management Source: https://github.com/honojs/node-server/blob/main/_autodocs/01-serve.md Shows how to manage server listeners manually, including error handling. This allows for fine-grained control over server startup and shutdown. ```typescript const server = createAdaptorServer({ fetch: app.fetch, port: 3000, }) server.on('error', (err) => { console.error('Server error:', err) }) server.listen(3000, '127.0.0.1', () => { console.log('Ready') }) ``` -------------------------------- ### Start HTTP/2 Server with Hono Source: https://github.com/honojs/node-server/blob/main/_autodocs/00-START-HERE.md Initiate an HTTP/2 server by specifying the `fetch` handler and `createHttp2Server` for the `createServer` option in the `serve` function. ```typescript // Start HTTP/2 server serve({ fetch: app.fetch, createServer: createHttp2Server }) ``` -------------------------------- ### createAdaptorServer() Source: https://github.com/honojs/node-server/blob/main/_autodocs/01-serve.md Creates and configures an HTTP server without starting the listener, providing manual control over when the server begins accepting connections. ```APIDOC ## createAdaptorServer() ### Description Creates and configures an HTTP server without starting the listener. Useful when you need manual control over when the server begins accepting connections. ### Method Signature ```typescript createAdaptorServer(options: Options): ServerType ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **options** (`Options`) - Required - Server configuration (see `serve()` options). ### Return Type `ServerType` — The configured server instance, ready to be passed to `.listen()`. ### Example: UNIX Domain Socket ```typescript import { createAdaptorServer } from '@hono/node-server' import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.text('Hello')) const server = createAdaptorServer({ fetch: app.fetch, }) const socketPath = '/tmp/hono.sock' server.listen(socketPath, () => { console.log(`Server listening on ${socketPath}`) }) ``` ### Example: Custom Listener Management ```typescript const server = createAdaptorServer({ fetch: app.fetch, port: 3000, }) server.on('error', (err) => { console.error('Server error:', err) }) server.listen(3000, '127.0.0.1', () => { console.log('Ready') }) ``` ### Types #### Options Union type combining HTTP/HTTPS/HTTP2 configuration with base server options. ```typescript type Options = { fetch: FetchCallback overrideGlobalObjects?: boolean autoCleanupIncoming?: boolean port?: number hostname?: string websocket?: { server: WebSocketServerLike } } & ServerOptions ``` #### ServerType ```typescript type ServerType = Server | Http2Server | Http2SecureServer ``` Represents any Node.js HTTP server type that the adapter can create. #### FetchCallback ```typescript type FetchCallback = ( request: Request, env: HttpBindings | Http2Bindings ) => Promise | unknown ``` The entry point handler. Called with the incoming request and environment bindings (node request/response objects). ``` -------------------------------- ### Type Bindings for HTTP/2 Source: https://github.com/honojs/node-server/blob/main/_autodocs/07-types.md Example of typing bindings for HTTP/2 environments using Http2Bindings from @hono/node-server. ```typescript import type { Http2Bindings } from '@hono/node-server' const app = new Hono<{ Bindings: Http2Bindings }>() ``` -------------------------------- ### Basic HTTP Server with Hono Source: https://github.com/honojs/node-server/blob/main/_autodocs/01-serve.md Starts a basic HTTP server using Hono. This is the simplest way to run a Hono app on Node.js. ```typescript import { serve } from '@hono/node-server' import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.text('Hello World')) serve(app, (info) => { console.log(`Server running on http://localhost:${info.port}`) }) ``` -------------------------------- ### Type Bindings for HTTP/1.1 Source: https://github.com/honojs/node-server/blob/main/_autodocs/07-types.md Example of typing bindings for HTTP/1.1 environments using HttpBindings from @hono/node-server. ```typescript import type { HttpBindings } from '@hono/node-server' const app = new Hono<{ Bindings: HttpBindings }>() app.get('/', (c) => { const { incoming, outgoing } = c.env return c.text('OK') }) ``` -------------------------------- ### Create Adaptor Server Source: https://github.com/honojs/node-server/blob/main/_autodocs/01-serve.md Creates an HTTP server instance without starting the listener. Useful for manual control over server startup. ```typescript createAdaptorServer(options: Options): ServerType ``` -------------------------------- ### Server-Sent Events (SSE) Source: https://github.com/honojs/node-server/blob/main/_autodocs/09-utils.md Example demonstrating how to implement Server-Sent Events (SSE) using TransformStream. ```APIDOC ## Server-Sent Events (SSE) ### Description This example implements Server-Sent Events by creating a `TransformStream` and writing messages to its writable side. The readable side is then returned as a `Response` with the appropriate SSE headers. ### Endpoint `GET /events` ### Request Example ```typescript app.get('/events', (c) => { const { readable, writable } = new TransformStream() const writer = writable.getWriter() // Send events in background ;(async () => { try { for (let i = 0; i < 10; i++) { await writer.write(new TextEncoder().encode(`data: event ${i}\n\n`)) await new Promise(r => setTimeout(r, 1000)) } } finally { writer.close() } })() return new Response(readable, { headers: { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', }, }) }) ``` ``` -------------------------------- ### Integration Test Hono Server with Vitest Source: https://github.com/honojs/node-server/blob/main/_autodocs/11-integration-patterns.md Perform integration tests by starting a Hono server using `@hono/node-server` and making actual HTTP requests to it. Ensure the server is properly started before tests and closed afterwards. ```typescript import { test, beforeAll, afterAll } from 'vitest' import { serve } from '@hono/node-server' let server: any beforeAll(async () => { server = serve({ fetch: app.fetch, port: 0 }) // Port 0 = random available }) afterAll(async () => { server.close() }) test('Server responds to requests', async () => { const port = (server.address() as any).port const res = await fetch(`http://localhost:${port}/api/test`) expect(res.status).toBe(200) }) ``` -------------------------------- ### Piping External Data Source: https://github.com/honojs/node-server/blob/main/_autodocs/09-utils.md Example demonstrating how to pipe the incoming request body to a file stream. ```APIDOC ## Piping External Data ### Description This example shows how to handle file uploads by piping the incoming request body (available as `c.env.incoming` which is a Node.js `IncomingMessage`) directly to a file write stream using `pipeline` from `node:stream/promises`. ### Endpoint `POST /upload/:id` ### Request Example ```typescript import { pipeline } from 'node:stream/promises' import { createReadStream, createWriteStream } from 'node:fs' app.post('/upload/:id', async (c) => { const { id } = c.req.param() const dest = `./uploads/${id}.bin` try { // Write request body to disk const nodeStream = c.env.incoming // Node.js IncomingMessage const output = createWriteStream(dest) await pipeline(nodeStream, output) return c.json({ uploaded: id }) } catch (err) { return c.json({ error: 'Upload failed' }, 500) } }) ``` ``` -------------------------------- ### Hono + Node Server Migration Example Source: https://github.com/honojs/node-server/blob/main/_autodocs/11-integration-patterns.md The equivalent Hono application demonstrating API and file download routes using the Node.js adapter. It highlights the use of `serve` and `createStreamBody` for stream handling. ```typescript import { serve } from '@hono/node-server' import { createStreamBody } from '@hono/node-server/utils/stream' import { createReadStream } from 'node:fs' import { Hono } from 'hono' import { json } from 'hono/middleware' const app = new Hono() app.use('*', json()) app.get('/api/data', (c) => { return c.json({ message: 'hello' }) }) app.get('/download', (c) => { const stream = createReadStream('./file.bin') const body = createStreamBody(stream) return new Response(body, { headers: { 'Content-Type': 'application/octet-stream' }, }) }) serve(app, (info) => { console.log(`Hono listening on port ${info.port}`) }) ``` -------------------------------- ### Example: Handling Binary WebSocket Data Source: https://github.com/honojs/node-server/blob/main/_autodocs/03-websocket.md Demonstrates how to handle binary data (ArrayBuffer) received over a WebSocket connection and send a binary response. ```typescript app.get('/binary', upgradeWebSocket((c) => ({ onMessage(event, ws) { const data = event.data if (data instanceof ArrayBuffer) { const view = new Uint8Array(data) console.log('Received bytes:', view) ws.send(new Uint8Array([1, 2, 3])) } }, }))) ``` -------------------------------- ### Streaming Large Files Source: https://github.com/honojs/node-server/blob/main/_autodocs/09-utils.md Example demonstrating how to stream large files using Node.js streams and Hono. ```APIDOC ## Streaming Large Files ### Description This example shows how to serve large files by creating a readable stream from the file system and using `createStreamBody` to prepare it for a `Response`. ### Endpoint `GET /video/:id` ### Request Example ```typescript import { serve } from '@hono/node-server' import { createReadStream } from 'node:fs' import { createStreamBody } from '@hono/node-server/utils/stream' import { Hono } from 'hono' const app = new Hono() app.get('/video/:id', async (c) => { const { id } = c.req.param() const filePath = `./videos/${id}.mp4` try { const stream = createReadStream(filePath) const body = createStreamBody(stream) return new Response(body, { headers: { 'Content-Type': 'video/mp4', 'Accept-Ranges': 'bytes', }, }) } catch (err) { return c.notFound() } }) serve(app) ``` ``` -------------------------------- ### HTTPS Server with Hono Source: https://github.com/honojs/node-server/blob/main/_autodocs/01-serve.md Configures and starts an HTTPS server using Hono. Requires SSL certificate and key files. ```typescript import { serve } from '@hono/node-server' import { createServer } from 'node:https' import fs from 'node:fs' import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.text('Secure')) serve({ fetch: app.fetch, port: 8443, createServer: createServer, serverOptions: { key: fs.readFileSync('./key.pem'), cert: fs.readFileSync('./cert.pem'), }, }, (info) => { console.log(`HTTPS server on port ${info.port}`) }) ``` -------------------------------- ### Example: Echo WebSocket Server Source: https://github.com/honojs/node-server/blob/main/_autodocs/03-websocket.md A basic Hono application that sets up an echo WebSocket server. It echoes back any message received from a client and logs when a connection is closed. ```typescript import { serve, upgradeWebSocket } from '@hono/node-server' import { WebSocketServer } from 'ws' import { Hono } from 'hono' const app = new Hono() const wss = new WebSocketServer({ noServer: true }) app.get('/ws', upgradeWebSocket((c) => ({ onMessage(event, ws) { ws.send(`Echo: ${event.data}`) }, onClose() { console.log('Connection closed') }, }))) serve({ fetch: app.fetch, websocket: { server: wss }, }) ``` -------------------------------- ### HTTPS Server Source: https://github.com/honojs/node-server/blob/main/_autodocs/README.md Configures and starts a Hono server using HTTPS with custom server options. ```APIDOC ## serve() with HTTPS ### Description Starts a Hono server configured for HTTPS, requiring SSL certificate and key. ### Method `serve(options: ServerOptions)` ### Parameters - `options` (ServerOptions): Configuration object including `fetch`, `port`, `createServer`, and `serverOptions` for HTTPS. - `createServer`: Function to create the HTTPS server (e.g., `node:https.createServer`). - `serverOptions`: Options for the HTTPS server, including `key` and `cert` paths. ### Request Example ```typescript import { serve } from '@hono/node-server' import { createServer } from 'node:https' import fs from 'node:fs' serve({ fetch: app.fetch, port: 8443, createServer: createServer, serverOptions: { key: fs.readFileSync('key.pem'), cert: fs.readFileSync('cert.pem'), }, }) ``` ``` -------------------------------- ### Type Bindings for Dual-Protocol Support Source: https://github.com/honojs/node-server/blob/main/_autodocs/07-types.md Example of typing bindings for dual-protocol support (HTTP/1.1 and HTTP/2) using both HttpBindings and Http2Bindings. ```typescript import type { HttpBindings, Http2Bindings } from '@hono/node-server' const app = new Hono<{ Bindings: HttpBindings | Http2Bindings }>() app.get('/', (c) => { const bindings = c.env as HttpBindings | Http2Bindings return c.text('OK') }) ``` -------------------------------- ### Database Connection Pooling with `pg` Source: https://github.com/honojs/node-server/blob/main/_autodocs/11-integration-patterns.md Initialize a PostgreSQL connection pool at server start and make it available to request handlers. Includes graceful shutdown by draining the pool. ```typescript import { Pool } from 'pg' const pool = new Pool({ connectionString: process.env.DATABASE_URL, }) app.use('*', (c, next) => { // Make pool available to handlers c.set('db', pool) return next() }) app.get('/users/:id', async (c) => { const db = c.get('db') as Pool const userId = c.req.param('id') const result = await db.query('SELECT * FROM users WHERE id = $1', [userId]) if (result.rows.length === 0) { return c.notFound() } return c.json(result.rows[0]) }) // Graceful shutdown with pool drain process.on('SIGTERM', async () => { await pool.end() server.close() }) const server = serve(app) ``` -------------------------------- ### Path Traversal Protection Example Source: https://github.com/honojs/node-server/blob/main/_autodocs/04-serve-static.md Illustrates paths that are protected against traversal attacks and will result in a 404 or fall through. ```typescript // These all return 404 or fall through to next(): // GET /static/../etc/passwd // GET /static/..%2Fetc%2Fpasswd // GET /static//etc/passwd ``` -------------------------------- ### Example: Broadcast WebSocket Server Source: https://github.com/honojs/node-server/blob/main/_autodocs/03-websocket.md Implements a broadcast WebSocket server where messages received from any client are sent to all connected clients. It manages a set of connected clients. ```typescript const clients = new Set() app.get('/broadcast', upgradeWebSocket((c) => ({ onOpen(event, ws) { clients.add(ws) }, onMessage(event, ws) { for (const client of clients) { if (client.readyState === 1) { // OPEN client.send(`${event.data}`) } } }, onClose(event, ws) { clients.delete(ws) }, }))) ``` -------------------------------- ### Serve File with Custom Headers using createStreamBody Source: https://github.com/honojs/node-server/blob/main/_autodocs/09-utils.md Example of serving a file using `createStreamBody` to stream the file content. This is efficient for large files as it avoids loading the entire file into memory. ```typescript import { createStreamBody } from '@hono/node-server/utils/stream' import { createReadStream } from 'node:fs' import { Hono } from 'hono' const app = new Hono() app.get('/download', (c) => { const stream = createReadStream('./large-file.bin') const body = createStreamBody(stream) return new Response(body, { headers: { 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="file.bin"', }, }) }) ``` -------------------------------- ### Safe Path Rewriting Example Source: https://github.com/honojs/node-server/blob/main/_autodocs/04-serve-static.md Demonstrates how to use `rewriteRequestPath` to safely remove a prefix from the request path. ```typescript app.use('/docs/*', serveStatic({ root: './docs', rewriteRequestPath: (path) => { // Safe: removes a known prefix return path.replace(/^\/docs/, '') }, })) ``` -------------------------------- ### Hono WebSocket Server Setup Source: https://github.com/honojs/node-server/blob/main/README.md Implement WebSocket support in your Hono Node.js application. Requires the 'ws' package. Ensure `noServer: true` is set when creating `WebSocketServer`. ```ts import { serve, upgradeWebSocket } from '@hono/node-server' import { WebSocketServer } from 'ws' import { Hono } from 'hono' const app = new Hono() app.get( '/ws', upgradeWebSocket(() => ({ onMessage(event, ws) { ws.send(event.data) }, })) ) const wss = new WebSocketServer({ noServer: true }) // important to create with `noServer: true` serve({ fetch: app.fetch, websocket: { server: wss }, }) ``` -------------------------------- ### Graceful Shutdown with Hono Server Source: https://github.com/honojs/node-server/blob/main/_autodocs/11-integration-patterns.md Implement graceful shutdown for a Hono server by closing new connections and waiting for existing ones to complete. This example uses SIGTERM. ```typescript import { serve } from '@hono/node-server' import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.text('OK')) const server = serve(app, (info) => { console.log(`Listening on ${info.port}`) }) // Graceful shutdown signal handler process.on('SIGTERM', async () => { console.log('SIGTERM received, shutting down gracefully...') // Stop accepting new connections server.close() // Wait up to 30 seconds for existing requests to finish const timeout = setTimeout(() => { console.error('Shutdown timeout, forcing exit') process.exit(1) }, 30000) server.on('close', () => { clearTimeout(timeout) console.log('Server closed, exiting') process.exit(0) }) }) ``` -------------------------------- ### Headers API Usage Source: https://github.com/honojs/node-server/blob/main/_autodocs/06-request-response.md Demonstrates the standard Headers API for managing request and response headers, including initialization, appending, setting, getting, and checking for header existence. Iteration over headers is also shown. ```typescript const headers = new Headers({ 'content-type': 'application/json', }) headers.append('set-cookie', 'session=abc123') headers.set('cache-control', 'no-cache') headers.get('content-type') // 'application/json' headers.has('authorization') // false // Iterate for (const [name, value] of headers) { console.log(`${name}: ${value}`) } ``` -------------------------------- ### Serve Static Files with Hono Node.js Source: https://github.com/honojs/node-server/blob/main/README.md Use the serveStatic middleware to serve files from a specified root directory. The root path is relative to the current working directory where the app is started. ```typescript import { serveStatic } from '@hono/node-server/serve-static' //... app.use('/static/*', serveStatic({ root: './' })) ``` ```typescript app.use('/static/*', serveStatic({ root: './static' })) ``` -------------------------------- ### WebSocket Server Setup with `noServer: true` Source: https://github.com/honojs/node-server/blob/main/_autodocs/11-integration-patterns.md When integrating with an existing Node.js HTTP server (like http.createServer), ensure the WebSocket server is configured with `noServer: true` to prevent it from creating its own server instance. ```typescript // ✗ Wrong const wss = new WebSocketServer({ port: 8080 }) // ✓ Correct const wss = new WebSocketServer({ noServer: true }) ``` -------------------------------- ### Get Client IP Behind Reverse Proxy Source: https://github.com/honojs/node-server/blob/main/_autodocs/05-conninfo.md When Hono is behind a reverse proxy, use the `X-Forwarded-For` header to get the client's IP address. This example prioritizes the header value, falling back to the direct connection's remote address if the header is not present. ```typescript app.get('/', (c) => { const connInfo = getConnInfo(c) const forwardedFor = c.req.header('x-forwarded-for') const clientIP = forwardedFor?.split(',')[0].trim() || connInfo.remote.address return c.json({ clientIP }) }) ``` -------------------------------- ### setupWebSocket() Source: https://github.com/honojs/node-server/blob/main/_autodocs/03-websocket.md Internal utility that configures the server to handle WebSocket upgrade requests. Called automatically by `serve()` when the `websocket` option is provided. Not typically called directly; used internally by the adapter. ```APIDOC ## setupWebSocket() Internal utility that configures the server to handle WebSocket upgrade requests. Called automatically by `serve()` when the `websocket` option is provided. ```typescript setupWebSocket(options: { server: ServerType fetchCallback: FetchCallback wss: WebSocketServerLike }): void ``` ### Parameters | Parameter | Type | Description | |-----------|------|-------------| | server | `ServerType` | The HTTP/HTTPS/HTTP2 server instance. | | fetchCallback | `FetchCallback` | The Hono application handler. | | wss | `WebSocketServerLike` | The WebSocket server instance (must have `noServer: true`). | Not typically called directly; used internally by the adapter. ``` -------------------------------- ### createAdaptorServer() Source: https://github.com/honojs/node-server/blob/main/_autodocs/README.md Manually creates a server instance, providing more control over the server lifecycle. ```APIDOC ## createAdaptorServer() ### Description Provides a lower-level API to create a server instance, allowing for manual control over the request listener and server lifecycle. ### Method `createAdaptorServer(requestListener: RequestListener, options?: ServerOptions)` ### Parameters - `requestListener` (RequestListener): A function that handles incoming requests. - `options` (ServerOptions, optional): Configuration options for the server. ``` -------------------------------- ### Basic Server Initialization with Hono Source: https://github.com/honojs/node-server/blob/main/_autodocs/10-configuration.md Initialize the Hono Node.js server with basic fetch handler, port, and hostname. ```typescript import { serve } from '@hono/node-server' import { Hono } from 'hono' const app = new Hono() serve({ fetch: app.fetch, port: 3000, hostname: 'localhost', }) ``` -------------------------------- ### UNIX Domain Socket Server Initialization Source: https://github.com/honojs/node-server/blob/main/_autodocs/10-configuration.md Create a server that listens on a UNIX domain socket instead of a TCP port, using `createAdaptorServer` and its `listen` method. ```typescript import { createAdaptorServer } from '@hono/node-server' const server = createAdaptorServer({ fetch: app.fetch, }) const socketPath = '/tmp/hono.sock' server.listen(socketPath, () => { console.log(`Listening on ${socketPath}`) }) ``` -------------------------------- ### Serve Precompressed Static Files Source: https://github.com/honojs/node-server/blob/main/README.md Enable the `precompressed` option to automatically serve `.br`, `.zst`, or `.gz` versions of files based on the `Accept-Encoding` header, falling back to the original file if compressed versions are not found. ```typescript app.use( '/static/*', serveStatic({ precompressed: true, }) ) ``` -------------------------------- ### Catching RequestError Source: https://github.com/honojs/node-server/blob/main/_autodocs/08-errors.md Example demonstrating how to catch and handle `RequestError` specifically, returning a 400 response if the error is of this type. ```APIDOC ### Example: Catching RequestError ```typescript import { RequestError } from '@hono/node-server' const listener = getRequestListener(app.fetch, { errorHandler: (err) => { if (err instanceof RequestError) { console.warn('Invalid request:', err.message) return new Response(err.message, { status: 400 }) } return undefined }, }) ``` ``` -------------------------------- ### Incremental Migration with Express and Hono Source: https://github.com/honojs/node-server/blob/main/_autodocs/11-integration-patterns.md Demonstrates mixing Express and Hono during a migration. It shows how to define routes in both frameworks and integrate them using Hono's middleware. ```typescript import express from 'express' import { serve } from '@hono/node-server' import { Hono } from 'hono' const expressApp = express() const honoApp = new Hono() // New code in Hono honoApp.get('/api/new', (c) => c.json({ status: 'new' })) // Old code in Express expressApp.get('/api/old', (req, res) => { res.json({ status: 'old' }) }) // Combine via middleware honoApp.all('/legacy/*', async (c) => { return new Promise((resolve) => { expressApp(c.env.incoming, c.env.outgoing, () => { resolve(new Response('')) }) }) }) serve({ fetch: honoApp.fetch }) ``` -------------------------------- ### Basic Static File Serving with serveStatic Source: https://github.com/honojs/node-server/blob/main/_autodocs/04-serve-static.md Configure the middleware to serve files from a specified root directory. Relative paths for the root are resolved from the application's startup directory. ```typescript import { serve } from '@hono/node-server' import { serveStatic } from '@hono/node-server/serve-static' import { Hono } from 'hono' const app = new Hono() // Serve all files under /static from ./public directory app.use('/static/*', serveStatic({ root: './public' })) serve(app) ``` -------------------------------- ### HTTPS Server Initialization Source: https://github.com/honojs/node-server/blob/main/_autodocs/10-configuration.md Configure the server to use HTTPS by providing a custom `createServer` function and necessary SSL certificate options. ```typescript import { serve } from '@hono/node-server' import { createServer } from 'node:https' import fs from 'node:fs' serve({ fetch: app.fetch, port: 8443, createServer: createServer, serverOptions: { key: fs.readFileSync('./key.pem'), cert: fs.readFileSync('./cert.pem'), }, }) ``` -------------------------------- ### Get Connection Information Source: https://github.com/honojs/node-server/blob/main/_autodocs/05-conninfo.md Retrieves remote client connection details from the Hono context. Ensure the context's environment includes HttpBindings. ```typescript import { serve } from '@hono/node-server' import { getConnInfo } from '@hono/node-server/conninfo' import type { HttpBindings } from '@hono/node-server' import { Hono } from 'hono' const app = new Hono<{ Bindings: HttpBindings }>() app.get('/', (c) => { const info = getConnInfo(c) return c.json({ ip: info.remote.address, port: info.remote.port, version: info.remote.addressType, }) }) serve(app) ``` -------------------------------- ### Get Connection Information with ConnInfo Helper Source: https://github.com/honojs/node-server/blob/main/README.md Import and use the `getConnInfo` helper to access connection details such as the remote address from the Hono context. ```typescript import { getConnInfo } from '@hono/node-server/conninfo' app.get('/', (c) => { const info = getConnInfo(c) // info is `ConnInfo` return c.text(`Your remote address is ${info.remote.address}`) }) ``` -------------------------------- ### HTTP/2 Plaintext Server Initialization Source: https://github.com/honojs/node-server/blob/main/_autodocs/10-configuration.md Set up an HTTP/2 server without encryption by using `node:http2`'s `createServer` function. ```typescript import { serve } from '@hono/node-server' import { createServer } from 'node:http2' serve({ fetch: app.fetch, port: 3000, createServer: createServer, }) ``` -------------------------------- ### Catching RequestError in Error Handler Source: https://github.com/honojs/node-server/blob/main/_autodocs/08-errors.md Example of using an `errorHandler` to catch and specifically handle `RequestError`. If caught, it logs a warning and returns a 400 Response. ```typescript import { RequestError } from '@hono/node-server' const listener = getRequestListener(app.fetch, { errorHandler: (err) => { if (err instanceof RequestError) { console.warn('Invalid request:', err.message) return new Response(err.message, { status: 400 }) } return undefined }, }) ``` -------------------------------- ### Implement Custom Error Handler Source: https://github.com/honojs/node-server/blob/main/_autodocs/07-types.md Example of implementing a custom error handler that logs errors and returns specific Responses based on error type. ```typescript const errorHandler: CustomErrorHandler = async (err) => { console.error('Error:', err) if (err instanceof SyntaxError) { return new Response('Invalid JSON', { status: 400 }) } return new Response('Internal Server Error', { status: 500 }) } serve({ fetch: app.fetch, errorHandler, }) ``` -------------------------------- ### HTTP/1.1 Server Initialization Source: https://github.com/honojs/node-server/blob/main/_autodocs/10-configuration.md Serve a Hono application using the default HTTP/1.1 protocol. No special configuration is needed beyond specifying the fetch handler and port. ```typescript import { serve } from '@hono/node-server' serve({ fetch: app.fetch, port: 3000, }) // Creates HTTP/1.1 server on port 3000 ``` -------------------------------- ### Get Client Connection Info Source: https://github.com/honojs/node-server/blob/main/_autodocs/00-START-HERE.md Retrieve client connection information, such as IP address, using the `getConnInfo` function within a Hono route handler. ```typescript // Get client IP const info = getConnInfo(c) ``` -------------------------------- ### Configuring Server Port and Host with dotenv Source: https://github.com/honojs/node-server/blob/main/_autodocs/10-configuration.md Use the `dotenv` package to load environment variables for configuring the server's port and hostname. ```typescript import dotenv from 'dotenv' dotenv.config() const port = parseInt(process.env.PORT || '3000') const hostname = process.env.HOST || 'localhost' serve({ fetch: app.fetch, port, hostname, }) ``` -------------------------------- ### Geo-location based Response Source: https://github.com/honojs/node-server/blob/main/_autodocs/05-conninfo.md Determines the geographical location (country, city) of the client based on their IP address using the 'geoip-lite' library. Ensure 'geoip-lite' is installed. ```typescript import geoip from 'geoip-lite' app.get('/detect-region', (c) => { const connInfo = getConnInfo(c) const geo = geoip.lookup(connInfo.remote.address || '') return c.json({ ip: connInfo.remote.address, country: geo?.country, region: geo?.city, }) }) ``` -------------------------------- ### Capture Adapter Logs in TypeScript Source: https://github.com/honojs/node-server/blob/main/_autodocs/08-errors.md Customize console.error to filter or modify adapter logs. This example prevents logging client abort messages at the debug level. ```typescript const originalError = console.error console.error = (...args) => { if (typeof args[0] === 'string' && args[0].includes('aborted')) { // Log client abort at debug level return } originalError(...args) } ``` -------------------------------- ### Response Constructor Source: https://github.com/honojs/node-server/blob/main/_autodocs/06-request-response.md Initializes a new Response object with a given body and optional initialization settings. ```APIDOC ## Response Constructor ### Description Initializes a new Response object with a given body and optional initialization settings. ### Signature ```typescript constructor(body?: BodyInit | null, init?: ResponseInit) ``` ### Example ```typescript const response = new Response('Hello World', { status: 200, headers: { 'Content-Type': 'text/plain', }, }) response.headers.set('Cache-Control', 'max-age=3600') ``` ``` -------------------------------- ### URL Validation Error Handling Source: https://github.com/honojs/node-server/blob/main/_autodocs/08-errors.md Shows an example of handling `RequestError` specifically when the error message indicates a URL parsing failure, returning a custom response. ```APIDOC ### Example: URL Validation Error ```typescript // Triggered when: // - URL contains invalid characters // - Query string is malformed // - URL path exceeds limits (browser/proxy-dependent) const listener = getRequestListener(app.fetch, { errorHandler: (err) => { if (err instanceof RequestError && err.message.includes('URL')) { return new Response('URL parsing failed', { status: 400 }) } return undefined }, }) ``` ```