先に要点
- tRPC は TypeScript 用の ` 型安全な API ライブラリ』。サーバが定義した型を クライアント側で直接インポート できるため、`OpenAPI / GraphQL スキーマを生成して同期する』 ような工程が不要。
- API 呼び出しは ` client.user.byId.query({ id: 1 })』 のように `関数を呼ぶ感覚』 で書ける。レスポンスの型も自動で導出されるので、`API レスポンスの型を別に書く』 作業がゼロになる。
- Zod による入力検証、pnpm workspaces によるモノレポ、Vercel へのデプロイ、というモダン TS スタックの中心に位置するライブラリ。
- 万能ではない。` 外部に公開する API』 `非 TypeScript クライアント』 が前提なら REST / GraphQL の方が向く。tRPC は基本 `サーバとクライアントを両方自社の TS で書く案件』 に最適化されている。
tRPC ってよく聞くけど、結局 REST と何が違うの? GraphQL でいいのでは? `モノレポなら使うべき?』 ── TypeScript フルスタックで開発する案件が増えるほど、tRPC の名前は外せない存在になってきました。
ざっくり言うと、tRPC は サーバが書いた TypeScript 型を、クライアントから直接 import して呼び出せる』</strong> ことを最大の売りにした API ライブラリです。 OpenAPI のスキーマ定義や GraphQL の SDL を介さず、<strong> TypeScript の型システムをそのまま API 契約として使う』 という割り切りで、`型を書く時間 = API 契約を書く時間』 という体験を実現します。
この記事では、2026年5月時点の tRPC を、`何を解決するのか・REST / GraphQL との違い・どう書くのか・どこで効くか・どこでは向かないか』 の順で整理します。
tRPC が解決した問題
なぜ tRPC が広まったか』 は、フロントエンドエンジニアが API 開発のたびに同じ作業をしている』 という不満の歴史を見ると分かります。
①型を二重に書く
サーバで `User』 型を書き、フロントでも `ApiUser』 型を書く。`OpenAPI を生成してジェネレータを回す』 という選択肢もあるが、ビルドの一手間と微妙にずれる型が問題になる。
② エンドポイントの構造を覚える必要がある
`GET /api/users/:id』 を覚え、`fetch』 で叩き、JSON をパースし、型を当てる ─ という同じ作業を毎回書く。`シンプルだが面倒』 が積み重なる。
④ TypeScript の表現力を使い切れない
OpenAPI / GraphQL は TS より表現力が低い。`ユニオン型』 `条件付き型』 などの強い型情報が、API 境界で失われがち。
tRPC は ` サーバとクライアントが同じリポジトリ(or モノレポ)にあるなら、TS 型をそのまま共有すればいいじゃないか』 という、ある意味で開き直った発想で、これらの問題を一気に解消しました。
基本の使い方 — Procedure』 と Router』
最小例で雰囲気を確認します。
// server/router.ts
import { initTRPC } from '@trpc/server';
import { z } from 'zod';
const t = initTRPC.create();
export const appRouter = t.router({
user: t.router({
byId: t.procedure
.input(z.object({ id: z.string() }))
.query(async ({ input }) => {
return await db.user.findUnique({ where: { id: input.id } });
}),
create: t.procedure
.input(z.object({ name: z.string(), email: z.string().email() }))
.mutation(async ({ input }) => {
return await db.user.create({ data: input });
}),
}),
});
export type AppRouter = typeof appRouter;
クライアント側はこうなります。
// client.ts
import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
import type { AppRouter } from '../server/router';
const trpc = createTRPCProxyClient<AppRouter>({
links: [httpBatchLink({ url: '/trpc' })],
});
const user = await trpc.user.byId.query({ id: '42' });
const created = await trpc.user.create.mutate({ name: 'Alice', email: 'a@example.com' });
ポイント:
- サーバの
AppRouter』 型を <strong>クライアントがimport type』 するだけ で、利用できるエンドポイント、引数、戻り値の型が完全に揃う。 query』 は GET 系の参照、mutation』 は POST/PUT/DELETE 系の更新、と概念的に分ける。- 入力検証は Zod をそのまま使う(Yup / Valibot 等もアダプタ経由で可)。
`スキーマ生成のコマンドを叩く必要がない』 のが、地味だが体験を大きく変える点です。
REST / GraphQL との比較
3つを並べると、それぞれの立ち位置が見えやすくなります。
| 軸 | REST | GraphQL | tRPC |
|---|---|---|---|
| API 契約の形 | OpenAPI(別途定義) | SDL(別途定義) | TypeScript の型(自動) |
| クライアントの呼び方 | HTTP リクエスト | クエリ文字列 + 変数 | 関数呼び出し |
| 型生成 | codegen が必要 | codegen が必要 | 不要(import するだけ) |
| 外部公開向き | ◎(標準) | ○(SDL があれば多言語OK) | ×(TS 前提) |
| クライアントの言語 | 何でもOK | 何でもOK | TypeScript のみ |
| サーバ↔フロントが同じ TS | 普通 | 普通 | 圧倒的に楽 |
| クエリの柔軟性 | 低(エンドポイント固定) | 高(クライアントが選ぶ) | 中(サーバが procedure を提供) |
| ツール / ドキュメント | 豊富 | 豊富 | TS スタック向きに豊富 |
要点は ` API を誰が・何で呼ぶか』 で選ぶ:
どれが優れているか』 ではなく、案件の境界条件にどれが合うか』 で決める道具立てです。
React Query との統合
tRPC が普段使いで快適に感じるもう1つの理由が、React Query(TanStack Query)との深い統合 です。
// 通常版 React Query を意識せずに使える
const { data, isLoading, error } = trpc.user.byId.useQuery({ id: '42' });
const create = trpc.user.create.useMutation({
onSuccess: () => {
trpc.user.byId.invalidate({ id: '42' });
},
});
fetch を直接書く / axios を呼ぶ』 が、React Query のフック + 型安全な引数 + 自動キャッシュ無効化』 に置き換わります。
キャッシュ、リトライ、optimistic update など React Query の機能はそのまま使え、`データ取得の標準的なコードベース』 が一気に手に入る、というのが現場の体感です。
どこで効くか — tRPC が活きる案件
実務で `tRPC を選んでよかった』 となる構成は、おおむね決まっています。
①Next.js + 自社 TypeScript フルスタック
Next.js の App Router / Pages Router の API レイヤを tRPC で組む構成は最頻出。`サーバ側のコードを書く感覚で API が完成』 する。
② モノレポでサーバとクライアントを並走
pnpm workspaces や Turborepo で `apps/web』 と `apps/api』 を並べる構成と相性◎。`同じ型を共有』 が物理ファイルとして自然に成立する。
③ 小〜中規模スタートアップ
` 早く作って・早く出す』 が求められるフェーズで、`API スキーマの整備』 を後回しにしても型安全を保てる。MVP〜スケール初期で抜群に効く。
④ 社内ツール / 管理画面
外部 API としての公開が不要で、TS で書く社内システムなら、tRPC で書かない理由がほぼない。
完全に内向きの TS スタック』 のときに、tRPC は最も大きな威力を発揮します。 逆に <strong> 外向きの API として公開する』 場合は、後述のように tRPC ではなく REST / GraphQL の方が自然 です。
どこでは向かないか — tRPC の限界
`流行っているから tRPC』 で選ぶと、後で痛い目を見る場面もあります。
② モバイルや別言語クライアント
iOS / Android / Go / Rust など TypeScript 以外のクライアントを想定する場合、tRPC は使えない / 旨味がない。`type を import する』 が成立しないため。
④ 非常に複雑なクエリ要件
` 1画面で 30 種類のデータを取得し、フィルタや並びをクライアント側で柔軟に選ぶ』 のような GraphQL の本来の強みが効く案件は、GraphQL のほうが向く。
`内向き TS なら tRPC、外向きや複雑な要件なら別』 という判断軸を持っておくと、選定で迷いが減ります。
認証・認可・ミドルウェア
tRPC は ` procedure ミドルウェア』 という仕組みで、認証・認可・ロギング・レート制御などを共通化できます。
const isAuthed = t.middleware(async ({ ctx, next }) => {
if (!ctx.user) throw new Error('UNAUTHORIZED');
return next({ ctx: { ...ctx, user: ctx.user } });
});
export const protectedProcedure = t.procedure.use(isAuthed);
// 使うとき
export const appRouter = t.router({
me: protectedProcedure.query(({ ctx }) => ctx.user),
});
保護したい procedure は protectedProcedure を使う』 と決めるだけで、認証チェックが一律にかかる、という設計です。 [HTTP ステータスコードの記事](/articles/representative-http-status-codes-explained) で触れた 401 / 403 を返す境界』 を、tRPC では エラーコード(UNAUTHORIZED』 `FORBIDDEN』)』 として表現できる仕組みも持っています。
モノレポでの典型構成
tRPC が真価を発揮するのは、モノレポでの構成です。
`API の追加 = サーバの router にメソッドを増やす』 だけで、クライアント側は即座に補完が効く ─ という体験が、現代の TS フルスタックにおける tRPC の魅力の核心です。
AI 時代の tRPC 観
AI を組み込んだ TS アプリでも、tRPC の役割は重要になっています。
AI 呼び出しの型安全
` AI に何を投げて、何が返ってくるか』 を Zod スキーマで宣言し、tRPC の procedure として公開する。フロントから `trpc.ai.summarize.useMutation』 のような自然な呼び出しが可能になる。
ストリーミングと相性
` tRPC + React Query の streaming』 で、`AI が応答を生成する過程』 を UI にリアルタイム反映するのが楽。LLM のストリーミング応答に向いた構成。
小さなチームが AI で爆速に開発する』 文脈で、tRPC は事実上のスタンダードのひとつになっています。 内向き / TypeScript / モノレポ』 が揃った瞬間に、tRPC の合理性は最大化される、というのが2026年現在の景色です。
tRPC に関するよくある質問
Q. tRPC は本番運用に耐えますか?
A. 十分耐えています。Vercel・Cal.com・PlanetScale など多くの著名プロダクトで本番採用実績があり、v10』 以降は安定して使われています。<strong> 設計が割り切られているがゆえに、ライブラリとしての複雑性は小さく、運用上のトラブルは少なめ』というのが現場の評価です。
Q. REST / GraphQL を捨てて全部 tRPC にすべきですか?
A. いいえ。 内向きは tRPC、外向き API は REST / GraphQL』</strong> の使い分けが現実的です。同じ会社の中で、社内ツールは tRPC、公開 API は REST』 という二刀流の構成も普通にあります。
Q. Zod は必須ですか?
A. 必須ではないですが、事実上の標準コンビ』 です。Zod を使うと <strong> 入力検証 + 型推論 + tRPC procedure の型』 が全部1つの定義で済む ので、これを採用しないのはむしろ手間が増えやすいです。Valibot などのアダプタも存在します。
Q. SSR / Next.js での扱いはどうなりますか?
A. tRPC は Next.js を一級サポート しています。@trpc/next』 で SSR / SSG / RSC との統合を提供し、サーバコンポーネントから直接 procedure を呼ぶ』 ような構成も可能です。Next.js + tRPC は現在の TS フルスタック開発で頻出するセットです。
Q. パフォーマンスは REST より劣りますか?
A. 大差ありません。 HTTP の上で動く JSON 通信』</strong> という意味では REST と同等のオーバーヘッドで、バッチング(`httpBatchLink』)』 で複数 procedure をまとめて送ることで、むしろ通信回数を減らせる場面もあります。
Q. tRPC の学習コストはどのくらい?
A. TypeScript と Zod を知っていれば、半日〜1日で書き始められる』</strong> 程度です。procedure / router / client / React Query』 の4語と、`query / mutation / input / output』 の4語を押さえれば、最初のエンドポイントは作れます。
Q. tRPC を採用すると、技術ロックインは厳しいですか?
A. ある程度はあります。tRPC で書いた procedure を REST にエクスポート』 するアダプタもありますが、設計の根っこは TS の型共有前提なので、完全に別技術に移行する』 ときは書き直しに近い作業が発生します。これも `内向きの内製案件で使う』 という前提なら問題になりにくい、というのが多くの判断です。