ai-infrastructure-hugg…
Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation,…
tRPC type-safe API patterns — routers and procedures, input validation, context and middleware, TRPCError, and the typed client bridge
$ npx -y skills add agents-inc/skills --skill web-data-fetching-trpc --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/web-data-fetching-trpcContext preview
The summary Claude sees to decide when to auto-load this skill.
tRPC type-safe API patterns — routers and procedures, input validation, context and middleware, TRPCError, and the typed client bridge
name: web-data-fetching-trpc description: tRPC type-safe API patterns — routers and procedures, input validation, context and middleware, TRPCError, and the typed client bridge
> **Quick Guide:** tRPC carries types from server to client through one exported type rather than > through a generated schema, so `export type AppRouter = typeof appRouter` is the whole bridge and > everything downstream fails without it. Procedures take a validated input and return a value; > `TRPCError` codes are what become HTTP statuses; middleware narrows the context type so an > authenticated procedure's `ctx.user` is non-nullable. In v11 the transformer moved inside the > link, subscriptions are async generators, and `@trpc/tanstack-react-query` is the current React > integration.
**Detailed Resources:**
---
hook, and each procedure exposes `queryOptions()`, `mutationOptions()`, `infiniteQueryOptions()` and `queryKey()` that go straight into the standard query hooks. Pattern 5.
own `trpc.x.useQuery()` hooks instead, and a cache key comes from `getQueryKey(trpc.x)` rather than from a `queryKey()` on the procedure. Migrate when convenient; the two can coexist.
---
<critical_requirements>
**Export the router's type: `export type AppRouter = typeof appRouter`.** That single line is the whole client-side contract — without it the client falls back to `unknown` and every guarantee tRPC offers is gone, with no error at the point the export was forgotten.
**Give every procedure that accepts input a validator on `.input()`.** It is both the runtime check and the source of the handler's parameter type, so a procedure without one receives `unknown` and tempts a cast.
**Throw `TRPCError` with a code rather than a bare `Error`.** The code is what maps to an HTTP status and what the client switches on; a bare `Error` arrives as an opaque 500.
**Place the transformer inside `httpBatchLink()`, not on `createTRPCClient()`.** v11 moved it, and the old position raises an error at client construction.
</critical_requirements>
---
**Auto-detection:** `initTRPC`, `createTRPCClient`, `createTRPCContext`, `createTRPCOptionsProxy`, `@trpc/server`, `@trpc/client`, `@trpc/react-query`, `@trpc/tanstack-react-query`, `TRPCError`, `publicProcedure`, `protectedProcedure`, `httpBatchLink`, `httpSubscriptionLink`, `loggerLink`, `inferRouterInputs`, `inferRouterOutputs`, `useTRPC`, `tracked`, `AppRouter`
**Applies to:**
**Handled elsewhere:**
document rather than a shared type
the options a query client consumes, and the client decides what to do with them
show one
---
<philosophy>
There is no API description anywhere — no schema file, no generated client, no build step between the two halves. The router's inferred type _is_ the contract, and it is shared by importing a type across the codebase.
That buys immediate accuracy: a procedure's return type changes and every call site reddens in the same typecheck, with no regeneration step to forget. It costs polyglot support, a published contract, and HTTP caching — calls go out as POST by default, so a CDN in front of the endpoint has nothing to cache. Which is why tRPC suits an internal API in one TypeScript codebase and suits a public one badly.
</philosophy>
---
<patterns>
Initialize once per application and export the factories the routers compose from.
const t = initTRPC.context<Context>().create({
transformer: superjson, // Date, Map and Set survive the wire
errorFormatter({ shape, error }) {
return {
...shape,
data: {
...shape.data,
zodError:
error.cause instanceof ZodError ? error.cause.flatten() : null,
},
};
},
});
export const router = t.router;
export const publicProcedure = t.procedure;
export const middleware = t.middleware;The error formatter is what turns a validation failure into something a form can render per field, instead of one message.
Full code: [examples/core.md](examples/core.md) — including the per-request context factory
---
const createUserSchema = z.object({
email: z.string().email(),
name: z.string().min(1).The official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?
Repo: agents-inc/skills
Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation,…
LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking, virtual keys, and production…
Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client patterns
Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output, model management, and…
Replicate SDK patterns for TypeScript/Node.js -- client setup, predictions, streaming, webhooks, file handling, model versioning, deployments, and training
Together AI SDK patterns for TypeScript — client setup, chat completions, streaming, structured output, function calling, embeddings, image generation,…