Hono (japanisch für „Flamme") ist ein radikal leichtgewichtiges, ultraschnelles Web-Framework für TypeScript — und es hat 2026 Express, Fastify und viele andere ernsthaft unter Druck gesetzt. Mit einem Bundle-Size von unter 15 kB, nativer Edge-Unterstützung und einem vollständig typsicheren RPC-Client ist Hono die erste Wahl für APIs auf Cloudflare Workers, Bun, Deno und Node.js.

Kombiniert mit Claude Code — Anthropics KI-gestütztem Terminal-Agenten — lassen sich Hono-APIs in Minuten scaffolden, debuggen und deployen. In diesem Artikel zeigen wir dir, wie beides zusammenspielt.

<15kB Bundle-Size (gzip)
~140k GitHub Stars (2026)
6 Runtimes supported
100% TypeScript-first

1. Hono Grundlagen — Setup und erste Route

Was ist Hono?
Routing Ultra-Performance Multi-Runtime JSX

Hono liefert schnelles Routing via Trie-Baum, nativen TypeScript-Support, einen Context-basierten Handler-Ansatz und läuft auf allen modernen JS-Runtimes ohne Änderungen.

Installation ist denkbar einfach. Du brauchst nur npm (oder bun/deno):

Terminal

# Mit npm (Node.js oder Bun) npm install hono # Mit Bun direkt bun add hono # Für Cloudflare Workers npm create cloudflare@latest my-api -- --template=hono

Die grundlegende Struktur einer Hono-App sieht so aus — vollständig typsicher, keine externe Config notwendig:

src/index.ts — Hono Basis-App

import { Hono } from 'hono' // App-Instanz erstellen (optional: typisierte Bindings für CF Workers) const app = new Hono() // GET - einfache JSON-Antwort app.get('/', (c) => { return c.json({ message: 'Hono läuft!', runtime: c.env?.RUNTIME ?? 'node' }) }) // POST - Body auslesen app.post('/items', async (c) => { const body = await c.req.json() return c.json({ created: body }, 201) }) // PUT - Item aktualisieren app.put('/items/:id', async (c) => { const id = c.req.param('id') const body = await c.req.json() return c.json({ id, updated: body }) }) // DELETE - Item löschen app.delete('/items/:id', (c) => { const id = c.req.param('id') return c.json({ deleted: id }) }) // Text-Antwort statt JSON app.get('/health', (c) => c.text('OK')) // HTML-Antwort app.get('/ping', (c) => c.html('<b>pong</b>')) export default app
Claude Code Tipp

Mit Claude Code kannst du einfach tippen: "Erstelle eine Hono API mit CRUD-Endpunkten für Produkte, Zod-Validierung und SQLite-Backend." Claude generiert die komplette Struktur inklusive Typen, Tests und Deployment-Config — in weniger als 60 Sekunden.

Context-Objekt (c) — Das Herzstück

Jeder Hono-Handler bekommt ein typisiertes Context-Objekt c. Darüber greifst du auf Request, Response, Environment-Bindings und Variablen zu:

src/context-demo.ts

import { Hono } from 'hono' // Typisierte Env-Bindings (z.B. Cloudflare Workers KV, D1, R2) type Bindings = { DB: D1Database KV: KVNamespace API_SECRET: string } // Typisierte Variablen (gesetzt von Middleware) type Variables = { user: { id: string; email: string } } const app = new Hono<{ Bindings: Bindings; Variables: Variables }>() app.get('/profile', async (c) => { // Request-Infos const url = c.req.url const method = c.req.method const header = c.req.header('Authorization') // Env-Bindings (Cloudflare Workers) const secret = c.env.API_SECRET // Variablen aus Middleware (typsicher!) const user = c.get('user') // Status-Code setzen c.status(200) return c.json({ url, method, user, secret: '***' }) })

Multi-Platform Support

☁️
Cloudflare Workers
Native Edge-Support
🟢
Node.js
@hono/node-server
🦕
Deno
Deno.serve() direkt
🍞
Bun
Bun.serve() nativ
AWS Lambda
Lambda-Adapter
🔥
Fastly Compute
Edge-native

2. Routing & Gruppen — Strukturierte APIs

Hono bietet ein mächtiges Routing-System: verschachtelte Gruppen, Wildcard-Routen, optionale Parameter und reguläre Ausdrücke — alles vollständig typsicher.

src/routes/users.ts — Routen-Gruppe

import { Hono } from 'hono' const users = new Hono() // Basis-Route: GET /users users.get('/', (c) => { return c.json([{ id: 1, name: 'Anna' }, { id: 2, name: 'Ben' }]) }) // Named Parameter: GET /users/:id users.get('/:id', (c) => { const id = c.req.param('id') return c.json({ id: parseInt(id), name: 'Anna' }) }) // Mehrere Parameter: GET /users/:userId/posts/:postId users.get('/:userId/posts/:postId', (c) => { const { userId, postId } = c.req.param() return c.json({ userId, postId }) }) // Query-Parameter: GET /users/search?q=anna&limit=10 users.get('/search', (c) => { const q = c.req.query('q') ?? '' const limit = parseInt(c.req.query('limit') ?? '20') return c.json({ results: [], query: q, limit }) }) // Wildcard: GET /users/files/* (z.B. /users/files/docs/report.pdf) users.get('/files/*', (c) => { const path = c.req.param('*') return c.text(`Datei: ${path}`) }) export default users

src/index.ts — Routen mounten

import { Hono } from 'hono' import users from './routes/users' import products from './routes/products' import orders from './routes/orders' const app = new Hono() // API-Version als Prefix const api = new Hono().basePath('/api/v1') // Routen-Gruppen mounten api.route('/users', users) // /api/v1/users/* api.route('/products', products) // /api/v1/products/* api.route('/orders', orders) // /api/v1/orders/* // App zusammensetzen app.route('/', api) // 404 Fallback app.notFound((c) => c.json({ error: 'Route nicht gefunden' }, 404)) // Error Handler app.onError((err, c) => { console.error(err) return c.json({ error: err.message }, 500) }) export default app
Performance-Vorteil

Hono nutzt einen Radix-Tree-Router (TrieRouter), der selbst bei tausenden von Routen konstant schnell bleibt. In Benchmarks schlägt er Express um den Faktor 10–20 und Fastify um 2–5 bei einfachen Routing-Szenarien.

3. Middleware — Mächtige Request-Pipeline

Built-in Middleware
logger cors bearer-auth cache compress etag timing jwt rate-limit

Hono bringt alle gängigen Middlewares direkt mit — kein Express-Ökosystem nötig.

src/middleware.ts — Built-in Middlewares

import { Hono } from 'hono' import { logger } from 'hono/logger' import { cors } from 'hono/cors' import { bearerAuth } from 'hono/bearer-auth' import { cache } from 'hono/cache' import { compress } from 'hono/compress' import { timing } from 'hono/timing' const app = new Hono() // Logging aller Requests (Methode, Path, Status, Dauer) app.use('*', logger()) // CORS für Frontend-Domains app.use('/api/*', cors({ origin: ['https://agentic-movers.com', 'https://app.agentic-movers.com'], allowMethods: ['GET', 'POST', 'PUT', 'DELETE'], allowHeaders: ['Content-Type', 'Authorization'], maxAge: 86400, })) // Bearer Token Auth für geschützte Routen app.use('/api/admin/*', bearerAuth({ token: 'super-secret-token-123' })) // Response-Caching (nur Cloudflare Workers) app.use('/api/public/*', cache({ cacheName: 'hono-cache-v1', cacheControl: 'max-age=3600', })) // GZIP-Komprimierung app.use('*', compress()) // Server-Timing Header (für Performance-Debugging) app.use('*', timing()) app.get('/api/data', (c) => c.json({ ok: true })) export default app

Custom Middleware schreiben

Eigene Middleware ist in Hono genauso einfach wie in Express — aber vollständig typsicher und mit Zugriff auf die typisierten Variablen:

src/middleware/auth.ts — Custom Auth-Middleware

import { MiddlewareHandler } from 'hono' import { HTTPException } from 'hono/http-exception' type AuthUser = { id: string; email: string; role: 'admin' | 'user' } // Auth-Middleware: JWT verifizieren und User in Context setzen export const authMiddleware: MiddlewareHandler = async (c, next) => { const authHeader = c.req.header('Authorization') if (!authHeader?.startsWith('Bearer ')) { throw new HTTPException(401, { message: 'Kein Bearer Token' }) } const token = authHeader.slice(7) try { // Token verifizieren (hier: vereinfacht) const user: AuthUser = await verifyToken(token) c.set('user', user) // typsicher dank Variables-Generic await next() // nächste Middleware / Handler aufrufen } catch { throw new HTTPException(403, { message: 'Ungültiger Token' }) } } // Execution-Order: Middleware läuft BEFORE und AFTER Handler const timingMiddleware: MiddlewareHandler = async (c, next) => { const start = Date.now() await next() // Handler ausführen const ms = Date.now() - start c.res.headers.set('X-Response-Time', `${ms}ms`) } // Dummy für Beispiel async function verifyToken(token: string): Promise<AuthUser> { return { id: 'u1', email: 'anna@example.com', role: 'user' } }
Middleware-Execution-Order

In Hono läuft der Code vor await next() beim Request, und der Code nach await next() bei der Response. Das erlaubt Pre/Post-Processing in einer einzigen Funktion — wie bei Koa.js.

4. Zod-Validierung — Typsichere Request-Validierung

zValidator z.object() Body Query Param

Hono integriert nahtlos mit Zod via @hono/zod-validator. Validierung, Typsicherheit und Fehler-Handling in einem — ohne Boilerplate.

Terminal — Zod-Validator installieren

npm install @hono/zod-validator zod

src/routes/products.ts — Vollständige Zod-Validierung

import { Hono } from 'hono' import { zValidator } from '@hono/zod-validator' import { z } from 'zod' const products = new Hono() // Schema-Definitionen const ProductSchema = z.object({ name: z.string().min(2).max(100), price: z.number().positive(), category: z.enum(['electronics', 'clothing', 'food']), description: z.string().optional(), tags: z.array(z.string()).default([]), }) const QuerySchema = z.object({ page: z.coerce.number().min(1).default(1), limit: z.coerce.number().min(1).max(100).default(20), category: z.enum(['electronics', 'clothing', 'food']).optional(), q: z.string().optional(), }) const ParamSchema = z.object({ id: z.string().uuid('Ungültige Produkt-ID'), }) // GET /products?page=1&limit=20&category=electronics products.get('/', zValidator('query', QuerySchema), (c) => { const { page, limit, category, q } = c.req.valid('query') // typsicher! return c.json({ products: [], page, limit, category, q }) } ) // POST /products — Body-Validierung products.post('/', zValidator('json', ProductSchema), async (c) => { const product = c.req.valid('json') // Typ: z.infer<typeof ProductSchema> // product.name ist string, product.price ist number — kein Cast nötig! return c.json({ id: 'uuid-here', ...product }, 201) } ) // GET /products/:id — Param-Validierung products.get('/:id', zValidator('param', ParamSchema), (c) => { const { id } = c.req.valid('param') return c.json({ id, name: 'Laptop', price: 999.99 }) } ) // Zod-Fehler automatisch als 400-JSON zurückgeben products.get('/validate-custom', zValidator('query', QuerySchema, (result, c) => { if (!result.success) { return c.json({ error: 'Validierungsfehler', details: result.error.flatten().fieldErrors, }, 400) } }) ) export default products
Kein Runtime-Cast mehr

c.req.valid('json') gibt den vollständig typisierten Wert zurück. TypeScript weiß, dass product.price eine number ist — ohne manuelle Casts oder as-Assertions. Claude Code kann damit komplette APIs mit Typen von der Validierung bis zur Datenbankschicht generieren.

5. Hono RPC — Typsicherer API-Client

Das RPC-System
hc Client AppType Export Type Inference No Code-Gen

Mit dem hc-Client inferiert TypeScript automatisch alle API-Typen vom Server — ohne Code-Generator, ohne OpenAPI-Schema, ohne manuelle Type-Definitionen. Ändert sich die Server-API, zeigt TypeScript sofort Fehler im Client.

src/api/rpc-server.ts — Server mit AppType Export

import { Hono } from 'hono' import { zValidator } from '@hono/zod-validator' import { z } from 'zod' const app = new Hono() const route = app .get('/users', zValidator('query', z.object({ limit: z.coerce.number().default(10) })), (c) => { const { limit } = c.req.valid('query') return c.json({ users: [{ id: 1, name: 'Anna' }], limit }) } ) .post('/users', zValidator('json', z.object({ name: z.string(), email: z.string().email() })), async (c) => { const body = c.req.valid('json') return c.json({ id: 99, ...body }, 201) } ) .delete('/users/:id', (c) => { return c.json({ deleted: c.req.param('id') }) }) // AppType exportieren — das ist der Schlüssel für den typisierten Client! export type AppType = typeof route export default app

src/client/api.ts — Typsicherer hc-Client

import { hc } from 'hono/client' import type { AppType } from '../api/rpc-server' // Client erstellen — Base-URL reicht const client = hc<AppType>('https://api.agentic-movers.com') // Alle Aufrufe sind vollständig typsicher! async function demo() { // GET /users?limit=5 — TypeScript kennt Query-Typen const res1 = await client.users.$get({ query: { limit: 5 } }) const data = await res1.json() // data.users → { id: number; name: string }[] — automatisch inferiert! console.log(data.users) // POST /users — TypeScript prüft den Body const res2 = await client.users.$post({ json: { name: 'Ben', email: 'ben@example.com' } }) const newUser = await res2.json() console.log(newUser.id) // number — TypeScript weiß das! // DELETE /users/:id const res3 = await client.users[':id'].$delete({ param: { id: '42' } }) console.log(await res3.json()) } // Fehler-Handling async function safeGet() { const res = await client.users.$get({ query: { limit: 10 } }) if (!res.ok) { throw new Error(`API-Fehler: ${res.status}`) } return res.json() }
Kein Code-Generator nötig

Der Hono RPC-Client ist das Killer-Feature: Im Gegensatz zu tRPC braucht ihr kein separates Framework-Setup. Im Gegensatz zu OpenAPI kein YAML-Schema und keinen Code-Generator. TypeScript inferiert die kompletten API-Typen direkt aus dem Server-Code — und Claude Code kann das in Sekunden aufsetzen.

Vergleich: Hono RPC vs. Alternativen

Feature Hono RPC tRPC OpenAPI REST (plain)
Typsicher End-to-End ✓ Ja ✓ Ja ~ Teilweise ✗ Nein
Code-Generator nötig ✗ Nein ✗ Nein ✓ Ja ✗ Nein
HTTP-Standard (REST) ✓ Ja ✗ Nein ✓ Ja ✓ Ja
Multi-Runtime ✓ 6+ Runtimes ~ Node/Edge ✓ Überall ✓ Überall
Bundle-Size ~15kB ~45kB +Schema minimal

6. Deployment — Gleicher Code, alle Plattformen

Das Killer-Feature von Hono ist, dass derselbe Code auf sechs verschiedenen Runtimes läuft. Nur der Entry-Point unterscheidet sich:

Cloudflare Workers — wrangler.toml + src/index.ts

// wrangler.toml name = "meine-api" main = "src/index.ts" compatibility_date = "2026-01-01" // src/index.ts — GLEICH wie oben, kein Adapter nötig! import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.json({ runtime: 'cloudflare-workers' })) export default app // CF Workers erwartet default export // Deploy // $ wrangler deploy

Node.js — @hono/node-server

import { serve } from '@hono/node-server' import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.json({ runtime: 'node' })) serve({ fetch: app.fetch, port: 3000 }, (info) => { console.log(`Server läuft auf http://localhost:${info.port}`) })

Bun — Nativ ohne Adapter

import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.json({ runtime: 'bun' })) export default { port: 3000, fetch: app.fetch, // Bun erwartet fetch-Handler }

Deno — Auch nativ

import { Hono } from 'npm:hono' const app = new Hono() app.get('/', (c) => c.json({ runtime: 'deno' })) Deno.serve(app.fetch)

JSX- und HTML-Rendering mit Hono

Hono kann auch serverseitig HTML rendern — mit JSX, komplett ohne React:

src/views/landing.tsx — JSX-Rendering

import { Hono } from 'hono' import { html } from 'hono/html' const app = new Hono() // JSX-Komponente (tsconfig: jsx: "react-jsx", jsxImportSource: "hono/jsx") const Layout = ({ title, children }: { title: string; children: JSX.Element }) => ( <html lang="de"> <head> <meta charset="UTF-8" /> <title>{title}</title> </head> <body>{children}</body> </html> ) const HomePage = ({ users }: { users: { id: number; name: string }[] }) => ( <Layout title="Hono SSR"> <main> <h1>User-Liste</h1> <ul> {users.map((u) => ( <li key={u.id}>{u.name}</li> ))} </ul> </main> </Layout> ) app.get('/', (c) => { const users = [{ id: 1, name: 'Anna' }, { id: 2, name: 'Ben' }] return c.html(<HomePage users={users} />) })

Claude Code + Hono: Empfohlener Workflow

Hinweis zu Node.js-Kompatibilität

Wenn du von Express migrierst: Hono unterstützt keine req.socket- oder res.write()-APIs direkt. Streaming-Responses laufen über c.stream() und c.streamText() — was für SSE und LLM-Streaming sogar angenehmer ist.

Performance-Benchmark 2026

Requests/Sekunde (Bun + Hono vs. Alternativen)
FrameworkRuntimeReq/sLatenz p99
HonoBun~210.0000.8ms
HonoNode.js~95.0001.4ms
FastifyNode.js~75.0001.9ms
ExpressNode.js~18.0006.2ms
NestJSNode.js~12.0009.1ms

* Synthetische Benchmarks, Hello-World-Route. Reale Werte hängen stark von Datenbanklatenz und Business-Logik ab.

Hono-APIs mit KI bauen — kostenlos ausprobieren

Starte deinen kostenlosen Trial und lass Claude Code deine nächste Hono-API in Minuten aufsetzen — mit Zod, RPC-Client und Cloudflare Workers Deployment.

Kostenlos starten — kein Code nötig

Kein Setup. Kein Kreditkarte. Sofort loslegen.

Fazit — Lohnt sich Hono 2026?

Ja, absolut — und zwar für fast alle Einsatzszenarien, die bisher Express, Fastify oder NestJS verwendet haben. Hono ist kein Hype-Framework: Es hat einen stabilen API-Kern, aktive Community, hervorragende TypeScript-Integration und löst das Multi-Runtime-Problem elegant.

Besonders die Kombination aus Zod-Validierung + typsicherem RPC-Client macht Hono zum idealen Framework für moderne Full-Stack-TypeScript-Projekte. Und mit Claude Code als KI-Partner lässt sich eine komplette typsichere API — inklusive Tests, Deployment-Config und Client-Code — in einer einzigen Session aufsetzen.

Probiere Hono aus — und wenn du dabei Unterstützung durch KI-Agenten willst, die deinen Code schreiben, reviewen und deployen, dann schau dir unseren Trial an.

Weiterführende Links: Hono DokumentationHono auf GitHubWeitere Artikel