Tüm Yazılar
KategoriBackend
Okuma Süresi
14 dk okuma
Yayın Tarihi
...
Kelime Sayısı
3.093kelime

Kahveni hazırla - bu içerikli bir makale!

Hono.js ultra-hızlı web framework, multi-runtime desteği (Workers, Deno, Bun, Node), middleware sistemi, RPC mode ve production deployment deneyimi.

Hono.js: Serverless Web Framework Production Rehberi 2026

# Hono.js: Serverless Web Framework Production Rehberi 2026

Cloudflare Workers ekosistemi büyüdükçe, edge-first bir web framework ihtiyacı da giderek daha kritik hale geldi. Hono.js tam da bu noktada ortaya çıktı: sub-12KB bundle size, ~150K req/sec throughput ve tek kod tabanından Cloudflare Workers, Deno, Bun, Node.js, AWS Lambda ve Vercel Edge üzerinde çalışabilme kapasitesiyle 2024-2026 döneminin en hızlı büyüyen backend framework"i oldu.

Bu rehberde Hono"nun mimarisini, router sistemini, middleware ekosistemini, RPC modunu ve gerçek production deployment senaryolarını ele alacağız.

Pro Tip: Hono"da en sık yapılan hata, middleware sırasını yanlış kurmak. app.use() çağrıları route tanımlarından önce gelmelidir; sonra tanımlanan middleware yalnızca sonraki route"lara uygulanır. Bu Node.js/Express davranışından farklıdır.

İçindekiler

  1. Neden Hono? Rekabet Avantajı
  2. Router Mimarisi: RegExpRouter, TrieRouter, SmartRouter
  3. Multi-Runtime Compatibility
  4. Middleware Ekosistemi
  5. JSX Renderer ve SSR
  6. RPC Mode ile Type-Safe Client
  7. Validator ve OpenAPI Entegrasyonu
  8. Test Stratejileri
  9. Production Deployment Patterns
  10. Fastify ve Express Karşılaştırması

1. Neden Hono? Rekabet Avantajı

Hono, Japonca"da "flame" (alev) anlamına gelir ve bu isim framework"ün performans felsefesini yansıtır. Yoshi Wada tarafından başlatılan projenin temel hedefi şuydu: Web Standards API (Request, Response, Headers) üzerinde çalışan, sıfır bağımlılıklı, her JavaScript runtime"ında koşan minimal bir framework.

Rakiplerle temel fark:

  • Fastify: Node.js-only, ~250KB bundle, güçlü ama edge"e taşınmaz
  • Express: 30 yaşında, Web Standards değil Node.js http modülü üstünde
  • Itty Router: çok minimal, middleware ekosistemi yok
  • Hono: Web Standards üstünde, multi-runtime, tam-featured

Cloudflare Workers ortamında Hono yaklaşık 150.000 req/sec throughput sağlar. Bu sayı, benzer özellikteki framework"lerin 3-5 katıdır. Bunun nedeni Hono"nun router algoritmalarının özellikle path matching için optimize edilmesi ve allocasyon sayısının minimize edilmesidir.


2. Router Mimarisi: RegExpRouter, TrieRouter, SmartRouter

Hono"nun performans sırrı büyük ölçüde router seçiminde yatıyor. Framework üç farklı router sunar:

RegExpRouter

Tüm route pattern"larını tek bir dev regex"e derler. Routing işlemi O(1) karmaşıklığındadır çünkü tüm pattern"lar tek seferde test edilir. Route sayısı arttıkça avantajı büyür.

typescript
1import { Hono } from 'hono';
2import { RegExpRouter } from 'hono/router/reg-exp-router';
3 
4// RegExpRouter açıkça belirtme (SmartRouter zaten seçer)
5const app = new Hono({ router: new RegExpRouter() });
6 
7app.get('/users/:id', (c) => {
8 const id = c.req.param('id');
9 return c.json({ userId: id });
10});
11 
12app.get('/posts/:slug/comments/:commentId', (c) => {
13 const { slug, commentId } = c.req.param();
14 return c.json({ slug, commentId });
15});
16 
17export default app;

TrieRouter

Trie (prefix tree) veri yapısını kullanır. Dinamik segment sayısı çok fazlaysa RegExpRouter"dan daha hızlı olabilir. Wildcard pattern"lar için tercih edilir.

SmartRouter (Varsayılan)

Hono 4.x"ten itibaren varsayılan router. Route"ları analiz ederek RegExpRouter veya TrieRouter arasında otomatik seçim yapar. Geliştiricinin router konusunda düşünmesine gerek kalmaz.

typescript
1// SmartRouter varsayılan — özel bir şey belirtmeye gerek yok
2const app = new Hono();
3 
4// Tüm route"lara erişim (debug için):
5// app.routes.forEach(r => console.log(r.method, r.path));

3. Multi-Runtime Compatibility

Hono"nun en stratejik özelliği, aynı kodun birden fazla runtime"da çalışmasıdır. Bu, Web Standards API"ye (Fetch API, Request, Response, Headers, URL, URLSearchParams) bağlı kalınarak sağlanır.

Desteklenen runtime"lar:

Runtime
Entry Point
Not
Cloudflare Workers
`export default app`
Wrangler ile deploy
Deno
`Deno.serve(app.fetch)`
Native HTTP
Bun
`Bun.serve({ fetch: app.fetch })`
Hızlı startup
Node.js
`serve(app)` (@hono/node-server)
Adapter gerekli
Vercel Edge
`export const GET = handle(app)`
Edge runtime
AWS Lambda
`handle(app)` (@hono/aws-lambda)
Adapter gerekli
Fastly Compute
`app.fire()`
WASM runtime
typescript
1// src/index.ts — runtime-agnostic core
2import { Hono } from 'hono';
3import { cors } from 'hono/cors';
4import { logger } from 'hono/logger';
5import { prettyJSON } from 'hono/pretty-json';
6 
7type Env = {
8 Variables: {
9 userId: string;
10 };
11 Bindings: {
12 DATABASE_URL: string;
13 JWT_SECRET: string;
14 };
15};
16 
17const app = new Hono();
18 
19app.use('*', logger());
20app.use('/api/*', cors({ origin: ['https://muhittincamdali.com'] }));
21app.use('/api/*', prettyJSON());
22 
23app.get('/api/health', (c) => {
24 return c.json({
25 status: 'ok',
26 runtime: c.env?.DATABASE_URL ? 'cf-workers' : 'local',
27 timestamp: new Date().toISOString(),
28 });
29});
30 
31export default app;
32 
33// Cloudflare Workers: bu dosya yeterli (export default app)
34// Deno: Deno.serve(app.fetch) ekle
35// Bun: Bun.serve({ fetch: app.fetch }) ekle
36// Node: import { serve } from "@hono/node-server"; serve(app);

4. Middleware Ekosistemi

Hono"nun built-in middleware"leri hono/ prefix"i altında gelir. Üçüncü taraf middleware"ler ise @hono/ scope"undadır.

Kritik built-in middleware"ler:

typescript
1import { Hono } from 'hono';
2import { cors } from 'hono/cors';
3import { compress } from 'hono/compress';
4import { cache } from 'hono/cache';
5import { bearerAuth } from 'hono/bearer-auth';
6import { rateLimiter } from 'hono/rate-limiter';
7import { secureHeaders } from 'hono/secure-headers';
8import { timing } from 'hono/timing';
9import { etag } from 'hono/etag';
10 
11const app = new Hono();
12 
13// Güvenlik header"ları (tüm route"lara)
14app.use('*', secureHeaders());
15 
16// Response timing (Server-Timing header)
17app.use('*', timing());
18 
19// Gzip/Brotli sıkıştırma
20app.use('/api/*', compress());
21 
22// ETag cache kontrolü
23app.use('/static/*', etag());
24 
25// CDN-level cache (Cloudflare Cache API)
26app.use(
27 '/api/public/*',
28 cache({
29 cacheName: 'hono-public-api',
30 cacheControl: 'public, max-age=3600',
31 })
32);
33 
34// CORS — fine-grained ayar
35app.use(
36 '/api/*',
37 cors({
38 origin: (origin) => {
39 const allowed = ['https://muhittincamdali.com', 'https://app.muhittincamdali.com'];
40 return allowed.includes(origin) ? origin : 'https://muhittincamdali.com';
41 },
42 allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
43 allowHeaders: ['Content-Type', 'Authorization'],
44 credentials: true,
45 maxAge: 86400,
46 })
47);
48 
49// Rate limiting (IP tabanlı)
50app.use(
51 '/api/auth/*',
52 rateLimiter({
53 windowMs: 15 * 60 * 1000, // 15 dakika
54 limit: 10,
55 keyGenerator: (c) => c.req.header('CF-Connecting-IP') ?? 'unknown',
56 handler: (c) => c.json({ error: 'Too many requests' }, 429),
57 })
58);
59 
60// Custom middleware — JWT verification
61app.use('/api/protected/*', async (c, next) => {
62 const token = c.req.header('Authorization')?.replace('Bearer ', '');
63 if (!token) return c.json({ error: 'Unauthorized' }, 401);
64 
65 try {
66 const { verify } = await import('hono/jwt');
67 const payload = await verify(token, c.env.JWT_SECRET);
68 c.set('userId', payload.sub as string);
69 await next();
70 } catch {
71 return c.json({ error: 'Invalid token' }, 401);
72 }
73});
74 
75export default app;

5. JSX Renderer ve SSR

Hono, built-in JSX renderer ile sunucu taraflı rendering yapabilir. React gerektirmez — Hono"nun kendi hono/jsx modülü TSX/JSX"i HTML"e çevirir.

typescript
1/** @jsxImportSource hono/jsx */
2import { Hono } from 'hono';
3import { jsxRenderer } from 'hono/jsx-renderer';
4 
5const app = new Hono();
6 
7// Layout renderer
8app.use(
9 '*',
10 jsxRenderer(({ children, title }) => {
11 return (
12
13
14
15
16 {title ?? 'Hono App'}
17
18
19
20
{children}
21
22
23 );
24 })
25);
26 
27// SSR page
28app.get('/blog/:slug', async (c) => {
29 const slug = c.req.param('slug');
30 const post = await fetchBlogPost(slug);
31 
32 if (!post) return c.notFound();
33 
34 return c.render(
35
36

{post.title}

37
38

{post.summary}

39
,
40 { title: post.title }
41 );
42});
43 
44// Streaming SSR
45app.get('/stream', (c) => {
46 return c.streamText(async (stream) => {
47 await stream.writeln('# Streaming Response');
48 await stream.sleep(100);
49 await stream.writeln('Data chunk 1...');
50 await stream.sleep(100);
51 await stream.writeln('Data chunk 2...');
52 });
53});
54 
55async function fetchBlogPost(slug: string) {
56 // KV veya D1 sorgusu
57 return slug ? { title: 'Test Post', publishedAt: new Date().toISOString(), summary: 'İçerik...' } : null;
58}
59 
60function formatDate(iso: string) {
61 return new Date(iso).toLocaleDateString('tr-TR', {
62 year: 'numeric', month: 'long', day: 'numeric',
63 });
64}
65 
66export default app;