Hono: The Ultra-Fast Web Framework for Edge, Serverless, and Node.js
Hono (Japanese for "flame") is a small, fast, and multi-runtime web framework that has become one of the most talked-about tools in the TypeScript ecosystem. It runs on Cloudflare Workers, Bun, Deno, Node.js, AWS Lambda, Fastly Compute, and more — using the same codebase, switching runtimes with a single import change.
If you've been writing Express apps but are tired of its lack of TypeScript-first design, or you're building for Cloudflare Workers and want something more ergonomic than the raw fetch handler, Hono is worth serious attention.
Why Hono Exists
Express, Fastify, and Koa were built for Node.js, predating the modern WinterCG (Web-interoperable Runtimes Community Group) standards that define how edge runtimes handle HTTP. They rely on Node.js-specific APIs (req, res, streams) that don't exist in Cloudflare Workers, Deno, or Bun.
Hono is built on the standard Request/Response API that all modern runtimes implement. Write once, deploy anywhere — to edge, serverless, or traditional server environments.
Getting Started
Install and start a basic Hono app with Bun:
bun create hono my-app
cd my-app
bun run dev
The generated app is minimal:
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => {
return c.text('Hello, Hono!')
})
export default app
For Cloudflare Workers, the entry point is the same export default app — no wrapping required.
Core Concepts
The Context Object (c)
Instead of Express-style (req, res) parameters, Hono uses a single context object c that wraps both request and response:
app.get('/users/:id', (c) => {
const id = c.req.param('id') // route params
const query = c.req.query('page') // query string
const body = await c.req.json() // request body
return c.json({ id, query }) // JSON response
return c.text('Hello') // text response
return c.html('<h1>Hi</h1>') // HTML response
return c.redirect('/other') // redirect
})
Routing
Hono's router is one of its standout features — it uses a trie-based RegExpRouter that outperforms Express's regex routing in benchmarks:
// Route parameters
app.get('/posts/:id', (c) => c.json({ id: c.req.param('id') }))
// Wildcard
app.get('/assets/*', serveStatic({ root: './public' }))
// Grouped routes with prefix
const api = new Hono()
api.get('/users', listUsers)
api.post('/users', createUser)
const app = new Hono()
app.route('/api/v1', api)
Middleware
Hono uses standard middleware that wraps handlers via app.use():
import { logger } from 'hono/logger'
import { cors } from 'hono/cors'
import { jwt } from 'hono/jwt'
app.use('*', logger())
app.use('/api/*', cors())
app.use('/protected/*', jwt({ secret: Bun.env.JWT_SECRET }))
The built-in middleware library covers the most common cases without needing additional packages.
TypeScript Integration
Hono is built TypeScript-first. Route parameters, query strings, and request/response types are inferred or declared:
// Define typed variables for route params
const app = new Hono<{
Variables: {
user: User
}
}>()
app.use('/protected/*', async (c, next) => {
const user = await getUserFromToken(c.req.header('Authorization'))
c.set('user', user)
await next()
})
app.get('/protected/profile', (c) => {
const user = c.get('user') // typed as User
return c.json(user)
})
RPC client (hono/client): One of Hono's most distinctive features. Define your routes with type information and generate a fully typed client for calling your API from the frontend:
// server.ts
const routes = app
.get('/posts', (c) => c.json([{ id: 1, title: 'Hello' }]))
.post('/posts', zValidator('json', postSchema), (c) => {
const body = c.req.valid('json')
return c.json(body)
})
export type AppType = typeof routes
// client.ts (e.g., in your Next.js or Astro frontend)
import { hc } from 'hono/client'
import type { AppType } from '../server'
const client = hc<AppType>('http://localhost:3000')
const posts = await client.posts.$get() // fully typed
This eliminates an entire category of frontend/backend type drift without needing tRPC or GraphQL.
Multi-Runtime Deployment
Switching runtimes is a one-line import change:
// For Bun
import { Hono } from 'hono'
export default app // works directly
// For Cloudflare Workers - same code, same export
// wrangler.toml points to the same file
// For Node.js
import { serve } from '@hono/node-server'
serve(app)
// For Deno Deploy
Deno.serve(app.fetch)
The same application code can run locally on Bun for development, be deployed to Cloudflare Workers for production, and run on Node.js in a Docker container for a private deployment — without modification.
When to Choose Hono Over Alternatives
| Scenario | Best Choice |
|---|---|
| Building for Cloudflare Workers | Hono — purpose-built |
| Full-stack app with SSR | Remix, Next.js, or Astro |
| Microservices on Node.js | Hono or Fastify |
| Existing Express codebase | Keep Express unless you're refactoring |
| Type-safe API with frontend client | Hono (RPC client) or tRPC |
| REST API with OpenAPI spec | Hono + Zod OpenAPI plugin |
Don't use Hono when: you need extensive middleware ecosystem compatibility (Express has thousands of middleware packages), you're in a full-stack framework that handles routing for you, or your team has deep Express expertise and no specific performance or edge requirements.
Performance
Hono consistently ranks among the fastest Node.js/edge frameworks in benchmarks. On Cloudflare Workers, it's typically within a few percent of a raw fetch handler. On Bun, routing a simple endpoint takes under 20 microseconds in most benchmarks.
For most business applications, framework routing overhead is not your bottleneck — database calls, external APIs, and business logic dominate response time. But for high-throughput APIs or edge functions where cold start and overhead matter, Hono's lightweight footprint is a genuine advantage.
Hono is one of those tools that feels immediately right once you try it. The unified context API, TypeScript-first design, and multi-runtime portability make it a strong default choice for new TypeScript API projects in 2026 — especially anything targeting Cloudflare Workers, Bun, or serverless environments.