Hono.js Derinlemesine: Her Yerde Çalışan Ultrafast Web Framework
Modern web geliştirme dünyası hızla parçalanıyor — artık sadece Node.js değil, Bun, Deno, Cloudflare Workers, Vercel Edge Functions ve daha birçok runtime ortamı var. Peki ya tek bir framework yazıp bunların hepsinde çalıştırabilseydiniz? İşte Hono.js tam olarak bunu vaat ediyor.
Hono (炎, Japonca'da "alev" anlamına gelir), Yusuke Wada tarafından geliştirilen, Web Standards API üzerine inşa edilmiş, ultra hızlı ve minimalist bir web framework'üdür. 2022'de Cloudflare Workers için başlayan yolculuğu, bugün tüm büyük JavaScript runtime'larını kapsayan devasa bir ekosisteme dönüştü.
Neden Hono.js?
Express.js yıllardır Node.js ekosisteminin kralı olsa da, modern gereksinimlere yanıt vermekte zorlanıyor. Hono.js'in öne çıkmasının birkaç kritik nedeni var:
1. Runtime Agnostik Mimari
Hono.js, Web Standard API (Request, Response, fetch) üzerine kurulmuştur. Bu, herhangi bir platforma özgü API'ye bağımlı olmadığı anlamına gelir. Aynı kodu aşağıdaki ortamlarda çalıştırabilirsiniz:
- Cloudflare Workers / Pages
- Deno / Deno Deploy
- Bun
- Node.js
- AWS Lambda
- Vercel Edge Functions
- Fastly Compute
- Netlify Edge Functions
2. Blazing Fast Performans
Hono.js, RegExpRouter ve TrieRouter gibi özel router implementasyonları sayesinde inanılmaz hızlıdır. Benchmark'larda Express.js'den 5-10 kat daha hızlı sonuçlar üretir. Özellikle RegExpRouter, tüm route'ları tek bir regular expression'a derleyerek O(1) benzeri bir eşleştirme performansı sağlar.
3. Sıfır Bağımlılık ve Küçük Bundle
Hono.js'in çekirdek paketi 14KB civarındadır (minified). Sıfır dış bağımlılığı vardır. Edge ortamlarında bundle boyutunun kritik olduğu düşünülürse, bu büyük bir avantajdır.
4. TypeScript-First Tasarım
Hono.js baştan sona TypeScript ile yazılmıştır ve mükemmel tip çıkarımı (type inference) sunar. Route parametreleri, middleware'ler ve response tipleri otomatik olarak çıkarılır.
Kurulum ve İlk Uygulama
Hono.js'i farklı runtime'lar için kurmak son derece basittir. Her runtime için ayrı bir adapter bulunur.
Bun ile Kurulum
bun create hono my-app
cd my-app
bun install
bun run devNode.js ile Kurulum
npm create hono@latest my-app
cd my-app
npm install
npm run devTemel Bir Hono Uygulaması
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => {
return c.text('Merhaba Dünya!')
})
app.get('/json', (c) => {
return c.json({ mesaj: 'Hono.js harika!', timestamp: Date.now() })
})
app.get('/html', (c) => {
return c.html('<h1>Hono.js ile HTML</h1>')
})
export default appDikkat edin: req ve res yerine tek bir Context (c) nesnesi kullanılıyor. Bu, Hono'nun temel tasarım kararlarından biridir ve API'yi çok daha temiz hale getirir.
Routing Sistemi
Hono.js'in routing sistemi hem güçlü hem de sezgiseldir. Express.js'e aşinaysanız, sözdizimi size çok tanıdık gelecektir.
Parametreli Route'lar
import { Hono } from 'hono'
const app = new Hono()
// Basit parametre
app.get('/users/:id', (c) => {
const id = c.req.param('id')
return c.json({ userId: id })
})
// Çoklu parametreler
app.get('/posts/:postId/comments/:commentId', (c) => {
const { postId, commentId } = c.req.param()
return c.json({ postId, commentId })
})
// Wildcard
app.get('/files/*', (c) => {
const path = c.req.path
return c.text(`Dosya yolu: ${path}`)
})Route Grupları
Büyük uygulamalarda route'ları gruplamak önemlidir. Hono.js bunu route() metodu ile çözer:
import { Hono } from 'hono'
const app = new Hono()
// Kullanıcı route'ları
const users = new Hono()
users.get('/', (c) => c.json({ users: [] }))
users.get('/:id', (c) => {
return c.json({ user: { id: c.req.param('id') } })
})
users.post('/', async (c) => {
const body = await c.req.json()
return c.json({ created: body }, 201)
})
// Ürün route'ları
const products = new Hono()
products.get('/', (c) => c.json({ products: [] }))
products.get('/:id', (c) => {
return c.json({ product: { id: c.req.param('id') } })
})
// Ana uygulamaya bağla
app.route('/api/users', users)
app.route('/api/products', products)
export default appMiddleware Ekosistemi
Hono.js'in en güçlü yanlarından biri zengin ve iyi tasarlanmış middleware ekosistemidir. Hem yerleşik (built-in) hem de üçüncü parti middleware'ler mevcuttur.
Yerleşik Middleware'ler
import { Hono } from 'hono'
import { cors } from 'hono/cors'
import { logger } from 'hono/logger'
import { prettyJSON } from 'hono/pretty-json'
import { secureHeaders } from 'hono/secure-headers'
import { basicAuth } from 'hono/basic-auth'
import { compress } from 'hono/compress'
import { etag } from 'hono/etag'
const app = new Hono()
// Global middleware'ler
app.use('*', logger())
app.use('*', cors())
app.use('*', secureHeaders())
app.use('*', prettyJSON())
app.use('*', compress())
app.use('*', etag())
// Belirli route'lara middleware
app.use('/admin/*', basicAuth({
username: 'admin',
password: 'super-secret',
}))
app.get('/', (c) => c.text('Anasayfa'))
app.get('/admin/dashboard', (c) => c.text('Admin Paneli'))
export default appÖzel Middleware Yazma
Kendi middleware'inizi yazmak son derece kolaydır:
import { Hono } from 'hono'
import { createMiddleware } from 'hono/factory'
// Basit bir zamanlama middleware'i
const timing = createMiddleware(async (c, next) => {
const start = Date.now()
await next()
const duration = Date.now() - start
c.header('X-Response-Time', `${duration}ms`)
console.log(`${c.req.method} ${c.req.path} - ${duration}ms`)
})
// JWT doğrulama middleware'i
const authMiddleware = createMiddleware(async (c, next) => {
const token = c.req.header('Authorization')?.replace('Bearer ', '')
if (!token) {
return c.json({ error: 'Token gerekli' }, 401)
}
try {
// Token doğrulama mantığı
const payload = verifyToken(token)
c.set('user', payload)
await next()
} catch {
return c.json({ error: 'Geçersiz token' }, 403)
}
})
const app = new Hono()
app.use('*', timing)
app.use('/api/*', authMiddleware)
app.get('/api/profile', (c) => {
const user = c.get('user')
return c.json({ user })
})
export default appValidator ve Zod Entegrasyonu
Hono.js, @hono/zod-validator paketi ile Zod şemalarını doğrudan route handler'larına entegre etmenizi sağlar. Bu, tam tip güvenliği ile request doğrulaması yapmanın en zarif yoludur.
import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
const app = new Hono()
// Request body şeması
const createUserSchema = z.object({
name: z.string().min(2).max(50),
email: z.string().email(),
age: z.number().int().min(18).max(120),
})
// Query parametreleri şeması
const listQuerySchema = z.object({
page: z.string().transform(Number).default('1'),
limit: z.string().transform(Number).default('10'),
search: z.string().optional(),
})
app.post(
'/users',
zValidator('json', createUserSchema),
async (c) => {
// body otomatik olarak tiplenmiştir!
const { name, email, age } = c.req.valid('json')
return c.json({
message: 'Kullanıcı oluşturuldu',
user: { name, email, age }
}, 201)
}
)
app.get(
'/users',
zValidator('query', listQuerySchema),
(c) => {
const { page, limit, search } = c.req.valid('query')
return c.json({ page, limit, search, users: [] })
}
)
export default appZod validasyonu başarısız olursa Hono otomatik olarak 400 status kodu ile detaylı hata mesajları döner.
JSX ile Server-Side Rendering
Hono.js'in en ilginç özelliklerinden biri, React'a ihtiyaç duymadan JSX desteği sunmasıdır. Bu, server-side rendering için hafif ve hızlı bir çözümdür:
/** @jsxImportSource hono/jsx */
import { Hono } from 'hono'
const app = new Hono()
const Layout = ({ children, title }: { children: any; title: string }) => (
<html lang="tr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{title}</title>
</head>
<body>
<header>
<nav>
<a href="/">Ana Sayfa</a>
<a href="/about">Hakkında</a>
</nav>
</header>
<main>{children}</main>
<footer>
<p>© 2024 Hono.js Blog</p>
</footer>
</body>
</html>
)
const ArticleCard = ({ title, excerpt }: { title: string; excerpt: string }) => (
<article>
<h2>{title}</h2>
<p>{excerpt}</p>
</article>
)
app.get('/', (c) => {
const articles = [
{ title: 'Hono.js Nedir?', excerpt: 'Ultra hızlı web framework...' },
{ title: 'Edge Computing', excerpt: 'Kullanıcıya en yakın noktada...' },
]
return c.html(
<Layout title="Blog">
<h1>Son Yazılar</h1>
{articles.map((a) => (
<ArticleCard title={a.title} excerpt={a.excerpt} />
))}
</Layout>
)
})
export default appFarklı Runtime'larda Çalıştırma
Hono.js'in aynı uygulama kodunu farklı runtime'larda çalıştırmak için sadece giriş dosyasını (entry point) değiştirmeniz yeterlidir.
Cloudflare Workers
// src/index.ts
import app from './app'
export default appNode.js
import { serve } from '@hono/node-server'
import app from './app'
serve({
fetch: app.fetch,
port: 3000,
})
console.log('Server http://localhost:3000 adresinde çalışıyor')Bun
import app from './app'
export default {
port: 3000,
fetch: app.fetch,
}Deno
import { Hono } from 'https://deno.land/x/hono/mod.ts'
import app from './app.ts'
Deno.serve({ port: 3000 }, app.fetch)AWS Lambda
import { handle } from 'hono/aws-lambda'
import app from './app'
export const handler = handle(app)Gördüğünüz gibi, uygulama mantığı (app) her yerde aynı kalır. Sadece sunucuya bağlama (binding) kısmı değişir.
RPC Özelliği: Tip Güvenli API İstemcisi
Hono.js'in en yenilikçi özelliklerinden biri hc (Hono Client) adlı RPC mekanizmasıdır. Backend'de tanımladığınız route'ların tiplerini frontend'de otomatik olarak kullanabilirsiniz — tıpkı tRPC gibi, ama çok daha hafif:
// server.ts
import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
const app = new Hono()
.get('/api/posts', (c) => {
return c.json({
posts: [
{ id: 1, title: 'İlk Yazı' },
{ id: 2, title: 'İkinci Yazı' },
]
})
})
.post(
'/api/posts',
zValidator('json', z.object({
title: z.string(),
content: z.string(),
})),
(c) => {
const body = c.req.valid('json')
return c.json({ id: 3, ...body }, 201)
}
)
export type AppType = typeof app
export default app// client.ts — Frontend tarafı
import { hc } from 'hono/client'
import type { AppType } from './server'
const client = hc<AppType>('http://localhost:3000')
// Tam tip güvenliği!
const res = await client.api.posts.$get()
const data = await res.json()
// data.posts -> { id: number; title: string }[]
// POST isteği — body tipi otomatik çıkarılır
const createRes = await client.api.posts.$post({
json: {
title: 'Yeni Yazı',
content: 'İçerik burada...',
}
})Bu özellik, full-stack TypeScript projelerinde API katmanı için ayrı tip tanımlaması yapmayı tamamen ortadan kaldırır.
Hono.js vs Express.js: Karşılaştırma
| Özellik | Hono.js | Express.js |
|---|---|---|
| Boyut | ~14KB | ~200KB+ |
| TypeScript | Native | @types gerekli |
| Runtime Desteği | Çoklu (Edge, Bun, Deno, Node) | Sadece Node.js |
| Performans | Çok yüksek | Orta |
| Web Standards | Evet (Request/Response) | Hayır (req/res) |
| Yerleşik Middleware | Zengin | Minimal |
| RPC/Client | Var (hc) | Yok |
| JSX Desteği | Var | Yok |
Gerçek Dünya Kullanım Senaryoları
Hono.js özellikle şu senaryolarda mükemmel bir seçimdir:
- Edge API'ler: Cloudflare Workers veya Vercel Edge Functions üzerinde düşük gecikme süreli API'ler
- Microservice'ler: Küçük boyutu ve hızı sayesinde container tabanlı mikro servisler
- Full-Stack Uygulamalar: JSX desteği ve RPC özelliği ile monorepo full-stack projeler
- API Gateway'ler: Middleware ekosistemi ile auth, rate limiting ve routing katmanı
- Serverless Functions: AWS Lambda, Vercel ve Netlify Functions üzerinde minimum cold start
Sonuç
Hono.js, modern JavaScript ekosistemindeki parçalanmayı bir avantaja dönüştüren nadir framework'lerden biridir. "Write once, run anywhere" vaadini Web Standards API sayesinde gerçekten yerine getirir.
Express.js'in basitliğini, Fastify'ın performansını ve tRPC'nin tip güvenliğini tek bir pakette birleştiren Hono.js, 2024 ve sonrasında API geliştirme için güçlü bir adaydır. Özellikle Edge computing'in yükselişiyle birlikte, runtime agnostik bir framework kullanmak artık bir lüks değil, bir gerekliliktir.
Eğer yeni bir proje başlıyorsanız veya mevcut Express.js uygulamanızı modernize etmek istiyorsanız, Hono.js'i kesinlikle değerlendirmenizi öneririm. Küçük boyutu, sıfır bağımlılığı ve mükemmel TypeScript desteği ile sizi şaşırtacaktır.
🔥 Hono.js resmi dokümantasyonu: hono.dev