Back to Trpc

tRPC — Skill Spec

_artifacts/skill_spec.md

11.16.024.9 KB
Original Source

tRPC — Skill Spec

tRPC is a TypeScript framework for building end-to-end typesafe APIs without schemas or code generation. It lets you define server procedures (query, mutation, subscription) and call them from clients with full static type safety, autocompletion, and zero runtime overhead.

Domains

DomainDescriptionSkills
Defining the APIServer-side setup: routers, procedures, context, middleware, validators, errorsserver-setup, middlewares, validators, error-handling, server-side-calls, caching, non-json-content-types
Consuming the APIClient-side setup: clients, links, headers, transformers, React Queryclient-setup, links, react-query-setup, react-query-classic-migration, superjson
Hosting the APIAdapters for server and serverless runtimesadapter-standalone, adapter-express, adapter-fastify, adapter-aws-lambda, adapter-fetch
Real-timeSSE and WebSocket subscriptionssubscriptions
Framework integrationNext.js and React with SSR/RSCnextjs-app-router, nextjs-pages-router
Interop and publishingOpenAPI, SOA, authauth, openapi, service-oriented-architecture

Skill Inventory

SkillTypeDomainWhat it coversFailure modes
server-setupcoredefining-apiinitTRPC, routers, procedures, context, AppRouter export9
middlewarescoredefining-api.use(), .concat(), base procedures, OTEL tracing3
validatorscoredefining-api.input()/.output() with Zod, input chaining, Standard Schema3
error-handlingcoredefining-apiTRPCError, errorFormatter, onError, status codes3
server-side-callscoredefining-apicreateCallerFactory, testing patterns2
cachingcoredefining-apiresponseMeta, Cache-Control, CDN caching2
non-json-content-typescoredefining-apiFormData, file uploads, binary data, octetInputParser3
client-setupcoreconsuming-apicreateTRPCClient, headers, transformers, type inference6
linkscoreconsuming-apihttpLink, httpBatchLink, httpBatchStreamLink, splitLink, wsLink, etc.5
react-query-setupframeworkconsuming-apicreateTRPCContext, TRPCProvider, queryOptions, mutationOptions3
react-query-classic-migrationlifecycleconsuming-api@trpc/upgrade CLI, hook→options migration2
superjsoncompositionconsuming-apiSuperJSON transformer on server + client links3
adapter-standalonecorehosting-apicreateHTTPServer, CORS, basePath, HTTP/21
adapter-expresscorehosting-apicreateExpressMiddleware, context with req/res1
adapter-fastifycorehosting-apifastifyTRPCPlugin, WebSocket, maxParamLength3
adapter-aws-lambdacorehosting-apiawsLambdaRequestHandler, streaming, API Gateway2
adapter-fetchcorehosting-apifetchRequestHandler, Cloudflare/Deno/Vercel Edge1
subscriptionscorerealtimeasync generators, tracked(), SSE, WebSocket, reconnection7
nextjs-app-routerframeworkframework-integrationfetch adapter, RSC prefetch, HydrateClient, Server Actions4
nextjs-pages-routerframeworkframework-integrationwithTRPC HOC, SSR, SSG, createNextApiHandler2
authcompositiondefining-apiJWT/cookie auth, middleware, context narrowing, SSE auth4
openapicompositioninteropOpenAPI spec generation, HeyAPI client, transformers2
service-oriented-architecturecompositioninteropCustom routing links, gateway pattern, shared routers1

Failure Mode Inventory

server-setup (9 failure modes)

#MistakePrioritySourceCross-skill?
1Calling initTRPC.create() more than onceCRITICALdocs
2Using reserved words as procedure namesHIGHsource
3Importing AppRouter as a value importCRITICALinterview
4Creating context without inner/outer splitMEDIUMexamples
5Merging routers with different transformersHIGHsource
6Hallucinating v10 API patternsCRITICALmigration guideclient-setup, links, subscriptions
7Using type assertions to work around AppRouter import errorsCRITICALinterviewclient-setup
8Treating tRPC as a REST APICRITICALinterviewclient-setup
9Importing appRouter value (not type) into clientCRITICALinterview

middlewares (3 failure modes)

#MistakePrioritySourceCross-skill?
1Forgetting to call and return opts.next()CRITICALsource
2Extending context with wrong typeHIGHdocs
3Using experimental_standaloneMiddleware (deprecated)MEDIUMsource

validators (3 failure modes)

#MistakePrioritySourceCross-skill?
1Chaining non-object inputsMEDIUMdocs
2Output validation failure returns 500MEDIUMdocs
3cursor: z.optional() without nullable for infinite queriesHIGHGitHub #6862

error-handling (3 failure modes)

#MistakePrioritySourceCross-skill?
1Throwing plain Error instead of TRPCErrorHIGHdocs
2Expecting stack traces in productionMEDIUMdocs
3Not handling Zod errors in errorFormatterHIGHdocs

server-side-calls (2 failure modes)

#MistakePrioritySourceCross-skill?
1Using createCaller inside another procedureHIGHdocs
2Not providing context to createCallerMEDIUMdocs

caching (2 failure modes)

#MistakePrioritySourceCross-skill?
1Caching authenticated responsesCRITICALdocs
2Caching with Next.js App Router overridesHIGHGitHub #5625

non-json-content-types (3 failure modes)

#MistakePrioritySourceCross-skill?
1Using httpBatchLink for FormData requestsHIGHdocs
2Global body parser intercepting FormDataHIGHdocs
3FormData only works with mutationsHIGHsource

client-setup (6 failure modes)

#MistakePrioritySourceCross-skill?
1Missing AppRouter type parameterCRITICALdocs
2Transformer on server but not on client linksCRITICALGitHub #7083
3Passing transformer to createTRPCClient instead of linksCRITICALsource
4HTML error page instead of JSON responseHIGHinterview
5Confusion about which client factory to useHIGHinterview
6Worrying about @trpc/server as client dependencyMEDIUMinterview
#MistakePrioritySourceCross-skill?
1No terminating link in the chainCRITICALsource
2Sending subscriptions through httpLinkCRITICALsource
3Batch headers callback using wrong parameterHIGHsource
4httpBatchStreamLink data loss on stream completionHIGHGitHub #7209
5Default batch limits are InfinityMEDIUMsource

react-query-setup (3 failure modes)

#MistakePrioritySourceCross-skill?
1Using useQuery without queryOptions factoryHIGHdocs
2Missing TRPCProvider wrapperHIGHsource
3Invalidating queries with wrong APIHIGHdocs

react-query-classic-migration (2 failure modes)

#MistakePrioritySourceCross-skill?
1Assuming the codemod handles everythingMEDIUMdocs
2Mixing classic and new hooks in same componentMEDIUMdocs

superjson (3 failure modes)

#MistakePrioritySourceCross-skill?
1Transformer on server but not on client linkCRITICALGitHub #7083
2Error responses bypass transformerHIGHGitHub #7083
3Forgetting transformer on subscription linksHIGHdocs

adapter-standalone (1 failure mode)

#MistakePrioritySourceCross-skill?
1No CORS configurationHIGHdocs

adapter-express (1 failure mode)

#MistakePrioritySourceCross-skill?
1Global express.json() consuming tRPC request bodyHIGHdocs

adapter-fastify (3 failure modes)

#MistakePrioritySourceCross-skill?
1Registering WebSocket after tRPC pluginHIGHdocs
2Missing maxParamLength for batch requestsHIGHdocs
3Using Fastify v4 with tRPC v11CRITICALdocs

adapter-aws-lambda (2 failure modes)

#MistakePrioritySourceCross-skill?
1httpBatchLink with per-procedure API Gateway resourcesHIGHdocs
2Forgetting streamifyResponse wrapperHIGHdocs

adapter-fetch (1 failure mode)

#MistakePrioritySourceCross-skill?
1Mismatched endpoint path in fetchRequestHandlerHIGHdocs

subscriptions (7 failure modes)

#MistakePrioritySourceCross-skill?
1Using Observable instead of async generatorHIGHsource
2Empty string as tracked event IDMEDIUMsource
3Fetching history before setting up event listenerHIGHdocs
4WebSocket subscription stale inputs on reconnectMEDIUMGitHub #4122
5SSE ping interval >= client reconnect intervalMEDIUMsource
6Sending custom headers with SSE without polyfillHIGHinterview/docs
7Choosing WebSocket when SSE would sufficeMEDIUMinterview

nextjs-app-router (4 failure modes)

#MistakePrioritySourceCross-skill?
1Not exporting both GET and POST from route handlerCRITICALdocs
2Suspense query failure crashes entire pageHIGHdocs
3Creating singleton QueryClient for SSRCRITICALdocs
4Missing dehydrate/serialize config on QueryClientHIGHsource

nextjs-pages-router (2 failure modes)

#MistakePrioritySourceCross-skill?
1SSR prepass renders multiple timesMEDIUMsource
2Using ssr: true without understanding implicationsMEDIUMdocs

auth (4 failure modes)

#MistakePrioritySourceCross-skill?
1Not narrowing user type in auth middlewareHIGHdocs
2SSE auth via URL query params exposes tokensHIGHdocs
3Async headers causing stuck isFetchingMEDIUMGitHub #7001
4Skipping auth or opening CORS too wideHIGHinterview

openapi (2 failure modes)

#MistakePrioritySourceCross-skill?
1Missing transformer config in HeyAPI clientHIGHdocs
2Expecting subscriptions in OpenAPI specMEDIUMdocs

service-oriented-architecture (1 failure mode)

#MistakePrioritySourceCross-skill?
1Path routing assumes server name prefixMEDIUMexamples

Tensions

TensionSkillsAgent implication
Type safety vs runtime flexibilityserver-setup ↔ middlewaresAgent may compose routers from different initTRPC instances without compile-time errors, but they crash at runtime
Batching convenience vs caching safetylinks ↔ cachingAgent adding cache headers may not realize batched responses mix public and private data
SSR simplicity vs server component architecturenextjs-app-router ↔ nextjs-pages-routerAgent may apply Pages Router SSR patterns in App Router or vice versa
Streaming performance vs reliabilitylinks ↔ subscriptionsAgent may default to httpBatchStreamLink without considering platform streaming support

Cross-References

FromToReason
server-setupclient-setupTransformer/errorFormatter config must match; AppRouter type consumed by client
server-setupmiddlewaresBase procedures compose middleware during setup
client-setuplinksClient creation requires configuring a link chain
client-setupsuperjsonTransformer must be on every terminating link
linkssubscriptionsSubscriptions require specific link type via splitLink
authmiddlewaresAuth implemented as middleware narrowing context
authsubscriptionsSSE/WS auth uses different mechanisms than HTTP
validatorserror-handlingValidation failures produce BAD_REQUEST; errorFormatter exposes Zod details
react-query-setupnextjs-app-routerApp Router uses @trpc/tanstack-react-query with RSC prefetching
react-query-classic-migrationreact-query-setupMigration target is the new package
openapisuperjsonOpenAPI clients need matching transformer config
non-json-content-typeslinksNon-JSON inputs require splitLink routing to httpLink
cachingauthCached responses must not include authenticated data
nextjs-app-routernextjs-pages-routerBoth routers may coexist during migration

Subsystems & Reference Candidates

SkillSubsystemsReference candidates
linkshttpLink, httpBatchLink, httpBatchStreamLink, wsLink, httpSubscriptionLinkLink options reference (>10 link types with unique config)

Remaining Gaps

SkillQuestionStatus
subscriptionsRecommended patterns for scaling WebSocket connections in production?open
nextjs-app-routerRecommended caching strategy given App Router overrides Cache-Control?open
openapiTransformer configs for OpenAPI beyond superjson (EJSON, Ion)?open
service-oriented-architecturePatterns for service discovery, health checks, circuit breaking?open
  • Core skills: server-setup, middlewares, validators, error-handling, server-side-calls, caching, non-json-content-types, client-setup, links, subscriptions
  • Framework skills: react-query-setup, nextjs-app-router, nextjs-pages-router
  • Lifecycle skills: react-query-classic-migration
  • Composition skills: auth, superjson, openapi, service-oriented-architecture
  • Adapter skills: adapter-standalone, adapter-express, adapter-fastify, adapter-aws-lambda, adapter-fetch
  • Reference files: links (needs references/ for each link type's config surface)

Composition Opportunities

LibraryIntegration pointsComposition skill needed?
ZodInput/output validationNo — covered in validators skill
SuperJSONData transformerYes — superjson
@tanstack/react-queryReact data fetchingYes — react-query-setup
Next.jsFull-stack frameworkYes — nextjs-app-router, nextjs-pages-router
ExpressHTTP serverYes — adapter-express
FastifyHTTP serverYes — adapter-fastify
@hey-api/openapi-tsClient generationYes — openapi
OAuth2.0 / JWTAuthenticationYes — auth
Prisma / DrizzleDatabase ORMNo — standard usage, no tRPC-specific integration patterns