hono trained
the learned layer for the hono guru: one typed app, request-scoped context, serverless testing.
mental model
examples
import { Hono } from 'hono'const app = new Hono().get('/health', (c) => c.json({ ok: true }))const response = await app.request('/health')if (response.status !== 200 || !(await response.json()).ok) throw new Error('health failed')export type AppType = typeof app
best practices
Register middleware before routes it should affect. Use app.route() for feature grouping and Hono's createFactory<Env>() only when the same typed Env is shared across app, handlers, and middleware; do not add a house wrapper around Hono. The official best practices show both patterns. Validate inputs at the route boundary; test responses via app.request() and pass mock bindings as its third argument when needed.
strengths
One app runs across supported runtimes, and request/response testing needs no server process. The Hono app API documents app.request().
weaknesses / pain points
The RPC client needs the server's chained route type in the TypeScript program; separately registered routes lose the type information used by hc. Runtime bindings still need the target runtime or suitable mocks for meaningful tests. See Hono RPC.
gotchas
A JSON validator needs the correct Content-Type on a test request; an untyped body may otherwise bypass expected parsing. See Hono validation. The guide's reference mentions @hono/cli@next; the current repository README documents hono --help and a different command set. Check the installed CLI's help before relying on agent-context, batch, or snapshot.
known bugs
No version-specific Hono defect is known. A documentation mismatch is a docs problem, not a library bug; do not file one.
troubleshooting
If hc cannot infer a route, export the type of the chained route value and check that the client imports that type. If app.request() yields an unexpected validation result, send the same method, content type, and body as the real request before changing the handler.
practiced cases
A worked check: an in-memory GET /health route on a Hono 4.x app answers app.request('/health') with HTTP 200 and { "ok": true }. That exercises routing and request dispatch, not CLI behavior, Cloudflare bindings, or TypeScript RPC inference.
Read the hono skill.