Skip to Content

Last Updated: 3/11/2026


Node.js

Node.js  is an open-source JavaScript runtime. Hono runs on Node.js via the @hono/node-server  adapter.

Requirements: Node.js 18.14.1+, 19.7.0+, or 20.0.0+

Setup

Create a new Node.js project:

npm create hono@latest my-app

Select nodejs when prompted, then install dependencies:

cd my-app npm install

Hello World

Edit src/index.ts:

import { serve } from '@hono/node-server' import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.text('Hello Node.js!')) serve(app)

Graceful Shutdown

Handle shutdown signals:

const server = serve(app) process.on('SIGINT', () => { server.close() process.exit(0) }) process.on('SIGTERM', () => { server.close((err) => { if (err) { console.error(err) process.exit(1) } process.exit(0) }) })

Run Locally

Start the development server:

npm run dev

Access http://localhost:3000 in your browser.

Change Port

Specify the port:

serve({ fetch: app.fetch, port: 8787, })

Serve Static Files

Use serveStatic from @hono/node-server/serve-static:

import { serveStatic } from '@hono/node-server/serve-static' app.use('/static/*', serveStatic({ root: './' })) app.use('/favicon.ico', serveStatic({ path: './favicon.ico' }))

Directory structure:

./ ├── favicon.ico ├── index.ts └── static ├── hello.txt └── image.png

rewriteRequestPath

Map URLs to different paths:

app.get( '/static/*', serveStatic({ root: './', rewriteRequestPath: (path) => path.replace(/^\/static/, '/statics'), }) )

Access Raw Node.js APIs

Access Node.js APIs via c.env:

import { Hono } from 'hono' import { serve, type HttpBindings } from '@hono/node-server' type Bindings = HttpBindings & { /* ... */ } const app = new Hono<{ Bindings: Bindings }>() app.get('/', (c) => { return c.json({ remoteAddress: c.env.incoming.socket.remoteAddress, }) }) serve(app)

HTTP/2

Unencrypted HTTP/2

import { createServer } from 'node:http2' const server = serve({ fetch: app.fetch, createServer, })

Encrypted HTTP/2

import { createSecureServer } from 'node:http2' import { readFileSync } from 'node:fs' const server = serve({ fetch: app.fetch, createServer: createSecureServer, serverOptions: { key: readFileSync('localhost-privkey.pem'), cert: readFileSync('localhost-cert.pem'), }, })

Building & Deployment

Build your application:

npm run build

Dockerfile Example

FROM node:22-alpine AS base FROM base AS builder RUN apk add --no-cache gcompat WORKDIR /app COPY package*json tsconfig.json src ./ RUN npm ci && \ npm run build && \ npm prune --production FROM base AS runner WORKDIR /app RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 hono COPY --from=builder --chown=hono:nodejs /app/node_modules /app/node_modules COPY --from=builder --chown=hono:nodejs /app/dist /app/dist COPY --from=builder --chown=hono:nodejs /app/package.json /app/package.json USER hono EXPOSE 3000 CMD ["node", "/app/dist/index.js"]