From knowledge-patch
Provides tRPC 11.18 API references and guidance for transport patterns, subscriptions, migration, OpenAPI, and TanStack/Next.js integration.
How this skill is triggered — by the user, by Claude, or both
Slash command
/knowledge-patch:trpc-knowledge-patchThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Use this skill to choose current tRPC APIs and transport patterns. Read the
Use this skill to choose current tRPC APIs and transport patterns. Read the reference that matches the task before changing an integration; transport, subscription, and cache behavior often depend on one another.
| Reference | Topics |
|---|---|
| migration-and-core.md | Removed compatibility APIs, nested and lazy routers, in-process calls, runtime fixes |
| non-json-and-http.md | FormData, binary bodies, link routing, transformers, server batch limits |
| openapi.md | Static OpenAPI generation, recursive schemas, document cleanup, generated clients |
| streaming-and-retry.md | Async generators, batch streaming, headers, runtimes, keepalives, retry policies |
| subscriptions.md | SSE and WebSocket recovery, credentials, liveness, React state, mobile support, types |
| tanstack-and-nextjs.md | TanStack-native keys and options, RSC hydration, Server Actions |
.interop()The temporary compatibility mode no longer exists. Finish the builder-API
migration before upgrading code that still calls .interop(); do not try to
shim it in a current router.
skipTokenPass TanStack Query's skipToken as the subscription input. Treat the older
enabled option as deprecated.
import { skipToken } from '@tanstack/react-query';
const result = trpc.postFeed.useSubscription(
paused ? skipToken : undefined,
{ onData: handlePost },
);
Use httpLink for FormData, Blob, File, Uint8Array, and octet-stream
inputs. httpBatchLink and httpBatchStreamLink do not carry these inputs.
splitLink({
condition: (op) => isNonJsonSerializable(op.input),
true: httpLink({ url }),
false: httpBatchLink({ url }),
});
httpBatchStreamLink commits headers before procedure results exist.
Procedures cannot set result-dependent headers or cookies after streaming
starts, and streamed responseMeta receives no data property. Use
httpBatchLink when headers depend on returned data.
Validate FormData normally. Parse an octet-stream request with
octetInputParser; its procedure input is a ReadableStream.
import { octetInputParser } from '@trpc/server/http';
import { z } from 'zod';
const appRouter = router({
uploadForm: publicProcedure
.input(z.instanceof(FormData))
.mutation(({ input }) => consumeForm(input)),
uploadBytes: publicProcedure
.input(octetInputParser)
.mutation(({ input }) => consumeStream(input)),
});
When a transformer is configured, keep the request serializer as identity on the non-JSON branch while retaining the transformer's response deserializer. See non-json-and-http.md for the complete split-link configuration.
Return an async generator from a query or mutation and use
httpBatchStreamLink. The resolved client result is an AsyncIterable.
const numbers = publicProcedure.query(async function* () {
yield 1;
yield 2;
});
const values = await client.numbers.query();
for await (const value of values) process(value);
Keep this distinct from subscriptions: an incremental procedure result ends with that call, while a subscription represents an ongoing event source. Configure runtime stream primitives, JSONL keepalives, and retry policy using streaming-and-retry.md.
Prefer SSE as the first subscription transport unless bidirectional WebSocket
behavior is required. Implement a generator and yield tracked(id, data) so
SSE and WebSocket links can resume from lastEventId.
const feed = publicProcedure
.input(z.object({ lastEventId: z.string().nullish() }).optional())
.subscription(async function* (opts) {
const live = on(events, 'post', { signal: opts.signal });
yield* replayAfter(opts.input?.lastEventId);
for await (const [post] of live) yield tracked(post.id, post);
});
Attach the live listener before querying missed records, or an event can fall between replay and listening. Expect thrown server errors in the 5xx class to reconnect and resume; let other errors stop and reach the client callback.
Use a ponyfill for arbitrary request headers. Place retryLink before
httpSubscriptionLink when a reconnect must rerun URL or credential callbacks.
Read subscriptions.md before implementing auth,
liveness, completion state, or React Native support.
Prefer @trpc/tanstack-react-query for new React work and migrate incrementally
from classic hook wrappers. Apply a common prefix consistently to generated
query and mutation keys. Router-prefix mutation options can supply defaults to
all matching procedures.
Use the RSC helpers to start a procedure on the server and let the client adopt the pending promise while hydrating the query cache. This avoids adding a server-to-client request waterfall.
For a suspense infinite query, skipToken is valid even when
getNextPageParam is omitted.
Use experimental_caller with experimental_nextAppDirCaller to expose a
procedure as a directly callable Server Action. Because the call bypasses HTTP:
pathExtractor and procedure metadata;const actionProcedure = t.procedure
.experimental_caller(
experimental_nextAppDirCaller({
pathExtractor: ({ meta }) => meta?.span ?? '',
}),
)
.use(async (opts) => opts.next({ ctx: await createActionContext() }));
Keep action construction and RSC/TanStack setup aligned with tanstack-and-nextjs.md.
Use the alpha @trpc/openapi generator for a static OpenAPI 3.1 document. It
analyzes an exported router type without running the application or requiring
route annotations and output schemas. It maps queries to GET, mutations to
POST, and omits subscriptions.
Generated clients need tRPC-aware query-input encoding plus response and error decoding. For Hey API, install the tRPC type resolvers during generation and configure the runtime client with the same transformer used by the server. Read openapi.md for recursive schemas and server URLs.
fetch and stream primitives in non-browser runtimes.npx claudepluginhub nevaberry/nevaberry-plugins --plugin knowledge-patchBuild end-to-end type-safe APIs with tRPC — routers, procedures, middleware, subscriptions, and Next.js/React integration patterns.
Builds tRPC APIs with Zod validation, middleware chaining, Vertical Slice architecture, and domain error handling.
Sets up tRPC with Next.js App Router using the fetch adapter, server-side callers for RSC, and client components via React Query.