trpc
trpcに関する深い知識を持ち、スキーマやコード生成なしで型安全なAPIを構築し、サーバーとクライアント間で型推論をフル活用したTypeScriptアプリケーション開発を支援するSkill。
📜 元の英語説明(参考)
You are an expert in tRPC, the framework for building type-safe APIs without schemas or code generation. You help developers create full-stack TypeScript applications where the server defines procedures and the client calls them with full type inference — no REST routes, no GraphQL schemas, no OpenAPI specs, just TypeScript functions that are type-safe from database to UI.
🇯🇵 日本人クリエイター向け解説
trpcに関する深い知識を持ち、スキーマやコード生成なしで型安全なAPIを構築し、サーバーとクライアント間で型推論をフル活用したTypeScriptアプリケーション開発を支援するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o trpc.zip https://jpskill.com/download/15497.zip && unzip -o trpc.zip && rm trpc.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/15497.zip -OutFile "$d\trpc.zip"; Expand-Archive "$d\trpc.zip" -DestinationPath $d -Force; ri "$d\trpc.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
trpc.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
trpcフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
tRPC — エンドツーエンドのタイプセーフなAPI
あなたはtRPCのエキスパートです。tRPCは、スキーマやコード生成なしにタイプセーフなAPIを構築するためのフレームワークです。サーバーがプロシージャを定義し、クライアントが完全な型推論でそれらを呼び出すフルスタックTypeScriptアプリケーションを開発者が作成するのを支援します。RESTルートも、GraphQLスキーマも、OpenAPIスペックも必要ありません。データベースからUIまでタイプセーフなTypeScript関数だけです。
主要な機能
サーバー
// server/trpc.ts — tRPCの設定
import { initTRPC, TRPCError } from "@trpc/server";
import { z } from "zod";
const t = initTRPC.context<Context>().create();
export const router = t.router;
export const publicProcedure = t.procedure;
export const protectedProcedure = t.procedure.use(async ({ ctx, next }) => {
if (!ctx.session?.user) throw new TRPCError({ code: "UNAUTHORIZED" });
return next({ ctx: { user: ctx.session.user } });
});
// server/routers/users.ts
export const usersRouter = router({
getById: publicProcedure
.input(z.object({ id: z.string() }))
.query(async ({ input, ctx }) => {
const user = await ctx.db.users.findUnique({ where: { id: input.id } });
if (!user) throw new TRPCError({ code: "NOT_FOUND", message: "User not found" });
return user;
}),
list: publicProcedure
.input(z.object({
cursor: z.string().optional(),
limit: z.number().min(1).max(100).default(20),
}))
.query(async ({ input, ctx }) => {
const items = await ctx.db.users.findMany({
take: input.limit + 1,
cursor: input.cursor ? { id: input.cursor } : undefined,
orderBy: { createdAt: "desc" },
});
const hasMore = items.length > input.limit;
return { items: items.slice(0, input.limit), nextCursor: hasMore ? items[input.limit].id : undefined };
}),
update: protectedProcedure
.input(z.object({ name: z.string().min(1), bio: z.string().max(500).optional() }))
.mutation(async ({ input, ctx }) => {
return ctx.db.users.update({ where: { id: ctx.user.id }, data: input });
}),
});
// server/routers/_app.ts
export const appRouter = router({
users: usersRouter,
posts: postsRouter,
});
export type AppRouter = typeof appRouter;
Reactクライアント
import { trpc } from "@/utils/trpc";
function UserProfile({ userId }: { userId: string }) {
// 完全な型推論 — ホバーするとサーバーからの戻り値の型が表示されます
const { data: user, isLoading } = trpc.users.getById.useQuery({ id: userId });
const updateUser = trpc.users.update.useMutation({
onSuccess: () => utils.users.getById.invalidate({ id: userId }),
});
const utils = trpc.useUtils();
if (isLoading) return <Spinner />;
return (
<div>
<h1>{user?.name}</h1> {/* userはUser | undefinedとして型付けされます */}
<button onClick={() => updateUser.mutate({ name: "New Name" })}>
{updateUser.isPending ? "Saving..." : "Update"}
</button>
</div>
);
}
// 無限スクロール
function UserList() {
const { data, fetchNextPage, hasNextPage } = trpc.users.list.useInfiniteQuery(
{ limit: 20 },
{ getNextPageParam: (lastPage) => lastPage.nextCursor },
);
return (
<>
{data?.pages.flatMap(p => p.items).map(user => <UserCard key={user.id} user={user} />)}
{hasNextPage && <button onClick={() => fetchNextPage()}>Load More</button>}
</>
);
}
インストール
npm install @trpc/server @trpc/client @trpc/react-query @tanstack/react-query zod
ベストプラクティス
- コード生成ゼロ — 型はTypeScriptの推論を介してサーバーからクライアントに流れます。ビルドステップは不要です。
- Zodバリデーション — ランタイムバリデーションには
.input(z.object(...))を使用します。コンパイル時とランタイムでタイプセーフです。 - React Queryの裏側 —
useQuery、useMutation、useInfiniteQueryはすべて動作します。完全なキャッシュ機能があります。 - プロシージャの型 — 読み取りには
query、書き込みにはmutation、WebSocketストリームにはsubscriptionを使用します。 - ミドルウェア — 認証、ロギング、レート制限のためにミドルウェアをチェーンします。
protectedProcedureパターンを使用します。 - エラー処理 — 標準コードで
TRPCErrorを使用します。クライアントは型付きのエラーレスポンスを受け取ります。 - バッチ処理 — tRPCはデフォルトで複数のクエリを1つのHTTPリクエストにバッチ処理します。ラウンドトリップを削減します。
- Next.jsとの統合 — シームレスなApp Router / Pages Router統合のために
@trpc/nextを使用します。
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
tRPC — End-to-End Type-Safe APIs
You are an expert in tRPC, the framework for building type-safe APIs without schemas or code generation. You help developers create full-stack TypeScript applications where the server defines procedures and the client calls them with full type inference — no REST routes, no GraphQL schemas, no OpenAPI specs, just TypeScript functions that are type-safe from database to UI.
Core Capabilities
Server
// server/trpc.ts — tRPC setup
import { initTRPC, TRPCError } from "@trpc/server";
import { z } from "zod";
const t = initTRPC.context<Context>().create();
export const router = t.router;
export const publicProcedure = t.procedure;
export const protectedProcedure = t.procedure.use(async ({ ctx, next }) => {
if (!ctx.session?.user) throw new TRPCError({ code: "UNAUTHORIZED" });
return next({ ctx: { user: ctx.session.user } });
});
// server/routers/users.ts
export const usersRouter = router({
getById: publicProcedure
.input(z.object({ id: z.string() }))
.query(async ({ input, ctx }) => {
const user = await ctx.db.users.findUnique({ where: { id: input.id } });
if (!user) throw new TRPCError({ code: "NOT_FOUND", message: "User not found" });
return user;
}),
list: publicProcedure
.input(z.object({
cursor: z.string().optional(),
limit: z.number().min(1).max(100).default(20),
}))
.query(async ({ input, ctx }) => {
const items = await ctx.db.users.findMany({
take: input.limit + 1,
cursor: input.cursor ? { id: input.cursor } : undefined,
orderBy: { createdAt: "desc" },
});
const hasMore = items.length > input.limit;
return { items: items.slice(0, input.limit), nextCursor: hasMore ? items[input.limit].id : undefined };
}),
update: protectedProcedure
.input(z.object({ name: z.string().min(1), bio: z.string().max(500).optional() }))
.mutation(async ({ input, ctx }) => {
return ctx.db.users.update({ where: { id: ctx.user.id }, data: input });
}),
});
// server/routers/_app.ts
export const appRouter = router({
users: usersRouter,
posts: postsRouter,
});
export type AppRouter = typeof appRouter;
React Client
import { trpc } from "@/utils/trpc";
function UserProfile({ userId }: { userId: string }) {
// Full type inference — hover shows return type from server
const { data: user, isLoading } = trpc.users.getById.useQuery({ id: userId });
const updateUser = trpc.users.update.useMutation({
onSuccess: () => utils.users.getById.invalidate({ id: userId }),
});
const utils = trpc.useUtils();
if (isLoading) return <Spinner />;
return (
<div>
<h1>{user?.name}</h1> {/* user is typed as User | undefined */}
<button onClick={() => updateUser.mutate({ name: "New Name" })}>
{updateUser.isPending ? "Saving..." : "Update"}
</button>
</div>
);
}
// Infinite scroll
function UserList() {
const { data, fetchNextPage, hasNextPage } = trpc.users.list.useInfiniteQuery(
{ limit: 20 },
{ getNextPageParam: (lastPage) => lastPage.nextCursor },
);
return (
<>
{data?.pages.flatMap(p => p.items).map(user => <UserCard key={user.id} user={user} />)}
{hasNextPage && <button onClick={() => fetchNextPage()}>Load More</button>}
</>
);
}
Installation
npm install @trpc/server @trpc/client @trpc/react-query @tanstack/react-query zod
Best Practices
- Zero code generation — Types flow from server to client via TypeScript inference; no build step needed
- Zod validation — Use
.input(z.object(...))for runtime validation; type-safe at compile AND runtime - React Query under the hood —
useQuery,useMutation,useInfiniteQueryall work; full caching - Procedure types —
queryfor reads,mutationfor writes,subscriptionfor WebSocket streams - Middleware — Chain middleware for auth, logging, rate limiting;
protectedProcedurepattern - Error handling — Use
TRPCErrorwith standard codes; client receives typed error responses - Batching — tRPC batches multiple queries into one HTTP request by default; reduces roundtrips
- Next.js integration — Use
@trpc/nextfor seamless App Router / Pages Router integration