Hono.js Complete Guide: Ultra-Fast Web Framework for Edge Runtimes 2026
Master Hono.js: the ultra-fast web framework for Cloudflare Workers, Bun, Deno, and Node.js. Routing, middleware, JSX, RPC client, and performance benchmarks.
If you’ve been building APIs on Node.js with Express and wondering if there’s something faster—there is. Hono.js is a small, fast, and universally deployable web framework that runs everywhere: Cloudflare Workers, Bun, Deno, Node.js, AWS Lambda, and more. In 2026, it’s become the go-to choice for edge-deployed APIs.
This guide covers everything you need to go from zero to production with Hono.
What is Hono.js?
Hono (炎, meaning “flame” in Japanese) is a web framework built on the Web Standards API (Request/Response/fetch). Because it speaks the same language as the browser and edge runtimes natively, it doesn’t need adapters or polyfills—it just runs.
Key facts:
- ~14KB bundle size (no dependencies)
- ~1M requests/sec throughput on Cloudflare Workers in benchmarks
- Identical API across all runtimes
- TypeScript-first with full type inference
- Built-in JSX renderer, RPC client, and validation
Installation
Cloudflare Workers (recommended for edge)
npm create hono@latest my-app
# Select "cloudflare-workers" template
cd my-app
npm install
npm run dev
Bun
bun create hono@latest my-app
# Select "bun" template
cd my-app
bun install
bun run dev
Node.js
npm create hono@latest my-app
# Select "nodejs" template
cd my-app
npm install
npm run dev
Deno
import { Hono } from 'npm:hono'
The same Hono import works everywhere. This is the key insight: learn once, deploy anywhere.
Basic Routing
Hono’s routing API is similar to Express but fully typed:
import { Hono } from 'hono'
const app = new Hono()
// Basic routes
app.get('/', (c) => c.text('Hello Hono!'))
app.post('/users', (c) => c.json({ created: true }))
app.put('/users/:id', (c) => c.json({ updated: c.req.param('id') }))
app.delete('/users/:id', (c) => c.json({ deleted: true }))
export default app
Route Parameters
app.get('/posts/:id/comments/:commentId', (c) => {
const { id, commentId } = c.req.param()
return c.json({ postId: id, commentId })
})
Query Parameters
app.get('/search', (c) => {
const query = c.req.query('q')
const page = c.req.query('page') ?? '1'
return c.json({ query, page: parseInt(page) })
})
Route Groups
const api = new Hono().basePath('/api')
api.get('/users', (c) => c.json([]))
api.get('/users/:id', (c) => c.json({ id: c.req.param('id') }))
app.route('/', api)
Middleware
Middleware in Hono uses the same async (c, next) pattern. It runs before and after handlers.
Built-in Middleware
import { Hono } from 'hono'
import { logger } from 'hono/logger'
import { cors } from 'hono/cors'
import { bearerAuth } from 'hono/bearer-auth'
const app = new Hono()
// Logging
app.use('*', logger())
// CORS
app.use('/api/*', cors({
origin: 'https://myapp.com',
allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
}))
// Bearer token auth
app.use('/admin/*', bearerAuth({ token: process.env.ADMIN_TOKEN! }))
Custom Middleware
// Timing middleware
app.use('*', async (c, next) => {
const start = Date.now()
await next()
const ms = Date.now() - start
c.header('X-Response-Time', `${ms}ms`)
})
// Auth middleware with context
app.use('/protected/*', async (c, next) => {
const token = c.req.header('Authorization')?.replace('Bearer ', '')
if (!token) return c.json({ error: 'Unauthorized' }, 401)
// Attach user to context
c.set('user', { id: '123', token })
await next()
})
// Access in handler
app.get('/protected/profile', (c) => {
const user = c.get('user')
return c.json(user)
})
Error Handling
app.onError((err, c) => {
console.error(err)
return c.json({ error: err.message }, 500)
})
app.notFound((c) => c.json({ error: 'Not found' }, 404))
Request and Response Helpers
The context object c is Hono’s primary API surface:
app.post('/data', async (c) => {
// Parse body
const body = await c.req.json() // JSON
const form = await c.req.formData() // Form data
const text = await c.req.text() // Raw text
// Headers
const auth = c.req.header('Authorization')
const ua = c.req.header('User-Agent')
// Cookies
const session = getCookie(c, 'session')
// Response types
return c.json({ ok: true }, 201) // JSON
return c.text('Hello', 200) // Plain text
return c.html('<h1>Hello</h1>') // HTML
return c.redirect('/new-url') // Redirect
return c.stream(async (stream) => { // Streaming
await stream.write('chunk1')
await stream.write('chunk2')
})
})
Input Validation with Zod
Hono integrates with Zod via the @hono/zod-validator package:
npm install zod @hono/zod-validator
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
const createUserSchema = z.object({
name: z.string().min(2),
email: z.string().email(),
age: z.number().min(18).optional(),
})
app.post(
'/users',
zValidator('json', createUserSchema),
async (c) => {
const user = c.req.valid('json') // Fully typed!
// user.name, user.email are guaranteed valid
return c.json({ created: user }, 201)
}
)
Validation errors automatically return 400 with error details.
JSX Support
Hono has a built-in JSX renderer for server-side HTML generation—no React required:
/** @jsx jsx */
/** @jsxImportSource hono/jsx */
import { Hono } from 'hono'
import { html } from 'hono/html'
const app = new Hono()
const Layout = ({ children }: { children: any }) => html`
<!DOCTYPE html>
<html>
<head><title>My App</title></head>
<body>${children}</body>
</html>
`
app.get('/', (c) => {
return c.html(
<Layout>
<h1>Hello from Hono JSX!</h1>
</Layout>
)
})
For full JSX with component files, configure your tsconfig.json:
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "hono/jsx"
}
}
RPC Client (Type-Safe API Calls)
This is Hono’s killer feature: a type-safe client generated from your server routes.
Server (api.ts):
import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
const app = new Hono()
.get('/posts', (c) => c.json([{ id: 1, title: 'Hello' }]))
.post(
'/posts',
zValidator('json', z.object({ title: z.string() })),
async (c) => {
const { title } = c.req.valid('json')
return c.json({ id: 2, title }, 201)
}
)
export type AppType = typeof app
export default app
Client (client.ts):
import { hc } from 'hono/client'
import type { AppType } from './api'
const client = hc<AppType>('https://api.example.com')
// Fully typed!
const posts = await client.posts.$get()
const data = await posts.json() // type: { id: number, title: string }[]
const created = await client.posts.$post({
json: { title: 'New Post' },
})
No code generation, no schemas to maintain—the types flow directly from your route definitions.
Deploying to Cloudflare Workers
Cloudflare Workers is where Hono shines brightest. Your app runs at the edge, within 50ms of every user globally.
// src/index.ts
import { Hono } from 'hono'
const app = new Hono<{ Bindings: Env }>()
app.get('/kv/:key', async (c) => {
// Access KV, D1, R2, and other Cloudflare bindings
const value = await c.env.MY_KV.get(c.req.param('key'))
return c.json({ value })
})
app.post('/db', async (c) => {
const body = await c.req.json()
const result = await c.env.DB.prepare(
'INSERT INTO items (name) VALUES (?)'
).bind(body.name).run()
return c.json(result)
})
export default app
wrangler.toml:
name = "my-api"
main = "src/index.ts"
compatibility_date = "2026-01-01"
[[kv_namespaces]]
binding = "MY_KV"
id = "your-kv-namespace-id"
[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "your-d1-id"
Deploy:
npx wrangler deploy
Bun Deployment
import { Hono } from 'hono'
import { serve } from '@hono/node-server'
const app = new Hono()
app.get('/', (c) => c.text('Hello from Bun!'))
serve({ fetch: app.fetch, port: 3000 })
bun run src/index.ts
Performance Benchmarks
Hono consistently tops framework benchmarks for edge and server runtimes. Approximate request/sec on Bun:
| Framework | Req/sec |
|---|---|
| Hono | ~310,000 |
| Elysia | ~295,000 |
| Fastify | ~80,000 |
| Express | ~25,000 |
On Cloudflare Workers, Hono handles over 1M req/sec in benchmarks because routing uses a RadixTree algorithm with zero regex overhead.
The performance gap with Express isn’t just raw speed—it’s cold start time. Hono’s ~14KB bundle initializes near-instantly, while Express with its dependency chain can add 100ms+ to cold starts on serverless platforms.
Advanced Patterns
App Factory Pattern
// Testable app factory
export function createApp(config: Config) {
const app = new Hono()
app.use('*', logger())
app.use('*', cors({ origin: config.allowedOrigins }))
app.route('/api/v1', createV1Routes(config))
return app
}
// Test
const app = createApp({ allowedOrigins: ['http://localhost:3000'] })
const res = await app.request('/api/v1/users')
Testing with Hono’s Test Helpers
import { describe, it, expect } from 'bun:test'
import app from './app'
describe('Users API', () => {
it('GET /users returns array', async () => {
const res = await app.request('/users')
expect(res.status).toBe(200)
const body = await res.json()
expect(Array.isArray(body)).toBe(true)
})
it('POST /users creates user', async () => {
const res = await app.request('/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Test', email: '[email protected]' }),
})
expect(res.status).toBe(201)
})
})
No mocking required—Hono’s request method accepts standard Request objects.
When to Use Hono
Great fit:
- Cloudflare Workers / edge APIs
- Bun or Deno servers
- Microservices where bundle size matters
- Projects needing type-safe API clients (Hono RPC)
- Full-stack TypeScript projects
Consider alternatives:
- Large monolithic apps with complex plugin ecosystems (consider Fastify)
- Apps with heavy ORM integrations where Prisma’s Node.js dependency chain is fine
- Teams deeply invested in NestJS’s dependency injection patterns
Key Takeaways
Hono.js is the web framework built for 2026. It runs everywhere the Web Standards API exists, delivers near-zero overhead routing, and the RPC client feature eliminates an entire category of type-safety problems in full-stack TypeScript apps.
For edge deployments especially, there’s no real competitor. If you’re building a new API or microservice in 2026, Hono should be your first evaluation.
Explore Hono tools on DevPlaybook:
- API Testing Tools — test your Hono endpoints
- JSON Formatter — format API responses
- JWT Decoder — debug JWT auth middleware
50 CLI Commands That Save Hours Every Week
The exact Git shortcuts, file search tricks, Docker commands, and productivity hacks that senior developers use daily. Compiled from 5+ years of shipping production code.
- Git mastery (10 cmds)
- File & search wizardry
- Docker & DevOps tricks
- Process & network tools
- Productivity boosters
- macOS & Linux install guide
No spam. 1 email/week max. Unsubscribe anytime.
Found this guide useful? Check out our free developer tools.
Affiliate disclosure: Some links below are affiliate links — we may earn a small commission at no extra cost to you. Learn more.
Recommended Tools & Resources
DigitalOcean
$200 credit for new users. Simple, affordable cloud hosting for developers.
GitHub Student Pack
Free access to 100+ developer tools. Perfect for students and new devs.
Vercel
Deploy frontend apps instantly. Free tier is generous for side projects.
DevPlaybook Products
Boilerplates, scripts & AI toolkits to 10x your dev workflow.