# Hono: Das ultraschnelle Edge-Framework **Meta-Description:** Hono Framework für Edge Computing. Web Standards, Multi-Runtime Support und nur 12KB. Von Cloudflare Workers bis Bun. **Keywords:** Hono, Edge Framework, Cloudflare Workers, Web Standards, Bun, Deno, Serverless Framework, TypeScript API --- ## Einführung Hono (炎 = Flamme) ist ein **ultraschnelles Web-Framework** gebaut auf Web Standards. Mit unter 12KB läuft es auf jedem JavaScript-Runtime: Cloudflare Workers, Deno, Bun, Node.js, AWS Lambda und mehr. --- ## Hono Overview ``` ┌─────────────────────────────────────────────────────────────┐ │ HONO FRAMEWORK │ ├─────────────────────────────────────────────────────────────┤ │ │ │ Core Features: │ │ ├── Web Standards API (Request/Response) │ │ ├── Zero Dependencies │ │ ├── TypeScript First │ │ └── < 12KB (hono/tiny) │ │ │ │ Supported Runtimes: │ │ ├── Cloudflare Workers / Pages │ │ ├── Deno / Deno Deploy │ │ ├── Bun │ │ ├── Node.js │ │ ├── AWS Lambda │ │ ├── Vercel Edge │ │ ├── Fastly Compute │ │ └── Netlify Edge │ │ │ │ Built-in Middleware: │ │ ├── CORS, CSRF, ETag │ │ ├── JWT, Basic Auth, Bearer Auth │ │ ├── Logger, Pretty JSON │ │ ├── Compress, Cache │ │ └── Streaming, SSE │ │ │ └─────────────────────────────────────────────────────────────┘ ``` --- ## Quick Start ```bash # Neues Projekt npm create hono@latest my-app # Runtime wählen: # - cloudflare-workers # - cloudflare-pages # - deno # - bun # - nodejs # - vercel cd my-app npm install npm run dev ``` --- ## Basic Routing ```typescript // src/index.ts import { Hono } from 'hono'; const app = new Hono(); // Basic Routes app.get('/', (c) => c.text('Hello Hono!')); app.get('/json', (c) => { return c.json({ message: 'Hello', timestamp: Date.now() }); }); // Path Parameters app.get('/users/:id', (c) => { const id = c.req.param('id'); return c.json({ userId: id }); }); // Query Parameters app.get('/search', (c) => { const query = c.req.query('q'); const page = c.req.query('page') || '1'; return c.json({ query, page: parseInt(page) }); }); // POST mit Body app.post('/users', async (c) => { const body = await c.req.json(); return c.json({ created: body }, 201); }); // Wildcards app.get('/files/*', (c) => { const path = c.req.path; return c.text(`File path: ${path}`); }); export default app; ``` --- ## Typed Routes mit RPC ```typescript // src/index.ts import { Hono } from 'hono'; import { zValidator } from '@hono/zod-validator'; import { z } from 'zod'; const app = new Hono(); // Schema Definition const createUserSchema = z.object({ name: z.string().min(2), email: z.string().email() }); const userParamsSchema = z.object({ id: z.string().uuid() }); // Typed Route const route = app .get('/users', (c) => { return c.json([ { id: '1', name: 'Alice' }, { id: '2', name: 'Bob' } ]); }) .post( '/users', zValidator('json', createUserSchema), (c) => { const data = c.req.valid('json'); // data ist typisiert: { name: string; email: string } return c.json({ id: crypto.randomUUID(), ...data }, 201); } ) .get( '/users/:id', zValidator('param', userParamsSchema), (c) => { const { id } = c.req.valid('param'); return c.json({ id, name: 'Alice' }); } ); // Type Export für Client export type AppType = typeof route; export default app; ``` ```typescript // Client-Side (hc = Hono Client) import { hc } from 'hono/client'; import type { AppType } from './server'; const client = hc('http://localhost:8787'); // Vollständig typisiert! const users = await client.users.$get(); const newUser = await client.users.$post({ json: { name: 'Charlie', email: 'charlie@example.com' } }); ``` --- ## Middleware ```typescript import { Hono } from 'hono'; import { cors } from 'hono/cors'; import { jwt } from 'hono/jwt'; import { logger } from 'hono/logger'; import { prettyJSON } from 'hono/pretty-json'; import { secureHeaders } from 'hono/secure-headers'; import { compress } from 'hono/compress'; const app = new Hono(); // Global Middleware app.use('*', logger()); app.use('*', secureHeaders()); app.use('*', compress()); // CORS für API Routes app.use('/api/*', cors({ origin: ['https://example.com', 'https://app.example.com'], allowMethods: ['GET', 'POST', 'PUT', 'DELETE'], allowHeaders: ['Content-Type', 'Authorization'], credentials: true })); // JWT für geschützte Routes app.use('/api/protected/*', jwt({ secret: process.env.JWT_SECRET! })); // Pretty JSON in Development if (process.env.NODE_ENV === 'development') { app.use('*', prettyJSON()); } // Custom Middleware const timing = () => { return async (c, next) => { const start = Date.now(); await next(); const duration = Date.now() - start; c.header('X-Response-Time', `${duration}ms`); }; }; app.use('*', timing()); // Protected Route app.get('/api/protected/me', (c) => { const payload = c.get('jwtPayload'); return c.json({ user: payload }); }); ``` --- ## Error Handling ```typescript import { Hono } from 'hono'; import { HTTPException } from 'hono/http-exception'; const app = new Hono(); // Custom Error Handler app.onError((err, c) => { if (err instanceof HTTPException) { return c.json( { error: err.message, status: err.status }, err.status ); } console.error(err); return c.json( { error: 'Internal Server Error', status: 500 }, 500 ); }); // Not Found Handler app.notFound((c) => { return c.json({ error: 'Not Found', status: 404 }, 404); }); // Throwing Errors app.get('/users/:id', async (c) => { const user = await getUser(c.req.param('id')); if (!user) { throw new HTTPException(404, { message: 'User not found' }); } return c.json(user); }); // Mit Custom Response app.get('/admin', (c) => { const isAdmin = checkAdmin(c); if (!isAdmin) { throw new HTTPException(403, { message: 'Forbidden', res: c.json({ error: 'Admin access required' }, 403) }); } return c.json({ admin: true }); }); ``` --- ## Cloudflare Workers Integration ```typescript // src/index.ts import { Hono } from 'hono'; type Bindings = { DB: D1Database; KV: KVNamespace; AI: Ai; BUCKET: R2Bucket; }; const app = new Hono<{ Bindings: Bindings }>(); // D1 Database app.get('/users', async (c) => { const { results } = await c.env.DB .prepare('SELECT * FROM users LIMIT 10') .all(); return c.json(results); }); // KV Storage app.get('/cache/:key', async (c) => { const key = c.req.param('key'); const value = await c.env.KV.get(key); if (!value) { return c.json({ error: 'Not found' }, 404); } return c.json({ key, value: JSON.parse(value) }); }); app.put('/cache/:key', async (c) => { const key = c.req.param('key'); const body = await c.req.json(); await c.env.KV.put(key, JSON.stringify(body), { expirationTtl: 3600 // 1 Stunde }); return c.json({ success: true }); }); // R2 Storage app.post('/upload', async (c) => { const formData = await c.req.formData(); const file = formData.get('file') as File; await c.env.BUCKET.put(file.name, file); return c.json({ uploaded: file.name }); }); // Workers AI app.post('/ai/chat', async (c) => { const { message } = await c.req.json(); const response = await c.env.AI.run('@cf/meta/llama-2-7b-chat-int8', { messages: [{ role: 'user', content: message }] }); return c.json(response); }); export default app; ``` --- ## Streaming & SSE ```typescript import { Hono } from 'hono'; import { streamSSE, streamText } from 'hono/streaming'; const app = new Hono(); // Server-Sent Events app.get('/sse', (c) => { return streamSSE(c, async (stream) => { let id = 0; while (true) { await stream.writeSSE({ data: JSON.stringify({ time: new Date().toISOString() }), event: 'tick', id: String(id++) }); await stream.sleep(1000); } }); }); // Text Streaming (für AI) app.get('/stream', (c) => { return streamText(c, async (stream) => { const words = 'Hello, this is a streaming response!'.split(' '); for (const word of words) { await stream.write(word + ' '); await stream.sleep(100); } }); }); // AI Chat Streaming app.post('/chat', async (c) => { const { message } = await c.req.json(); return streamText(c, async (stream) => { const response = await openai.chat.completions.create({ model: 'gpt-4', messages: [{ role: 'user', content: message }], stream: true }); for await (const chunk of response) { const content = chunk.choices[0]?.delta?.content; if (content) { await stream.write(content); } } }); }); ``` --- ## HonoX (Meta-Framework) ```typescript // HonoX: File-based Routing + Islands Architecture // app/routes/index.tsx export default function Home() { return (

Welcome to HonoX

{/* Client Island */} ); } // app/routes/api/users.ts import { Hono } from 'hono'; const app = new Hono(); app.get('/', (c) => c.json({ users: [] })); export default app; ``` --- ## Fazit Hono bietet: 1. **Ultra-Lightweight**: < 12KB, zero dependencies 2. **Multi-Runtime**: Gleicher Code überall 3. **Web Standards**: Request/Response API 4. **Type-Safe RPC**: End-to-End TypeScript Das ideale Framework für Edge-First Entwicklung. --- ## Bildprompts 1. "Flame icon transforming into web API endpoints, Hono framework concept" 2. "Code running across multiple cloud platforms, multi-runtime visualization" 3. "Lightweight feather compared to heavy framework boxes, minimal bundle" --- ## Quellen - [Hono Documentation](https://hono.dev/) - [Hono GitHub](https://github.com/honojs/hono) - [Cloudflare Hono Guide](https://developers.cloudflare.com/workers/framework-guides/web-apps/more-web-frameworks/hono/) - [The Story of Hono](https://blog.cloudflare.com/the-story-of-web-framework-hono-from-the-creator-of-hono/)