Building with Hono
Time to assemble the pieces. A clean implementation separates routing, validation, and business logic, and wires cross-cutting concerns (auth, errors, CORS) as middleware.
A sensible structure
Section titled “A sensible structure”src/ index.ts // create the app, mount middleware + routes, start the server middleware/ // auth, error handler, CORS, rate limiting routes/ // one module per resource (articles, users, ...) services/ // business logic, independent of HTTP schemas/ // request/response validation (e.g. zod)Handlers stay thin: validate input, call a service, shape the response. Services know nothing about HTTP, so they are easy to unit-test.
A small resource, end to end
Section titled “A small resource, end to end”This Hono app brings together validation, a consistent error shape, and proper status codes for an articles resource. Open it in StackBlitz to run it:
Notice how every idea from the course shows up: a paginated collection envelope, 201 Created with Location, 422 validation with field errors, 404 via a thrown typed error, and one central onError producing problem+json.
| Advantages (Hono) | Trade-offs |
|---|---|
| Runs on edge runtimes (Cloudflare Workers, Bun, Deno) — low latency | Smaller ecosystem than Express |
| Type-safe middleware with TypeScript | A learning curve if you’re used to Express |
| Built-in validation via Zod integration | Fewer community resources than NestJS/Express |
| Faster than Express — benchmarks lead in most scenarios | No decorator-based MVC yet, unlike NestJS |
Common mistakes
Section titled “Common mistakes”No centralized error handler Symptom:
- Each route handler catches its own errors
- The error format ends up inconsistent
- Use
app.onError((err, c) => { ... })— handle every uncaught error in one place
Wrong middleware order Symptom:
- Auth middleware registered after the route — the route runs before the auth check
- Unauthenticated requests can reach a protected route
- Always register middleware before the route:
app.use(auth)beforeapp.get('/protected', handler)
💡 Real-world examples
Cloudflare Workers:
- Hono is the framework Cloudflare’s own docs recommend for Workers — runs on the V8 isolate runtime
- Very low latency because it runs at the edge, close to the user
Vercel Edge Functions:
- Hono supports the Vercel Edge runtime
- A good fit for APIs that need global low latency
Sources: Hono — getting started, Hono on Cloudflare Workers, Hono on Vercel