@hono/node-server
The official Node.js adapter that runs your Hono application on a native Node HTTP server using web-standard APIs.
Repository Health
Technical Analysis
@hono/node-server is the official adapter that lets you run a Hono application on Node.js without changing your handler code. Hono was originally built for edge runtimes like Cloudflare Workers, Deno, and Bun, and this package bridges that web-standard fetch model onto Node’s built-in http and http2 servers.
It ships lightweight Request and Response implementations that avoid unnecessary copying, giving benchmark throughput several times higher than a comparable Express server. Beyond the core serve() entry point, it bundles Node-specific helpers for static file serving, WebSocket upgrades, connection info, and direct access to the underlying Node request/response objects.
What You Get
- A one-line
serve(app)entry point that boots a native Node HTTP (or HTTP/2, or HTTPS) server for any Hono app. - Lightweight Request/Response shims that override the global objects for markedly faster throughput than a plain Express server.
- A Node-native serve-static middleware with precompression, path rewriting, and found/not-found hooks.
- First-class WebSocket upgrade support via
upgradeWebSocketbacked by awsWebSocketServer. - Helpers for connection info (
getConnInfo) and typed access to the raw NodeIncomingMessage/ServerResponsethroughc.env.
Common Use Cases
- Deploying a Hono API to a traditional Node.js host, container, or VM instead of an edge runtime.
- Serving static assets and a Hono API from the same Node process.
- Adding realtime WebSocket endpoints to a Hono application running on Node.
- Migrating an existing Node.js HTTP service to Hono incrementally by responding directly from the Node API where needed.
Under The Hood
Architecture — The adapter is organized as a thin bridge over Node’s HTTP stack. server.ts exposes createAdaptorServer/serve, which build a native node:http (or a user-supplied HTTP/2 or HTTPS) server whose request handler comes from getRequestListener in listener.ts. That listener is the core: it wraps each Node IncomingMessage in a lightweight web Request (request.ts), invokes the app’s fetch callback, and streams the returned Response back through response.ts, using symbol-tagged internal state, explicit incoming-body draining, and configurable auto-cleanup to keep half-read connections from stalling the server. Peripheral concerns are isolated in their own modules — websocket.ts (upgrade handling atop a ws server), serve-static.ts, conninfo.ts, and url.ts.
Tech Stack — The package is written almost entirely in TypeScript (~99%) with zero runtime dependencies; hono is a ^4 peer dependency and ws is optional for WebSockets. It targets Node >=20 and builds only on the standard library (node:http, node:http2, node:stream, node:net, node:tls). Tooling is modern: tsdown for the dual ESM/CJS build with subpath exports, Vitest plus supertest for tests, publint for package linting, and ESLint/Prettier for style.
Code Quality — Fifteen Vitest test files exercise the listener, request/response shims, WebSockets, conninfo, serve-static, and edge cases like client disconnects, giving strong coverage of the tricky streaming paths. The code is carefully typed, leans on Symbols for private state, mirrors native Request/Response semantics closely (including guarding against re-reading consumed bodies), and handles resource cleanup and error translation (RequestError, toRequestError) explicitly rather than swallowing failures.
API Design — The public surface is deliberately minimal: serve(app) is a genuine one-liner, and everything else is opt-in through a well-typed Options object (port, hostname, createServer, serverOptions, websocket, overrideGlobalObjects, autoCleanupIncoming). Extra capabilities live behind clean subpath imports (@hono/node-server/serve-static, /conninfo, /utils/response), and the README is thorough with runnable examples for every option, HTTPS, HTTP/2, UNIX sockets, and the raw-Node escape hatch — so getting started requires almost no boilerplate.