✍️ 필사 모드: TypeScript ORM・クエリビルダー 2026 — Drizzle・Kysely・Prisma・postgres.js 徹底比較(SQL にどれだけ近づけるか)(日本語)
日本語プロローグ — 「Prisma か raw SQL か」の時代は終わった
2026 年でも、新規 TypeScript プロジェクトのキックオフで必ず出る質問がある。
「DB アクセス、何使う?」
2022 年なら答えはだいたい二つ。Prisma(一番有名、フル ORM)か raw pg/mysql2(SQL は自分で書く、型は自分の問題)。間に TypeORM や Sequelize がいたが、TypeScript との相性とマイグレーション体験のせいで、新規プロジェクトからは徐々に消えていった。
2026 年は違う。二つの新しい強者が定着した。
- Drizzle ORM — 「SQL に最も近い」ヘッドレス ORM。スキーマは TS コードで宣言し、クエリは SQL の一行一行に 1:1 で対応する。バンドルが小さくエッジランタイムに強い。2026 年 5 月時点で GitHub スター 31k+、週次 npm ダウンロード 2M+。
- Kysely — 「スキーマレスな純粋クエリビルダー」。任意の DB クライアント(
pg・mysql2・better-sqlite3)を受け取り、型安全なビルダーで包む。マイグレーションとスキーマ管理は自分でやる。GitHub スター 12k+。
ここに Prisma が新カードを二枚追加。
- Prisma エンジン書き直し — Prisma 6 以降、従来の Rust 製クエリエンジンが TypeScript ネイティブ + Go ベースの軽量エンジンの組み合わせに段階的に置き換わった。コールドスタート遅延が減り、エッジランタイム互換性が正常化し、バンドルサイズも有意に小さくなった。
- Prisma Postgres — Prisma 社が直接運営するマネージド Postgres。unikernel ベアメタル上に分離コンピュート・ストレージで構成。free tier が思いのほか手厚く、cold start が速い。
そして全員を揺さぶる別の波。
- postgres.js・pg・mysql2 を直接使う — タグ付きテンプレートリテラルと TypeScript の satisfies・
as constを上手く使えば、ORM なしでも十分型安全という流れ。「クエリビルダー自体が過剰抽象」派。
この記事は 2026 年 5 月時点でこれらを直接比較する。抽象度・マイグレーション・エッジ・バンドル・エスケープハッチ・マルチ DB の 6 軸。そして同じクエリを四つのツールで並べる。
1 章 · 風景 — ツール地図
まず分類する。すべてが同じ位置にあるわけではない。
| 分類 | ツール | 一行要約 |
|---|---|---|
| フル ORM(Active Record・Data Mapper) | Prisma・MikroORM・TypeORM・Sequelize | モデル・関係・フェッチ・キャッシュまで面倒を見る |
| ヘッドレス ORM | Drizzle | スキーマはコード、クエリは SQL に 1:1 |
| クエリビルダー | Kysely・Knex | スキーマなしで型安全な SQL 合成 |
| Raw クライアント + 型ヘルパ | postgres.js・pg・mysql2 + Zod | タグ付きテンプレート、ランタイム検証 |
| リレーショナル DSL | EdgeQL(EdgeDB)・SurrealQL | DB が独自クエリ言語を持つ |
この記事の焦点は太字 4 グループの代表 — Prisma・Drizzle・Kysely・postgres.js。MikroORM・TypeORM は最後の章で短く扱う。
なぜこの 4 つか
- Prisma — 最も有名で、新規フルスタックプロジェクトの既定値に近い。2026 年の新エンジンと Postgres サービスを合わせれば、再び 1 軍。
- Drizzle — 2024~2026 で最も速く伸びたツール。Vercel 公式ガイド、Hono・Cloudflare Workers 推奨スタック、T3 stack の既定選択肢の一つ。
- Kysely — Prisma を抜けたチームが最初に出会うツール。マイグレーション体験談に頻出。
- postgres.js — Porsager が作った速くて小さい Postgres クライアント。Bun・Cloudflare Workers と相性が良い。ORM なし陣営の事実上の標準。
2 章 · 抽象度のスペクトラム — どこまで隠すか
データアクセスライブラリは「DB とコードの間にどのくらい厚い層を置くか」の選択だ。左ほど SQL に近く、右ほどオブジェクトに近い。
SQL オブジェクト
| |
postgres.js -- Kysely -- Drizzle -- Prisma -- MikroORM/TypeORM
(raw) (ビルダー) (ヘッドレス ORM) (フル ORM) (Active Record)
抽象度が厚いほど良いか?断じて違う。トレードオフだ。
- 薄い側の利点: SQL そのままの表現力、性能チューニングの直進性、学習とデバッグが結局 SQL 一つに収束。
- 厚い側の利点: 記述速度、ドメインオブジェクトとの直接対応、関係と N+1 の自動処理、IDE 補完の豊富さ。
- 薄い側の欠点: 関係フェッチを自分で書く必要、ドメイン写像は別作業。
- 厚い側の欠点: 抽象が足りない場面(window function・CTE・複雑な join)でエスケープハッチが不自然、バンドル・コールドスタート・ランタイム互換にコスト。
2026 年の空気は 「SQL に近く、しかし型は安全に」 に寄っている。Drizzle・Kysely・postgres.js の成長がその証拠。ただし Prisma 6 のエンジン書き直しで厚い側も軽くなり、「ORM だから重い」論はもう古い。
3 章 · Drizzle — 「TypeScript で書く SQL」
Drizzle は 2026 年の新規プロジェクトで最もよく選ばれる DB ツールの一つ。コア哲学は 3 つ。
- スキーマは TS コード —
schema.tsでテーブル・カラム・関係を宣言する。真実の源は DB ではなく TS ファイル。 - クエリは SQL に 1:1 —
db.select().from(users).where(eq(users.email, '...'))のような形。SQL を知っている人なら、何にコンパイルされるかが一目でわかる。 - ヘッドレスで小さい — ランタイム依存がほぼゼロ。Cloudflare Workers・Vercel Edge・Deno Deploy にそのまま乗る。圧縮 7~15KB 程度。
Drizzle のスキーマ
// db/schema.ts
import { pgTable, serial, text, timestamp, integer } from 'drizzle-orm/pg-core'
export const users = pgTable('users', {
id: serial('id').primaryKey(),
email: text('email').notNull().unique(),
name: text('name').notNull(),
createdAt: timestamp('created_at').defaultNow().notNull(),
})
export const posts = pgTable('posts', {
id: serial('id').primaryKey(),
authorId: integer('author_id').notNull().references(() => users.id),
title: text('title').notNull(),
body: text('body').notNull(),
})
Drizzle Kit でマイグレーション
# drizzle.config.ts を書いた後
npx drizzle-kit generate # スキーマ変更から SQL マイグレーション生成
npx drizzle-kit migrate # 実 DB に適用
npx drizzle-kit studio # ローカル GUI
Drizzle の強み
- SQL エスケープハッチが自然 —
sqlタグで任意の SQL を差し込み、その部分だけ型を手で定義できる。 - エッジ互換性 — すべてのアダプタ(
drizzle-orm/postgres-js、drizzle-orm/neon-http、drizzle-orm/d1)がエッジランタイムで動く。 - 複数 DB 対応 — PostgreSQL・MySQL・SQLite・D1・LibSQL・Neon・Planetscale・Vercel Postgres・Bun SQLite。乗り換えコストが小さい。
Drizzle の弱み
- 関係クエリ(Drizzle Relations API)は発展途上 — 関係で nested クエリを書くとき、まだ Prisma ほどなめらかではない。ただし 2025 年の v2 リリースでほぼ追いついた。
- マイグレーション衝突は手動 — 共同作業時にマイグレーションファイルが衝突すると手でマージが必要。
- 学習曲線 — SQL を知らないと Prisma ほど親切ではない。
4 章 · Kysely — 「スキーマレスな純粋クエリビルダー」
Kysely は別の道。スキーマを強制しない。DB スキーマは自分の責任(SQL ファイル・Atlas・Sqitch・Liquibase など何でも)で、Kysely はその上に型安全なクエリビルダーだけを提供する。
// db/types.ts — DB スキーマに対応する TS 型
import type { ColumnType, Generated } from 'kysely'
export interface Database {
user: UserTable
post: PostTable
}
export interface UserTable {
id: Generated<number>
email: string
name: string
created_at: ColumnType<Date, string | undefined, never>
}
export interface PostTable {
id: Generated<number>
author_id: number
title: string
body: string
}
Kysely の核は、上の Database インターフェースをジェネリックで受け取り、すべてのクエリでカラム名と型を自動推論することだ。
kysely-codegen で型を自動生成
スキーマインターフェースを手で書きたくないなら kysely-codegen を使う。ライブ DB をイントロスペクトして上のような TS 型を生成する。
npx kysely-codegen --url postgres://user:pw@localhost/db --out-file db/types.ts
Kysely の強み
- SQL そのままの表現力 — window function・CTE・
json_agg・UNION ALLなど、SQL のほぼ全てを 1:1 で書ける。 - DB とマイグレーションの分離 — マイグレーションツールは別に選ぶ。Atlas・Sqitch・dbmate・Flyway など何でも。
- 小さなバンドル — コアビルダーは圧縮約 14KB。
- 最小限のランタイム依存 — Cloudflare Workers・Bun・Deno で問題なく動く。
Kysely の弱み
- スキーマと型の一貫性は自分の責任 — マイグレーション後に
kysely-codegenを回さないと型が嘘をつく。CI に組み込むかマイグレーション後フックで自動化する必要あり。 - 関係フェッチは明示的 — N+1・
JOIN・json_aggパターンを自分で書く。Prisma や Drizzle ほど短くならない。 - エコシステムが小さい — プラグイン・チュートリアル・サードパーティ統合が他より少ない。
5 章 · Prisma — 新エンジンと Prisma Postgres
Prisma は 2024~2025 で大きな変化が二つあった。
5.1 エンジン書き直し — Rust から TS ネイティブ + Go へ
Prisma 5 時代のクエリエンジンは Rust 製の別プロセス(または WASM)。コールドスタートが遅く、エッジランタイムで不自然だった。Prisma 6 以降の段階的書き直しで次が変わった。
- TypeScript ネイティブクライアント — クエリコンパイラの多くが TS に移植された。クライアント内で SQL を直接生成する。
- Go ベースの軽量エンジン — Prisma Accelerate・Pulse のようなマネージドサービス側で動く。
- バンドル縮小 — クライアントサイズが有意に減った。具体的な数値は setup によるので、Prisma 公式ベンチマークとリリースノートを参照。
- エッジ互換性の正常化 — Vercel Edge・Cloudflare Workers で直接動くアダプタが安定化。
5.2 TypedSQL — Prisma の中で raw SQL を型安全に
Prisma の弱点は常に「複雑な SQL を書けない」だった。TypedSQL はその弱点を真正面から叩く。
-- prisma/sql/findActiveUsers.sql
SELECT id, email, name
FROM "User"
WHERE last_seen_at > $1
ORDER BY last_seen_at DESC
LIMIT $2;
import { PrismaClient } from '@prisma/client'
import { findActiveUsers } from '@prisma/client/sql'
const prisma = new PrismaClient()
const since = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)
const users = await prisma.$queryRawTyped(findActiveUsers(since, 50))
// users: SQL パラメータから推論された行の配列
.sql ファイルはビルド時に検査され、パラメータと結果の型が自動生成される。SQL は SQL のまま、型安全は保つ。
5.3 Prisma Postgres — マネージドサービス
Prisma 社が直接運営する Postgres。差別化は 3 点。
- コンピュート・ストレージ分離 — Neon と似たアーキテクチャだが unikernel ベース。
- コールドスタートが速い — サーバーレスワークロードに優しい。
- Prisma ツールチェインと密結合 —
prisma initで DB 作成・スキーマ push・クライアント生成まで一気に。
マネージド Postgres 市場は既に Neon・Supabase・PlanetScale Postgres・Vercel Postgres があり競争は激しいが、Prisma ユーザーには最も親和性の高い選択肢になった。
Prisma の強み(2026)
- 圧倒的に親切な学習曲線・ドキュメント・チュートリアル。
- 関係・フェッチ・トランザクション API が最もなめらか。
- TypedSQL でエスケープハッチが正常化。
- エッジ・バンドルの弱点が大幅に縮小。
Prisma の弱み(2026)
- 依然として抽象が一番厚い — デバッグ時に頭の中で一度 SQL に変換するモデルが必要。
- マイグレーションツール(
prisma migrate)は強いが、migrate dev のシャドウ DB 要件が、権限制限のあるホスティング環境で煩わしい場合がある。 - ライセンスと運用コスト — Accelerate・Pulse のマネージドサービスがあり、無料枠を超えると有料。セルフホストにするとその分作業が増える。
6 章 · postgres.js・pg・mysql2 — ORM なしで行く
最も薄い道。タグ付きテンプレートと TypeScript の推論・satisfies だけで十分という陣営。
// db/index.ts
import postgres from 'postgres'
export const sql = postgres(process.env.DATABASE_URL!, {
max: 10,
idle_timeout: 20,
})
// クエリ — タグ付きテンプレート
type User = { id: number; email: string; name: string }
const users = await sql<User[]>`
SELECT id, email, name
FROM users
WHERE email = ${'foo@example.com'}
LIMIT 10
`
// users: User[]
postgres.js はパラメータバインドによる SQL インジェクション防止と、prepared statement のキャッシュを自前で行う。型は手で宣言するか、kysely-codegen 等で生成するか、Zod でランタイム検証する。
Zod でランタイム検証
import { z } from 'zod'
const UserRow = z.object({
id: z.number(),
email: z.string().email(),
name: z.string(),
})
const rows = await sql<unknown[]>`SELECT id, email, name FROM users LIMIT 10`
const users = rows.map((r) => UserRow.parse(r))
// users: z.infer<typeof UserRow>[]
このパターンの利点は DB が実際に返したものを一度検証すること。ORM やビルダーの型はコンパイル時の約束に過ぎず、実 DB が約束を破った(NULL カラム・型ドリフト)かを捕まえはしない。
Raw クライアントの強み
- 最も小さく最も速い — 追加抽象がゼロ。
- SQL のほぼ全てが使える — Postgres の全機能をそのまま。
- エッジ互換性が最高 — postgres.js も
pgも Cloudflare Workers・Bun でよく動く。Neon HTTP アダプタはさらに綺麗。 - 学習対象が SQL のみ。
Raw クライアントの弱み
- 型安全は自分の責任。
- 関係クエリを自分で書く。
- マイグレーションツールも自分で選ぶ。
7 章 · 同じクエリを四つのツールで — 「email でユーザを引く」
最もシンプルな例。email でユーザを 1 件引き、最新ポスト 5 件を一緒に返す。
7.1 Drizzle
import { db } from './db'
import { users, posts } from './db/schema'
import { eq, desc } from 'drizzle-orm'
async function findUserWithPosts(email: string) {
const user = await db.query.users.findFirst({
where: eq(users.email, email),
with: {
posts: {
orderBy: [desc(posts.id)],
limit: 5,
},
},
})
return user
// user: ユーザ行と posts: ポスト行の配列、または undefined
}
db.query.users.findFirst は Drizzle Relations API。内部では json_agg か LATERAL join を伴う 1 本の SQL になる。
7.2 Kysely
import { db } from './db'
import { jsonArrayFrom } from 'kysely/helpers/postgres'
async function findUserWithPosts(email: string) {
const user = await db
.selectFrom('user')
.where('email', '=', email)
.select((eb) => [
'id',
'email',
'name',
jsonArrayFrom(
eb
.selectFrom('post')
.whereRef('post.author_id', '=', 'user.id')
.orderBy('post.id', 'desc')
.limit(5)
.select(['post.id', 'post.title', 'post.body'])
).as('posts'),
])
.executeTakeFirst()
return user
}
Kysely はサブセレクトヘルパで nested JSON を組む。jsonArrayFrom は Postgres json_agg に直接コンパイルされる。SQL が頭の中で正確に描ける。
7.3 Prisma
import { prisma } from './db'
async function findUserWithPosts(email: string) {
const user = await prisma.user.findUnique({
where: { email },
include: {
posts: {
orderBy: { id: 'desc' },
take: 5,
},
},
})
return user
}
最も読みやすい。Prisma は効率的なクエリを内部で選ぶ(以前は N+1 懸念があったが、新エンジンでは join strategy を明示的に選べる)。
7.4 postgres.js(raw)
import { sql } from './db'
type UserRow = {
id: number
email: string
name: string
posts: Array<{ id: number; title: string; body: string }>
}
async function findUserWithPosts(email: string) {
const rows = await sql<UserRow[]>`
SELECT
u.id, u.email, u.name,
COALESCE(
json_agg(json_build_object('id', p.id, 'title', p.title, 'body', p.body))
FILTER (WHERE p.id IS NOT NULL),
'[]'::json
) AS posts
FROM users u
LEFT JOIN LATERAL (
SELECT id, title, body
FROM posts
WHERE author_id = u.id
ORDER BY id DESC
LIMIT 5
) p ON TRUE
WHERE u.email = ${email}
GROUP BY u.id
`
return rows[0]
}
長いが、何が走るかが正確にわかる。COALESCE(json_agg(...) FILTER (WHERE ...)) のようなイディオムは raw なら毎回手で書く(ヘルパに切り出せば短くなる)。
比較 — 同じクエリ、違う抽象度
| ツール | 行数 | 読みやすさ | SQL 可視性 | 型推論 |
|---|---|---|---|---|
| Drizzle | 短い | 易しい | 中 | 自動 |
| Kysely | 中 | 中 | 高い | 自動 |
| Prisma | 最も短い | 最も易しい | 低い | 自動 |
| postgres.js | 最も長い | SQL 依存 | 最も高い | 手動 / Zod |
8 章 · 6 軸比較 — 素早く選ぶために
8.1 抽象度
| ツール | 抽象度 |
|---|---|
| postgres.js | ほぼなし |
| Kysely | SQL ビルダー |
| Drizzle | スキーマ + SQL ビルダー |
| Prisma | フル ORM |
| MikroORM・TypeORM | Active Record・Data Mapper |
8.2 マイグレーション
| ツール | ビルトインマイグレーション | 自動生成 | 備考 |
|---|---|---|---|
| Prisma | prisma migrate | あり | シャドウ DB が必要 |
| Drizzle | drizzle-kit | あり | 保守的な自動生成 |
| Kysely | Kysely マイグレーション + 外部ツール | なし | Atlas・dbmate 推奨 |
| postgres.js | なし | なし | Atlas・Sqitch・Flyway 等 |
8.3 エッジランタイム互換性(Cloudflare Workers・Vercel Edge・Bun)
| ツール | エッジ互換 | 備考 |
|---|---|---|
| Drizzle | 非常に良い | すべてのアダプタがエッジファースト |
| Kysely | 良い | ドライバ依存、概ね問題なし |
| postgres.js | 良い | Neon HTTP・Hyperdrive 併用で非常に良い |
| Prisma | 良い | 新エンジン以降安定 |
| MikroORM・TypeORM | 普通~制限あり | デコレータ・reflect-metadata 依存 |
8.4 バンドルサイズ(圧縮、クライアントコアのみ)
おおよその感覚(リリースで変動)。
| ツール | 圧縮後サイズ(概算) |
|---|---|
| postgres.js | 非常に小さい |
| Kysely | 小さい |
| Drizzle | 小さい |
| Prisma | 中(新エンジン以降大幅に縮小) |
| MikroORM・TypeORM | 大きい |
8.5 SQL エスケープハッチ
| ツール | エスケープハッチ | なめらかさ |
|---|---|---|
| postgres.js | 自分で SQL | 最高 |
| Kysely | sql タグ | 非常に良い |
| Drizzle | sql タグ | 非常に良い |
| Prisma | TypedSQL・$queryRaw | 良い(TypedSQL 以降正常) |
| MikroORM・TypeORM | raw query | 普通 |
8.6 マルチ DB 対応
| ツール | Postgres | MySQL | SQLite | その他 |
|---|---|---|---|---|
| Drizzle | あり | あり | あり | D1・LibSQL・Bun・Neon・Planetscale 他 |
| Kysely | あり | あり | あり | アダプタ多数 |
| Prisma | あり | あり | あり | SQL Server・MongoDB(限定的) |
| postgres.js | あり | なし | なし | Postgres 専用 |
9 章 · 実マイグレーション体験談 — Prisma → Drizzle / Kysely
9.1 Prisma → Drizzle(最も多いパス)
この経路を選ぶチームが増えた。理由は二つ。
- エッジとバンドル — コールドスタートとレスポンスタイムに差が見える。新 Prisma エンジンで差は縮んだがゼロではない。
- SQL エスケープハッチ —
sqlタグが Prisma の TypedSQL より自然。TypedSQL は別.sqlファイルが必要で、動的 SQL に制約がある。
典型的なマイグレーション手順。
- ステップ 1: 新コードのみ Drizzle で。既存 Prisma コードはそのまま。
- ステップ 2:
drizzle-kitで既存 DB をイントロスペクト → スキーマコード生成。 - ステップ 3: read 経路から段階的に置換。write・トランザクションは後で。
- ステップ 4: マイグレーションツールを差し替え(
prisma migrate→drizzle-kit)。
うまくいかない部分
- Prisma マイグレーションの履歴は Drizzle Kit から見えない — 共存期間中、衝突しないよう手で管理する必要あり。
- enum・複合 PK・partial index のような縁 — Drizzle introspection が 100% 捕えない場合あり。手動補正が必要。
- 関係クエリの意味の微妙な違い — Prisma
includeと Drizzlewithは同じに見えても LATERAL join 戦略が違えば、結果 JSON 形・並び順が微妙にずれることがある。
9.2 Prisma → Kysely(SQL 派チームの経路)
DB スキーマ運用を既に Atlas・Sqitch 等で行うチーム、または SQL を直接書きたいが型は欲しいチームがよく選ぶ。
- ステップ 1:
kysely-codegenでライブ DB から型を生成。 - ステップ 2: 最も複雑なクエリ(window・CTE・
json_agg)から置換 — 価値が最大のところから先に取る。 - ステップ 3: マイグレーションは Atlas・dbmate 等に分離(既にそうしているチームも多い)。
- ステップ 4: 単純な read も徐々に移行。write・トランザクションは最後。
うまくいかない部分
- 関係クエリが長くなる — Prisma の 1 行が Kysely では 5~15 行に。ヘルパ関数を作る作業が必要。
Selectable<DB["user"]>のようなユーティリティ型の理解コスト — 初見の人には少し不慣れ。- エコシステムが小さい — プラグイン・例・サードパーティ統合が Prisma ほど豊富ではない。
10 章 · MikroORM・TypeORM — まだ生きているが
MikroORM
エンティティクラスベースの Data Mapper ORM。identity map・unit of work・豊富な関係 API が強み。DDD スタイルのプロジェクトやドメインオブジェクト中心に書くチームが好む。SQL からは最も遠い。
- 強み: ドメインオブジェクト中心、Active Record / Data Mapper の両対応、トランザクションと関係がなめらか。
- 弱み: 重い、デコレータと
reflect-metadata依存、エッジ親和度は普通。
TypeORM
最古参の TS ORM の一つ。デコレータベース Active Record + Data Mapper。メンテナンスが安定せず既知のバグが長く残る傾向があり、新規プロジェクトの第一選択ではない。ただし既に TypeORM で書かれたコードを持っているなら、すぐに剥がせない。
- 強み: 馴染み、豊富なデコレータ API。
- 弱み: メンテリスク、TS 5.x の変化やデコレータ標準変更への追従が遅い、エッジ互換が難しい。
新規プロジェクトで自発的に TypeORM を選ぶケースは 2026 年では稀。既存コードベースは別途コスト・利益分析が必要。
11 章 · 何を、いつ選ぶか — 率直な結論
正解は?いつもの通り 「状況による」。ただしパターンはある。
Drizzle を選ぶとき
- 新規プロジェクトで、エッジランタイム(Cloudflare Workers・Vercel Edge)優先。
- SQL を知っている、または学ぼうとするチーム。
- マルチ DB(SQLite・Postgres・MySQL・D1・LibSQL)の可能性。
- バンドルサイズとコールドスタートが重要。
Kysely を選ぶとき
- マイグレーションを既に Atlas・Sqitch・dbmate 等で運用中。
- 複雑な SQL(CTE・window・
json_agg)が多く、SQL を直接書きたい。 - スキーマ管理と DDL を ORM から切り離したい。
- 小さな依存と小さなバンドルが欲しい。
Prisma を選ぶとき
- 新規フルスタックチーム、学習曲線最小化が最優先。
- 関係が複雑で、
includeとフェッチのなめらかさが重要。 - Prisma Postgres・Accelerate・Pulse のマネージドツールチェインを活用したい。
- TypedSQL で複雑な SQL を別途扱うことに抵抗がない。
postgres.js・pg(raw)を選ぶとき
- チーム全体が SQL に強い。
- 追加抽象を意識的に拒否。
- 最小のバンドルと最速のランタイムが核心要件。
- ランタイム検証(Zod)や codegen で型を別途管理可能。
アンチチェックリスト(避けるべきパターン)
- 一つのプロジェクトに ORM 二つ — 学習とデバッグのコストが倍。
- 「Prisma が遅いから Drizzle に乗り換えた」を測定せずに決める — 新エンジン以降は当てはまらないことが多い。
- ORM を選んでおいてほぼ全クエリを
$queryRawで書く — それは ORM ではなく重い raw クライアント。 - スキーマは Drizzle、マイグレーションは Prisma のような奇妙な組み合わせ — 真実の源が二つ。
- エッジファースト環境でデコレータ ORM を採用 — ビルド・バンドル・ランタイムすべてが茨。
エピローグ — 抽象は道具であって宗教ではない
ORM・クエリビルダー選びは 抽象度とエスケープハッチのなめらかさのトレードオフだ。どちらが優越という話ではない。ただし 2026 年 5 月の風景は明確だ。
- SQL に近い側が伸びた — Drizzle・Kysely・raw 陣営が育った。
- フル ORM はダイエット中 — Prisma 新エンジンと TypedSQL が弱点二つを正面から叩いた。
- エッジが既定値になった — どのツールを選んでもエッジ互換性を無視できない。
- 「一つのツールが全てを解決」は壊れた — DB クライアント + マイグレーションツール + 型生成ツールを別々に組むのが普通になった。
決定チェックリスト
- エッジファースト? — はいなら Drizzle・Kysely・postgres.js・新 Prisma。
- チームが SQL に強い? — はいなら Kysely・postgres.js、いいえなら Prisma・Drizzle。
- 関係フェッチが中心? — はいなら Prisma 大なり Drizzle Relations 大なり Kysely。
- 複雑な SQL(CTE・window)が多い? — はいなら Kysely・postgres.js 大なり Drizzle 大なり Prisma TypedSQL。
- マイグレーションツールは? — Prisma・Drizzle Kit のビルトイン、または Atlas・dbmate の外部。
- マルチ DB の可能性は? — はいなら Drizzle・Kysely。
- 学習曲線最小化? — Prisma。
アンチパターン
- 測定せず ORM 乗り換え — 数値の後で決める。
- 一つのコードベースに ORM 二つを並存 — 行き先を決めてマイグレーション日程を組む。
- ORM 使いながら
$queryRawが 9 割 — それは重い raw クライアント。 - スキーマの真実の源が二つ — DB とコードの真実は一つ。
- マイグレーション自動化なしで codegen — 型が嘘をつく。
- エッジファースト環境で重いデコレータ ORM — ビルドとランタイム両方にコスト。
- 関係が複雑なのに raw — 手で書く SQL が山積み。
次回予告
候補: Drizzle Relations v2 を深く — json_agg・LATERAL join がどう生成されるか、Prisma TypedSQL を一ヶ月使ってみた — 何に使い何に使わないか、Cloudflare Workers + Hyperdrive + postgres.js のフルスタック事例。
「SQL を知ればすべてのツールは親切になる。知らなければどのツールも魔法ではない。」
— TypeScript ORM・クエリビルダー 2026、終わり。
参考 / References
- Drizzle ORM 公式
- Drizzle ORM GitHub
- Drizzle Kit ドキュメント
- Drizzle Relations API
- Kysely 公式
- Kysely GitHub
- kysely-codegen
- Prisma 公式
- Prisma TypedSQL ドキュメント
- Prisma Postgres
- Prisma エンジン書き直し — 公式ブログ
- postgres.js GitHub — porsager/postgres
- node-postgres (pg) 公式
- mysql2 GitHub
- MikroORM 公式
- TypeORM 公式
- Neon — サーバーレス Postgres
- Cloudflare Hyperdrive
- Cloudflare D1
- Atlas — モダン DB マイグレーション
- Vercel Postgres
- Zod
- Hono — エッジ Web フレームワーク
- T3 Stack
현재 단락 (1/380)
2026 年でも、新規 TypeScript プロジェクトのキックオフで必ず出る質問がある。