Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
tRPC lets you build fully type-safe APIs without writing a schema or code-generation step. Your TypeScript types flow from the server router directly to the client — so every API call is autocompleted, validated at compile time, and refactoring-safe. Use this skill when building TypeScript monorepos, Next.js apps, or any project where the server and client share a codebase.
When to Use This Skill
Use when building a TypeScript full-stack app (Next.js, Remix, Express + React) where the client and server share a single repo
Use when you want end-to-end type safety on API calls without REST/GraphQL schema overhead
Use when adding real-time features (subscriptions) to an existing tRPC setup
Use when designing multi-step middleware (auth, rate limiting, tenant scoping) on tRPC procedures
Use when migrating an existing REST/GraphQL API to tRPC incrementally
Core Concepts
Routers and Procedures
A router groups related procedures (think: endpoints). Procedures are typed functions — query for reads, mutation for writes, subscription for real-time streams.
Input Validation with Zod
All procedure inputs are validated with Zod schemas. The validated, typed input is available in the procedure handler — no manual parsing.
Context
context is shared state passed to every procedure — auth session, database client, request headers, etc. It is built once per request in a context factory. Important: Next.js App Router and Pages Router require separate context factories because App Router handlers receive a fetch Request, not a Node.js NextApiRequest.
Middleware
Middleware chains run before a procedure. Use them for authentication, logging, and request enrichment. They can extend the context for downstream procedures.
Next.js App Router handlers receive a fetch Request (not a Node.js NextApiRequest), so the context
must be built differently depending on the call site. Define one factory per surface:
// src/server/context.tsimport { typeFetchCreateContextFnOptions } from'@trpc/server/adapters/fetch';
import { auth } from'@/server/auth'; // Next-Auth v5 / your auth helperimport { db } from'./db';
/**
* Context for the HTTP handler (App Router Route Handler).
* `opts.req` is the fetch Request — auth is resolved server-side via `auth()`.
*/exportasyncfunctioncreateTRPCContext(opts: FetchCreateContextFnOptions) {
const session = awaitauth(); // server-side auth — no req/res neededreturn { session, db, headers: opts.req.headers };
}
/**
* Context for direct server-side callers (Server Components, RSC, cron jobs).
* No HTTP request is involved, so we call auth() directly from the server.
*/exportasyncfunctioncreateServerContext() {
const session = awaitauth();
return { session, db };
}
exporttypeContext = Awaited<ReturnType<typeof createTRPCContext>>;
Step 3: Build an Auth Middleware and Protected Procedure
// src/server/root.tsimport { router } from'./trpc';
import { postRouter } from'./routers/post';
import { userRouter } from'./routers/user';
exportconst appRouter = router({
post: postRouter,
user: userRouter,
});
// Export the type for the client — never import the appRouter itself on the clientexporttypeAppRouter = typeof appRouter;
Step 6: Mount the API Handler (Next.js App Router)
The App Router handler must use fetchRequestHandler and the fetch-based context factory.
createTRPCContext receives FetchCreateContextFnOptions (with a fetch Request), not
a Pages Router req/res pair.
// Client usage — requires wsLink in the client config
trpc.notification.onNew.useSubscription(undefined, {
onData(data) {
toast(data.message);
},
});
Best Practices
✅ Export only AppRouter type from server code — never import appRouter on the client
✅ Use separate context factories — createTRPCContext for the HTTP handler, createServerContext for Server Components and callers
✅ Validate all inputs with Zod — never trust raw input without a schema
✅ Split routers by domain (posts, users, billing) and merge in root.ts
✅ Extend context in middleware rather than querying the DB multiple times per request
✅ Use utils.invalidate() after mutations to keep the cache fresh
❌ Don't cast context with as any to silence type errors — the mismatch will surface as a runtime failure when auth or session lookups return undefined
❌ Don't use createContext({} as any) in Server Components — use createServerContext() which calls auth() directly
❌ Don't put business logic in the route handler — keep it in the procedure or a service layer
❌ Don't share the tRPC client instance globally — create it per-provider to avoid stale closures
Security & Safety Notes
Always enforce authorization in protectedProcedure — never rely on client-side checks alone
Validate all input shapes with Zod, including pagination cursors and IDs, to prevent injection via malformed inputs
Avoid exposing internal error details to clients — use TRPCError with a public-safe message and keep stack traces server-side only
Rate-limit public procedures using middleware to prevent abuse
Common Pitfalls
Problem: Auth session is null in protected procedures even when the user is logged in
Solution: Ensure createTRPCContext uses the correct server-side auth call (e.g. auth() from Next-Auth v5) and is not receiving a Pages Router req/res cast via as any in an App Router handler
Problem: Server Component caller fails for auth-dependent queries
Solution: Use createServerContext() (the dedicated server-side factory) instead of passing an empty or synthetic object to createContext
Problem: "Type error: AppRouter is not assignable to AnyRouter"
Solution: Import AppRouter as a type import (import type { AppRouter }) on the client, not the full module
Problem: Mutations not reflecting in the UI after success
Solution: Call utils.<router>.<procedure>.invalidate() in onSuccess to trigger a refetch via React Query
Problem: "Cannot find module '@trpc/server/adapters/next'" with App Router
Solution: Use @trpc/server/adapters/fetch and fetchRequestHandler for the App Router; the nextjs adapter is for Pages Router only
Problem: Subscriptions not connecting
Solution: Subscriptions require splitLink — route subscriptions to wsLink and queries/mutations to httpBatchLink
Related Skills
@typescript-expert — Deep TypeScript patterns used inside tRPC routers and generic utilities
@react-patterns — React hooks patterns that pair with trpc.*.useQuery and useMutation
@test-driven-development — Write procedure unit tests using createCallerFactory without an HTTP server
@security-auditor — Review tRPC middleware chains for auth bypass and input validation gaps