Node.js is the most popular JavaScript runtime. Hono works seamlessly with Node.js using built-in adapters or standard Web APIs.
Quick Start
Create a new Hono project for Node.js:
npm create hono@latest my-app
Select “nodejs” as your template when prompted.
Installation
Add Hono to your existing Node.js project:
For Node.js v18+, you can use the built-in fetch adapter. For earlier versions, install an adapter:
npm install @hono/node-server
Basic Usage
Using Node.js Adapter
Create your application with the Node.js adapter:
import { Hono } from 'hono'
import { serve } from '@hono/node-server'
const app = new Hono()
app.get('/', (c) => c.text('Hello Node.js!'))
app.get('/api/hello', (c) => {
return c.json({ message: 'Hello from Node.js!' })
})
const port = 3000
console.log(`Server is running on http://localhost:${port}`)
serve({
fetch: app.fetch,
port,
})
Using Native Node.js APIs
For Node.js v18.0.0+, you can use native fetch support:
import { Hono } from 'hono'
import { createServer } from 'node:http'
const app = new Hono()
app.get('/', (c) => c.text('Hello Node.js!'))
const server = createServer((req, res) => {
const url = new URL(req.url || '', `http://${req.headers.host}`)
const request = new Request(url, {
method: req.method,
headers: req.headers as HeadersInit,
body: req.method !== 'GET' && req.method !== 'HEAD' ? req : undefined,
})
app.fetch(request).then((response) => {
res.statusCode = response.status
response.headers.forEach((value, key) => {
res.setHeader(key, value)
})
response.body?.pipeTo(new WritableStream({
write(chunk) {
res.write(chunk)
},
close() {
res.end()
},
}))
})
})
server.listen(3000, () => {
console.log('Server is running on http://localhost:3000')
})
Using @hono/node-server is recommended as it handles request/response conversion automatically.
Running Your App
With TypeScript
Using tsx for development:
Or add to package.json:
{
"scripts": {
"dev": "tsx watch index.ts",
"start": "node dist/index.js",
"build": "tsc"
}
}
With JavaScript
Adapter Features
Static Files
Serve static files using the node-server adapter:
import { Hono } from 'hono'
import { serve } from '@hono/node-server'
import { serveStatic } from '@hono/node-server/serve-static'
const app = new Hono()
app.use('/static/*', serveStatic({ root: './' }))
app.use('/favicon.ico', serveStatic({ path: './favicon.ico' }))
app.get('/', (c) => c.text('Hello!'))
serve({ fetch: app.fetch, port: 3000 })
Connection Info
Get connection information:
import { Hono } from 'hono'
import { serve } from '@hono/node-server'
import { getConnInfo } from '@hono/node-server/conninfo'
const app = new Hono()
app.get('/info', (c) => {
const info = getConnInfo(c)
return c.json({
remote: info.remote,
})
})
serve({ fetch: app.fetch, port: 3000 })
Environment Variables
Load environment variables using dotenv:
PORT=3000
API_KEY=your-secret-key
DATABASE_URL=postgres://localhost/mydb
import 'dotenv/config'
import { Hono } from 'hono'
import { serve } from '@hono/node-server'
const app = new Hono()
app.get('/config', (c) => {
return c.json({
apiKey: process.env.API_KEY,
dbUrl: process.env.DATABASE_URL,
})
})
const port = Number(process.env.PORT) || 3000
serve({ fetch: app.fetch, port })
Database Integration
PostgreSQL with Drizzle ORM
npm install drizzle-orm postgres
import { Hono } from 'hono'
import { drizzle } from 'drizzle-orm/postgres-js'
import postgres from 'postgres'
import { serve } from '@hono/node-server'
const client = postgres(process.env.DATABASE_URL!)
const db = drizzle(client)
const app = new Hono()
app.get('/users', async (c) => {
const users = await db.select().from(usersTable)
return c.json(users)
})
serve({ fetch: app.fetch, port: 3000 })
MongoDB
import { Hono } from 'hono'
import { MongoClient } from 'mongodb'
import { serve } from '@hono/node-server'
const client = new MongoClient(process.env.MONGODB_URI!)
await client.connect()
const db = client.db('myapp')
const app = new Hono()
app.get('/users', async (c) => {
const users = await db.collection('users').find().toArray()
return c.json(users)
})
serve({ fetch: app.fetch, port: 3000 })
Middleware
CORS
import { Hono } from 'hono'
import { cors } from 'hono/cors'
import { serve } from '@hono/node-server'
const app = new Hono()
app.use('/*', cors())
app.get('/', (c) => c.text('CORS enabled'))
serve({ fetch: app.fetch, port: 3000 })
Logger
import { Hono } from 'hono'
import { logger } from 'hono/logger'
import { serve } from '@hono/node-server'
const app = new Hono()
app.use('*', logger())
app.get('/', (c) => c.text('Hello!'))
serve({ fetch: app.fetch, port: 3000 })
Testing
Use any Node.js testing framework. Example with Vitest:
import { describe, it, expect } from 'vitest'
import app from './index'
describe('API Tests', () => {
it('GET /', async () => {
const res = await app.request('http://localhost/')
expect(res.status).toBe(200)
expect(await res.text()).toBe('Hello Node.js!')
})
it('GET /api/hello', async () => {
const res = await app.request('http://localhost/api/hello')
expect(res.status).toBe(200)
const json = await res.json()
expect(json.message).toBe('Hello from Node.js!')
})
})
Run tests:
Deployment
VPS/Cloud Server
Install dependencies on server
Run with PM2
Install PM2:Start your app:pm2 start dist/index.js --name my-hono-app
pm2 save
pm2 startup
Docker
Create a Dockerfile:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "dist/index.js"]
Build and run:
docker build -t my-hono-app .
docker run -p 3000:3000 my-hono-app
Heroku
Create a Procfile:
Deploy:
Best Practices
Use process managers in production
Use PM2 or systemd to keep your app running and handle restarts.
Enable clustering for multi-core
Use Node.js cluster module or PM2 cluster mode for better performance.
Implement proper error handling and logging.
TypeScript provides better type safety and developer experience.
- Use Node.js v20+ for best performance
- Enable HTTP/2 with the
http2 module
- Implement caching strategies (Redis, in-memory)
- Use a reverse proxy (nginx, Caddy) in production
- Enable gzip/brotli compression
Resources
Node.js Documentation
Official Node.js documentation
@hono/node-server
Node.js adapter for Hono