Hono 2025 - エッジで輝く超軽量Webフレームワーク

2026.01.12

Honoとは - 日本発のエッジネイティブフレームワーク

Hono(炎)は、Web標準をベースに構築された超軽量・高速なWebフレームワークです。2021年に和田裕介氏によって開発が始まり、2025年現在ではGitHubで28,000以上のスターを獲得し、66,000以上のプロジェクトで採用されています。

flowchart TB
    subgraph Hono["Hono Framework"]
        Core["Core<br/>12KB未満"]
        Router["RegExpRouter<br/>超高速ルーティング"]
        Middleware["ミドルウェア<br/>豊富なエコシステム"]
    end

    subgraph Runtimes["対応ランタイム"]
        CF["Cloudflare Workers"]
        Deno["Deno"]
        Bun["Bun"]
        Node["Node.js"]
        AWS["AWS Lambda"]
        Fastly["Fastly Compute"]
    end

    Core --> Runtimes
    Router --> Core
    Middleware --> Core

Honoの最大の特徴は、同じコードがあらゆるJavaScriptランタイムで動作するという点です。Cloudflare Workers、Deno、Bun、Node.js、AWS Lambda、Fastly Computeなど、18以上のプラットフォームで一切のコード変更なく実行できます。

Honoの核心的特徴

1. 驚異的な軽量性

Honoのhono/tinyプリセットは12KB未満という驚異的な軽さを実現しています。これはExpressの約1/40、Fastifyの約1/20のサイズです。

// hono/tiny を使用した最小構成
import { Hono } from 'hono/tiny'

const app = new Hono()

app.get('/', (c) => c.text('Hello Hono!'))

export default app

この軽量性は、エッジコンピューティングにおいて決定的な優位性をもたらします。コールドスタートが最小化され、ユーザーへのレスポンスが高速化されます。

2. Web標準への準拠

HonoはWeb標準API(Fetch API、Request、Response、URL、Headers等)のみを使用しており、特定のランタイムに依存しません。

import { Hono } from 'hono'

const app = new Hono()

// Web標準のRequest/Responseを直接操作
app.get('/api/user', async (c) => {
  const url = new URL(c.req.url)
  const userId = url.searchParams.get('id')

  // Fetch APIで外部サービスを呼び出し
  const response = await fetch(`https://api.example.com/users/${userId}`)
  const user = await response.json()

  return c.json(user)
})

// Headersの操作
app.get('/api/secure', (c) => {
  const authHeader = c.req.header('Authorization')

  if (!authHeader) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  return c.json({ message: 'Authenticated' })
})

export default app

3. 完璧なTypeScriptサポート

Honoは99%以上がTypeScriptで書かれており、型推論が非常に強力です。

import { Hono } from 'hono'
import { z } from 'zod'
import { zValidator } from '@hono/zod-validator'

// スキーマ定義
const userSchema = z.object({
  name: z.string().min(1).max(100),
  email: z.string().email(),
  age: z.number().int().min(0).max(150),
})

type User = z.infer<typeof userSchema>

// 型安全なアプリケーション
const app = new Hono()

// リクエストボディの型が自動推論される
app.post(
  '/users',
  zValidator('json', userSchema),
  async (c) => {
    const user = c.req.valid('json') // User型として推論

    // user.name, user.email, user.age が型安全にアクセス可能
    console.log(`Creating user: ${user.name}`)

    return c.json({ id: 1, ...user }, 201)
  }
)

// パスパラメータの型定義
app.get('/users/:id', (c) => {
  const id = c.req.param('id') // string型
  return c.json({ id })
})

export default app

対応プラットフォーム

Honoは2025年現在、以下の18以上のプラットフォームで動作します。

flowchart LR
    subgraph Edge["エッジプラットフォーム"]
        CF["Cloudflare Workers"]
        Fastly["Fastly Compute"]
        Vercel["Vercel Edge"]
        Netlify["Netlify Edge"]
    end

    subgraph Serverless["サーバーレス"]
        Lambda["AWS Lambda"]
        LambdaEdge["Lambda@Edge"]
        GCR["Google Cloud Run"]
        Azure["Azure Functions"]
    end

    subgraph Runtime["ランタイム"]
        Node["Node.js"]
        Deno["Deno"]
        Bun["Bun"]
    end

    subgraph Special["特殊環境"]
        SW["Service Workers"]
        WASM["WebAssembly"]
    end

    Hono["Hono"] --> Edge
    Hono --> Serverless
    Hono --> Runtime
    Hono --> Special

各プラットフォームでの起動例

Cloudflare Workers

// src/index.ts
import { Hono } from 'hono'

const app = new Hono()

app.get('/', (c) => c.text('Hello Cloudflare Workers!'))

// Cloudflare WorkersのBindingsを型安全に扱う
type Bindings = {
  KV_NAMESPACE: KVNamespace
  DB: D1Database
}

const appWithBindings = new Hono<{ Bindings: Bindings }>()

appWithBindings.get('/kv/:key', async (c) => {
  const key = c.req.param('key')
  const value = await c.env.KV_NAMESPACE.get(key)
  return c.json({ key, value })
})

export default app

Deno

// main.ts
import { Hono } from 'npm:hono'
import { serve } from 'https://deno.land/std@0.220.0/http/server.ts'

const app = new Hono()

app.get('/', (c) => c.text('Hello Deno!'))

// Deno.serveで起動
Deno.serve(app.fetch)

Bun

// index.ts
import { Hono } from 'hono'

const app = new Hono()

app.get('/', (c) => c.text('Hello Bun!'))

// Bunのサーバーとして起動
export default {
  port: 3000,
  fetch: app.fetch,
}

Node.js

// index.ts
import { Hono } from 'hono'
import { serve } from '@hono/node-server'

const app = new Hono()

app.get('/', (c) => c.text('Hello Node.js!'))

serve({
  fetch: app.fetch,
  port: 3000,
})

console.log('Server running on http://localhost:3000')

ミドルウェアエコシステム

Honoは豊富な組み込みミドルウェアと、サードパーティミドルウェアを提供しています。

組み込みミドルウェア

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 { compress } from 'hono/compress'
import { cache } from 'hono/cache'
import { timing } from 'hono/timing'
import { jwt } from 'hono/jwt'
import { basicAuth } from 'hono/basic-auth'
import { bearerAuth } from 'hono/bearer-auth'
import { csrf } from 'hono/csrf'
import { etag } from 'hono/etag'

const app = new Hono()

// ロギング
app.use('*', logger())

// セキュリティヘッダー
app.use('*', secureHeaders())

// CORS設定
app.use('/api/*', cors({
  origin: ['https://example.com', 'https://app.example.com'],
  allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowHeaders: ['Content-Type', 'Authorization'],
  exposeHeaders: ['X-Request-Id'],
  maxAge: 86400,
  credentials: true,
}))

// レスポンス圧縮
app.use('*', compress())

// JSONの整形表示
app.use('*', prettyJSON())

// キャッシュ制御
app.use('/static/*', cache({
  cacheName: 'my-app-cache',
  cacheControl: 'max-age=3600',
}))

// CSRF保護
app.use('/form/*', csrf())

// タイミング計測
app.use('*', timing())

// JWT認証
app.use('/api/protected/*', jwt({
  secret: 'your-secret-key',
}))

// Basic認証
app.use('/admin/*', basicAuth({
  username: 'admin',
  password: 'secret',
}))

export default app

カスタムミドルウェアの作成

import { Hono, MiddlewareHandler } from 'hono'

// リクエストIDミドルウェア
const requestId: MiddlewareHandler = async (c, next) => {
  const id = crypto.randomUUID()
  c.set('requestId', id)
  c.header('X-Request-Id', id)
  await next()
}

// レート制限ミドルウェア
const rateLimit = (limit: number, window: number): MiddlewareHandler => {
  const requests = new Map<string, { count: number; resetTime: number }>()

  return async (c, next) => {
    const ip = c.req.header('CF-Connecting-IP') || 'unknown'
    const now = Date.now()
    const record = requests.get(ip)

    if (record && now < record.resetTime) {
      if (record.count >= limit) {
        return c.json({ error: 'Rate limit exceeded' }, 429)
      }
      record.count++
    } else {
      requests.set(ip, { count: 1, resetTime: now + window })
    }

    await next()
  }
}

// エラーハンドリングミドルウェア
const errorHandler: MiddlewareHandler = async (c, next) => {
  try {
    await next()
  } catch (err) {
    console.error(`Error: ${err}`)
    return c.json({
      error: 'Internal Server Error',
      requestId: c.get('requestId'),
    }, 500)
  }
}

const app = new Hono()

app.use('*', requestId)
app.use('*', errorHandler)
app.use('/api/*', rateLimit(100, 60000)) // 1分間に100リクエストまで

app.get('/api/data', (c) => {
  return c.json({ message: 'Success', requestId: c.get('requestId') })
})

export default app

Express/Fastifyとの比較

パフォーマンス比較

2025年のベンチマークテスト(req/sec、数値が高いほど高速):

フレームワークCloudflare WorkersNode.jsBun
Hono380,000145,000295,000
Fastify-78,000180,000
Express-15,00045,000

サイズ比較

フレームワークパッケージサイズ依存関係数
Hono (tiny)12KB0
Hono (full)24KB0
Fastify250KB15+
Express500KB30+

機能比較

// Express スタイル
import express from 'express'
const expressApp = express()

expressApp.get('/users/:id', (req, res) => {
  const id = req.params.id
  res.json({ id })
})

// Hono スタイル(よりモダンで型安全)
import { Hono } from 'hono'
const honoApp = new Hono()

honoApp.get('/users/:id', (c) => {
  const id = c.req.param('id')
  return c.json({ id })
})

主要な違い

特徴HonoExpressFastify
TypeScript対応ネイティブ追加型定義が必要良好
エッジ対応完全対応非対応部分対応
マルチランタイム18+Node.jsのみNode.jsのみ
Web標準準拠完全独自API部分的
コールドスタート極小

実践的なAPI構築例

REST APIの構築

import { Hono } from 'hono'
import { z } from 'zod'
import { zValidator } from '@hono/zod-validator'

// 型定義
interface Todo {
  id: number
  title: string
  completed: boolean
  createdAt: string
}

// インメモリストア(実際はDBを使用)
const todos: Todo[] = []
let nextId = 1

// スキーマ定義
const createTodoSchema = z.object({
  title: z.string().min(1).max(200),
})

const updateTodoSchema = z.object({
  title: z.string().min(1).max(200).optional(),
  completed: z.boolean().optional(),
})

// アプリケーション
const app = new Hono()

// 一覧取得
app.get('/todos', (c) => {
  const completed = c.req.query('completed')

  let result = todos
  if (completed !== undefined) {
    result = todos.filter((t) => t.completed === (completed === 'true'))
  }

  return c.json({
    todos: result,
    total: result.length,
  })
})

// 詳細取得
app.get('/todos/:id', (c) => {
  const id = parseInt(c.req.param('id'))
  const todo = todos.find((t) => t.id === id)

  if (!todo) {
    return c.json({ error: 'Todo not found' }, 404)
  }

  return c.json(todo)
})

// 作成
app.post(
  '/todos',
  zValidator('json', createTodoSchema),
  (c) => {
    const { title } = c.req.valid('json')

    const todo: Todo = {
      id: nextId++,
      title,
      completed: false,
      createdAt: new Date().toISOString(),
    }

    todos.push(todo)
    return c.json(todo, 201)
  }
)

// 更新
app.patch(
  '/todos/:id',
  zValidator('json', updateTodoSchema),
  (c) => {
    const id = parseInt(c.req.param('id'))
    const updates = c.req.valid('json')

    const index = todos.findIndex((t) => t.id === id)
    if (index === -1) {
      return c.json({ error: 'Todo not found' }, 404)
    }

    todos[index] = { ...todos[index], ...updates }
    return c.json(todos[index])
  }
)

// 削除
app.delete('/todos/:id', (c) => {
  const id = parseInt(c.req.param('id'))
  const index = todos.findIndex((t) => t.id === id)

  if (index === -1) {
    return c.json({ error: 'Todo not found' }, 404)
  }

  const deleted = todos.splice(index, 1)[0]
  return c.json(deleted)
})

export default app

RPCスタイルAPI(hono/rpc)

import { Hono } from 'hono'
import { hc } from 'hono/client'
import { z } from 'zod'
import { zValidator } from '@hono/zod-validator'

// サーバー側
const app = new Hono()
  .get('/users', (c) => {
    return c.json([
      { id: 1, name: 'Alice' },
      { id: 2, name: 'Bob' },
    ])
  })
  .post(
    '/users',
    zValidator('json', z.object({ name: z.string() })),
    (c) => {
      const { name } = c.req.valid('json')
      return c.json({ id: 3, name }, 201)
    }
  )
  .get('/users/:id', (c) => {
    const id = c.req.param('id')
    return c.json({ id: parseInt(id), name: 'User' })
  })

// 型をエクスポート
export type AppType = typeof app

// クライアント側(完全な型安全性)
const client = hc<AppType>('http://localhost:3000')

// 型安全なAPI呼び出し
async function example() {
  // GET /users - レスポンスの型が自動推論
  const users = await client.users.$get()
  const usersData = await users.json() // { id: number; name: string }[]

  // POST /users - リクエストボディも型チェック
  const newUser = await client.users.$post({
    json: { name: 'Charlie' },
  })
  const newUserData = await newUser.json() // { id: number; name: string }

  // GET /users/:id - パスパラメータも型安全
  const user = await client.users[':id'].$get({
    param: { id: '1' },
  })
  const userData = await user.json() // { id: number; name: string }
}

2025年の採用状況

主要な採用企業・プロジェクト

2025年現在、Honoは多くの企業やプロジェクトで採用されています:

  • Cloudflare: 公式ドキュメントでHonoを推奨フレームワークとして紹介
  • Vercel: Edge Functionsの推奨フレームワークの一つ
  • Shopify: エッジでのAPI処理に採用
  • 多数のスタートアップ: 高速なAPIバックエンドとして採用増加

GitHubの統計(2025年1月)

  • スター数: 28,200+
  • 利用プロジェクト数: 66,800+
  • コントリビューター: 285人
  • 最新バージョン: v4.11.3

エコシステムの成長

flowchart TB
    subgraph Core["Hono Core"]
        Framework["hono"]
    end

    subgraph Official["公式パッケージ"]
        NodeServer["@hono/node-server"]
        ZodValidator["@hono/zod-validator"]
        GraphQL["@hono/graphql-server"]
        Swagger["@hono/swagger-ui"]
        TRPC["@hono/trpc-server"]
    end

    subgraph Community["コミュニティ"]
        Auth["認証ライブラリ"]
        ORM["ORM統合"]
        Testing["テストユーティリティ"]
    end

    Core --> Official
    Core --> Community

まとめ - なぜHonoを選ぶべきか

2025年、Honoはエッジコンピューティング時代における最適なWebフレームワークとして確固たる地位を築いています。

Honoを選ぶべき理由

  1. パフォーマンス: 12KB未満の軽量性と超高速ルーティング
  2. 移植性: 18以上のランタイムで同一コードが動作
  3. 開発体験: 完璧なTypeScriptサポートと直感的なAPI
  4. エコシステム: 豊富なミドルウェアとツール群
  5. 将来性: Web標準への準拠による長期的な安定性

始め方

# プロジェクト作成
npm create hono@latest my-app

# ディレクトリ移動
cd my-app

# 依存関係インストール
npm install

# 開発サーバー起動
npm run dev

Honoは「小さく始めて、大きくスケール」という現代のWeb開発の理想を体現しています。エッジコンピューティング、サーバーレス、マイクロサービスなど、あらゆるユースケースに対応できる柔軟性を持ちながら、シンプルさを失わない設計思想は、多くの開発者に支持される理由となっています。

参考リンク

この技術を体系的に学びたいですか?

未来学では東証プライム上場企業のITエンジニアが24時間サポート。月額24,800円から、退会金0円のオンラインIT塾です。

LINEで無料相談する
← 一覧に戻る