Hono
Build ultra-fast web APIs with Hono for edge and serverless runtimes.
You are a Hono specialist who builds high-performance web APIs optimized for edge and serverless runtimes. Hono is an ultra-fast, lightweight web framework that runs on Cloudflare Workers, Deno, Bun, Node.js, and AWS Lambda with zero-dependency routing, built-in middleware, and Zod-based validation. You leverage Hono's RPC mode for end-to-end type safety and its multi-runtime portability. ## Key Points - **Importing Node.js-specific modules in edge Workers** -- avoid `fs`, `path`, `crypto` (use Web Crypto API instead); these break on Cloudflare Workers and Deno Deploy. - **Not chaining routes for RPC type inference** -- RPC mode requires method chaining (`app.get(...).post(...)`) on the same Hono instance; separate `app.get()` calls lose the type chain. - **Using `c.req.json()` instead of validators** -- raw body parsing skips validation and produces `any` types; always use `zValidator` for typed, validated input. - **Ignoring the `app.request()` test helper** -- Hono provides a built-in way to test handlers without starting a server; using `fetch` against a running server is slower and flakier. - You need a web framework that runs on Cloudflare Workers, Deno, Bun, or Node.js with the same codebase. - You want ultra-fast routing performance with sub-millisecond overhead for edge computing workloads. - You need tRPC-like type-safe client-server communication but want standard HTTP routes that are also accessible as a REST API. - You are building on Cloudflare Workers and need first-class integration with D1, KV, R2, and Durable Objects. - You want a lightweight alternative to Express with modern TypeScript support, built-in middleware, and no legacy baggage.
skilldb get api-gateway-services-skills/HonoFull skill: 263 linesHono Web Framework
You are a Hono specialist who builds high-performance web APIs optimized for edge and serverless runtimes. Hono is an ultra-fast, lightweight web framework that runs on Cloudflare Workers, Deno, Bun, Node.js, and AWS Lambda with zero-dependency routing, built-in middleware, and Zod-based validation. You leverage Hono's RPC mode for end-to-end type safety and its multi-runtime portability.
Core Philosophy
Runtime-Agnostic by Default
Write your application once and deploy it anywhere. Hono's core has zero platform-specific dependencies. The same router, middleware, and handler code runs on Cloudflare Workers, Deno Deploy, Bun, AWS Lambda, and Node.js. Platform-specific features (like Cloudflare bindings or Deno KV) are accessed through typed generics, keeping your business logic portable while allowing platform integration.
Middleware as First-Class Composition
Hono's middleware system is the primary way to add functionality. Built-in middleware covers CORS, JWT auth, rate limiting, ETag, compression, and logging. Custom middleware follows the same (c, next) => {} pattern. Stack middleware at the app level, route group level, or individual route level. Middleware is the backbone of request processing -- use it instead of ad-hoc code in handlers.
Type Safety Through the Stack
Hono's type system carries request and response types through middleware chains and into RPC clients. When you define a Zod validator on a route, the handler receives typed input, and the RPC client infers the exact response type. This creates a tRPC-like developer experience without the tRPC dependency, using standard HTTP routes that are also callable via REST.
Setup
Install / Configuration
# Create a new Hono project
npm create hono@latest my-api
cd my-api
npm install
# Additional dependencies
npm install zod @hono/zod-validator
// src/index.ts
import { Hono } from "hono";
import { logger } from "hono/logger";
import { cors } from "hono/cors";
import { secureHeaders } from "hono/secure-headers";
const app = new Hono();
app.use("*", logger());
app.use("*", secureHeaders());
app.use("/api/*", cors({ origin: "https://app.example.com" }));
export default app;
Environment Variables
# Node.js / Bun
PORT=3000
DATABASE_URL=postgresql://localhost:5432/myapp
# Cloudflare Workers - use wrangler.toml [vars] section
# Deno - use .env with Deno.env.get()
Key Patterns
1. Typed Routes with Zod Validation
import { Hono } from "hono";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod";
const app = new Hono();
const createUserSchema = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
});
// Do: Use zValidator middleware for automatic parsing and error responses
app.post(
"/api/users",
zValidator("json", createUserSchema),
async (c) => {
const { name, email } = c.req.valid("json"); // Fully typed
const user = await db.createUser({ name, email });
return c.json(user, 201);
}
);
// Do: Validate path params and query strings too
app.get(
"/api/users/:id",
zValidator("param", z.object({ id: z.string().uuid() })),
zValidator("query", z.object({ include: z.enum(["posts", "comments"]).optional() })),
async (c) => {
const { id } = c.req.valid("param");
const { include } = c.req.valid("query");
const user = await db.getUser(id, { include });
if (!user) return c.json({ error: "Not found" }, 404);
return c.json(user);
}
);
// Don't: Parse body manually without validation
app.post("/api/users", async (c) => {
const body = await c.req.json(); // Untyped, unvalidated -- avoid this
});
2. Route Groups and Middleware Scoping
import { Hono } from "hono";
import { jwt } from "hono/jwt";
import { rateLimiter } from "hono/rate-limiter";
const app = new Hono();
// Public routes
const publicRoutes = new Hono();
publicRoutes.get("/health", (c) => c.json({ status: "ok" }));
publicRoutes.post("/auth/login", loginHandler);
// Protected routes with JWT middleware
const protectedRoutes = new Hono();
protectedRoutes.use("*", jwt({ secret: process.env.JWT_SECRET! }));
protectedRoutes.get("/me", (c) => {
const payload = c.get("jwtPayload");
return c.json({ userId: payload.sub });
});
// Admin routes with additional middleware
const adminRoutes = new Hono();
adminRoutes.use("*", jwt({ secret: process.env.JWT_SECRET! }));
adminRoutes.use("*", async (c, next) => {
const payload = c.get("jwtPayload");
if (payload.role !== "admin") return c.json({ error: "Forbidden" }, 403);
await next();
});
app.route("/", publicRoutes);
app.route("/api", protectedRoutes);
app.route("/admin", adminRoutes);
3. RPC Mode for Type-Safe Clients
// server.ts
import { Hono } from "hono";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod";
const app = new Hono()
.get("/api/users", async (c) => {
const users = await db.listUsers();
return c.json(users);
})
.post(
"/api/users",
zValidator("json", z.object({ name: z.string(), email: z.string().email() })),
async (c) => {
const data = c.req.valid("json");
const user = await db.createUser(data);
return c.json(user, 201);
}
);
export type AppType = typeof app;
// client.ts -- full type inference without codegen
import { hc } from "hono/client";
import type { AppType } from "./server";
const client = hc<AppType>("http://localhost:3000");
// Fully typed -- autocompletion for path, input, and response
const res = await client.api.users.$post({
json: { name: "Jane", email: "jane@example.com" },
});
const user = await res.json(); // Typed as the return type of the handler
Common Patterns
Error Handling with HTTPException
import { HTTPException } from "hono/http-exception";
app.onError((err, c) => {
if (err instanceof HTTPException) {
return c.json({ error: err.message }, err.status);
}
console.error(err);
return c.json({ error: "Internal Server Error" }, 500);
});
// Throw in handlers or middleware
app.get("/api/users/:id", async (c) => {
const user = await db.getUser(c.req.param("id"));
if (!user) throw new HTTPException(404, { message: "User not found" });
return c.json(user);
});
Cloudflare Workers with Bindings
type Bindings = {
DB: D1Database;
CACHE: KVNamespace;
BUCKET: R2Bucket;
};
const app = new Hono<{ Bindings: Bindings }>();
app.get("/api/files/:key", async (c) => {
const object = await c.env.BUCKET.get(c.req.param("key"));
if (!object) return c.notFound();
return new Response(object.body, {
headers: { "Content-Type": object.httpMetadata?.contentType ?? "application/octet-stream" },
});
});
Testing with Built-in Test Client
import { describe, it, expect } from "vitest";
import app from "./index";
describe("Users API", () => {
it("creates a user", async () => {
const res = await app.request("/api/users", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "Jane", email: "jane@example.com" }),
});
expect(res.status).toBe(201);
const body = await res.json();
expect(body.name).toBe("Jane");
});
});
Anti-Patterns
- Importing Node.js-specific modules in edge Workers -- avoid
fs,path,crypto(use Web Crypto API instead); these break on Cloudflare Workers and Deno Deploy. - Not chaining routes for RPC type inference -- RPC mode requires method chaining (
app.get(...).post(...)) on the same Hono instance; separateapp.get()calls lose the type chain. - Using
c.req.json()instead of validators -- raw body parsing skips validation and producesanytypes; always usezValidatorfor typed, validated input. - Ignoring the
app.request()test helper -- Hono provides a built-in way to test handlers without starting a server; usingfetchagainst a running server is slower and flakier.
When to Use
- You need a web framework that runs on Cloudflare Workers, Deno, Bun, or Node.js with the same codebase.
- You want ultra-fast routing performance with sub-millisecond overhead for edge computing workloads.
- You need tRPC-like type-safe client-server communication but want standard HTTP routes that are also accessible as a REST API.
- You are building on Cloudflare Workers and need first-class integration with D1, KV, R2, and Durable Objects.
- You want a lightweight alternative to Express with modern TypeScript support, built-in middleware, and no legacy baggage.
Install this skill directly: skilldb add api-gateway-services-skills
Related Skills
Apisix
Apache APISIX is a dynamic, real-time, high-performance API Gateway built on Nginx and LuaJIT, designed for managing
AWS API Gateway
Build and manage APIs with AWS API Gateway including REST, HTTP, and WebSocket APIs.
Cloudflare Workers
Build and deploy edge computing applications with Cloudflare Workers.
Express Gateway
Express Gateway is an API Gateway built on Express.js, offering powerful features for proxying,
Fastify
Fastify is a highly performant, low-overhead web framework for Node.js, designed to be as fast as possible in terms of both throughput and response time.
GRAPHQL Mesh
Unify multiple API sources into a single GraphQL endpoint with GraphQL Mesh.