---
name: hono-edge-api
description: "Build edge-runtime APIs with Hono — routing, middleware, JWT, OpenAPI, runs on Workers/Bun/Deno. Production Hono APIs: routing, validators (Zod), JWT auth, CORS, error handlers, OpenAPI doc generation, and deploys to Cloudflare Workers, Bun, Deno, Vercel Edge, AWS Lambda — same code, multiple runtimes."
license: MIT
---

# Hono Edge API

Scaffold and ship production HTTP APIs with [Hono](https://hono.dev), a small, fast web framework whose `Request`/`Response`-based core runs unchanged across Cloudflare Workers, Bun, Deno, Vercel Edge, Netlify, and AWS Lambda. This skill sets up routing, typed validation, JWT auth, CORS, structured error handling, and OpenAPI docs so you can write the API once and deploy it to whichever runtime you need. It's for backend and full-stack developers who want low-latency edge endpoints without rewriting handlers per platform.

## When to use it

- You're starting a new JSON API and want it portable across Workers/Bun/Deno from day one.
- You need request validation tied to TypeScript types (via `@hono/zod-validator`) instead of hand-written checks.
- You want auto-generated OpenAPI specs and a Swagger UI without maintaining them by hand.
- You're migrating an Express/Fastify service to the edge and want a familiar middleware model.

## How it works

Handlers are registered on a `new Hono()` app with `app.get`, `.post`, etc. Middleware is added with `app.use`, and Hono ships first-party middleware including `cors`, `jwt` (from `hono/jwt`), `logger`, and `bearerAuth`. The context object `c` exposes `c.req`, `c.json()`, `c.text()`, and `c.var` for values set by middleware. Validation uses `zValidator('json', schema)` to parse and type the body/query/params. Errors are centralized with `app.onError` and `HTTPException`. For documented APIs, the `@hono/zod-openapi` package lets you define routes with `createRoute` so the schema and the OpenAPI document stay in sync; pair it with `@hono/swagger-ui`.

## Usage

```ts
import { Hono } from 'hono'
import { cors } from 'hono/cors'
import { jwt } from 'hono/jwt'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'

const app = new Hono()
app.use('/api/*', cors())
app.use('/api/*', jwt({ secret: 'my-secret' }))

app.post(
  '/api/users',
  zValidator('json', z.object({ name: z.string().min(1) })),
  (c) => {
    const { name } = c.req.valid('json')
    return c.json({ id: crypto.randomUUID(), name }, 201)
  }
)

export default app // Workers/Bun/Deno entry
```

Deploy with `wrangler deploy` (Workers), `bun run`, or `deno run` — the `export default app` entry works for all three.

## Tips & gotchas

- Read env/secrets from `c.env` (Workers bindings), not `process.env` — the latter is empty on most edge runtimes.
- `app.route('/sub', subApp)` mounts sub-apps; chain `.get().post()` on one `app` to preserve RPC type inference for `hono/client`.
- `c.req.valid('json')` only returns data validated by a `zValidator` on that route; calling it without the middleware returns nothing.
- On Workers, defer background work with `c.executionCtx.waitUntil()` so the response isn't blocked.

## FAQ

**Does the same code really run everywhere?** The core does. Runtime-specific bits (KV, D1, file system, cron) differ, so isolate those behind `c.env` or adapters.

**How do I get a typed client?** Export your app's type and use `hc<typeof app>(url)` from `hono/client` for end-to-end type-safe calls.

**Can I serve OpenAPI?** Yes — use `@hono/zod-openapi` with `createRoute` and mount `@hono/swagger-ui` at a route like `/docs`.
