この記事は HowTelevision Advent Calendar 2025 18日目の記事です。25日まで連続投稿します。
https://qiita.com/advent-calendar/2025/howtv
ソフトウェアエンジニアの根本です。 今回は、Hono + Drizzle ORMを使ったバックエンド開発の技術選定のチャレンジについて紹介します。モダンなTypeScriptバックエンド開発において、この組み合わせがいかに強力かを実際の開発経験を交えて解説していきます。
技術スタックの概要
Hono は、Cloudflare Workers、Deno、Bun、Node.js、AWS Lambdaなど、あらゆるJavaScriptランタイム上で動作する、超軽量かつ高速なWebフレームワークです。Web標準(Web Standards)に準拠しているため、プラットフォームにロックインされない柔軟性を持っています。一方、Drizzle ORM は「TypeScript-first」を掲げる次世代のORMであり、TypeScriptの型安全性を最大限に保ちつつ、SQL本来の書き味を損なわない操作感が特徴です。
選定理由
TypeScript
言語として TypeScript を選定した最大の理由は、チームメンバーの既存の技術スタックとの親和性が非常に高いためです。フロントエンドですでにTypeScriptが浸透している環境であれば、バックエンドにも同じ言語を採用することで、コンテキストスイッチのコストを下げ、チーム全体でのコードレビューやナレッジ共有がスムーズに行えるという大きなメリットがあります。
Hono
Honoを採用する最大の理由は、Hono RPCによるフロントエンドとの連携です。
- バックエンドで定義した型定義をクライアント(React/Next.jsなど)と共有する「RPCモード」が強力です
- APIクライアントを自動生成することなく、
client.api.users.$get()のように、完全に型がついた状態でバックエンドを呼び出せます - OpenAPIなどのスキーマ定義ファイルを別途管理する必要がなく、TypeScriptコードがそのまま真実の情報源(Single Source of Truth)となります
Drizzle ORM
Drizzle ORMの選定理由は、以下の2点に集約されます。
1. 「SQLを知っていれば書ける」直感的な構文
- TypeORMやPrismaのような独自のクエリ言語(DSL)による厚い抽象化を避け、SQLに近い書き心地を提供します
- これにより、複雑なクエリが必要になった際もSQLの知識がそのまま活かせ、ブラックボックス化を防げます
- 例:
db.select().from(users).where(eq(users.id, 1)) - JOINやサブクエリなど、高度なSQL操作も直感的に記述できます
2. スキーマ定義がSingle Source of Truth
- TypeScriptのファイルでデータベースのスキーマを定義します。SQLファイルではなく、TypeScriptコードとしてテーブル定義を記述するため、エディタの支援をフルに受けられます。
- これがそのままマイグレーションの元となり、かつ型定義としても機能します
- DBスキーマとTypeScriptの型が常に同期されるため、開発効率が劇的に向上します。カラム追加などの変更があった際、関連する型定義も自動的に更新されるため、修正漏れを防げます
- スキーマ変更時も型エラーとして即座に検知できるため、安全性が高まります
ハマったポイント・注意点
一方で、導入時にいくつか躓きやすい点もありました。これから導入される方のために、ハマったポイントや注意点を説明します。
1. Hono RPCのバージョンの一致
- フロントエンドとバックエンドでHonoのバージョンを統一する必要があります
- バージョンが異なると、型定義の不整合が発生する可能性があります
- モノレポ構成の場合は、ワークスペースの依存関係を適切に設定しましょう。 ルートの依存関係として一元管理するなどして、常に同一バージョンが参照されるように工夫が必要です
2. Hono特有のコードの書き方
Honoの機能を最大限利用するためには、Hono流の書き方に倣う必要があります。
まず、route定義はメソッドチェーンで繋げないと、Hono ClientのRPCが使用できない。
また、入力データの型推論は、zValidatorを使って入力検証を行い、パス定義の直後にハンドラーを記述しないと利用できない。
3. Drizzle マイグレーションのコンフリクト
Drizzle ORMの仕様上、マイグレーションファイルは以前の履歴に依存して生成されます。そのため、以下のようなケースで問題が多発していました。
- 並行開発時の不整合: 複数の開発者がそれぞれのブランチでDBスキーマ変更を行うと、生成されるマイグレーションファイルの整合性が取れなくなる。
- マージ時の競合: GitHub等のリポジトリでマージする際、マイグレーション履歴の順序や内容が衝突し、手動での解決が必要になる頻度が高かった。
そこで、ローカルではdrizzleディレクトリをgitignoreし、リモートでマイグレーションファイルを自動生成してコミットするようにしました。
参考記事: https://zenn.dev/toridori/articles/7ea35472f8a30c
まとめ
この技術スタックを採用することで、開発効率と保守性が大幅に向上しました。特にHono RPCによる型共有は、フロントエンドとバックエンドの連携を劇的に改善してくれます。
We're Hiring!
今回ご紹介した取り組みに共感いただけるエンジニアの方がいらっしゃいましたら、ぜひ私たちのチームにジョインしませんか?
弊社では、一緒に技術的な課題に取り組んでくれるエンジニアを募集中です!
現在募集中の採用情報の詳細は下記をご覧ください。
開発チームの最新情報はXでも発信しています。ぜひフォローをお願いします!