Hono: Validation, RPC & Where It Fits
Request Validation
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
const schema = z.object({ name: z.string(), age: z.number() })
app.post('/users', zValidator('json', schema), (c) => {
const data = c.req.valid('json') // fully typed
return c.json({ created: data })
})Route Grouping via Sub-Apps
const usersApp = new Hono()
usersApp.get('/', (c) => c.json({ users: [] }))
const app = new Hono()
app.route('/api/users', usersApp)
// Keeps route organization modular instead of one massive fileEnd-to-End Type Safety via RPC
// server.ts
const app = new Hono().get('/users/:id', (c) => c.json({ id: c.req.param('id') }))
export type AppType = typeof app
// client.ts
import { hc } from 'hono/client'
const client = hc<AppType>('/api')
const res = await client.users[':id'].$get({ param: { id: '1' } })
// Types inferred directly from the server's route definitionsWhy Runtime Portability Matters
Cloudflare Workers and similar edge platforms don't run standard Node.js -- a framework assuming full Node API availability may not work there. Hono's runtime-agnostic design, plus reduced overhead, also helps minimize cold-start latency on serverless/edge platforms.
The Trade-off vs. a Full-Featured Framework
A minimal framework like Hono leaves choices like database access, templating, and project structure to the developer -- more flexibility for a lean, focused API, at the cost of more manual setup than an all-in-one, opinionated framework.
Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free