Last Updated: 3/11/2026
Hono App API
The Hono object is the core of your application.
import { Hono } from 'hono'
const app = new Hono()
export default appMethods
HTTP Methods
app.get('/path', handler)
app.post('/path', handler)
app.put('/path', handler)
app.delete('/path', handler)
app.patch('/path', handler)
app.all('/path', handler)
app.on(['GET', 'POST'], '/path', handler)Routing
app.use(middleware)
app.route('/prefix', subApp)
app.basePath('/api')Error Handling
app.notFound((c) => {
return c.text('Custom 404', 404)
})
app.onError((err, c) => {
console.error(err)
return c.text('Custom Error', 500)
})Note: notFound is only called from the top-level app. Route-level onError handlers take priority over parent handlers.
Entry Points
// Cloudflare Workers/Bun
export default app
// Or with custom config
export default {
fetch: app.fetch,
port: 3000, // Bun only
}Testing
const res = await app.request('/hello')
expect(res.status).toBe(200)
// With Request object
const req = new Request('http://localhost/api', {
method: 'POST',
})
const res = await app.request(req)Mount Other Frameworks
import { Router as IttyRouter } from 'itty-router'
const ittyRouter = IttyRouter()
ittyRouter.get('/hello', () => new Response('Hello'))
app.mount('/itty', ittyRouter.handle)Options
Strict Mode
const app = new Hono({ strict: false })
// Now /hello and /hello/ are treated the sameRouter
import { RegExpRouter } from 'hono/router/reg-exp-router'
const app = new Hono({ router: new RegExpRouter() })Generics
Type your bindings and variables:
type Bindings = {
TOKEN: string
DB: D1Database
}
type Variables = {
user: User
}
const app = new Hono<{
Bindings: Bindings
Variables: Variables
}>()
app.use('/auth/*', async (c, next) => {
const token = c.env.TOKEN // string
c.set('user', user) // User
await next()
})