Provides best practices and implementation patterns for tRPC, enabling end-to-end type safety in TypeScript apps.
Install
mkdir -p .claude/skills/trpc && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/11696" && unzip -o skill.zip -d .claude/skills/trpc && rm skill.zipInstalls to .claude/skills/trpc
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
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 GraphKey capabilities
- →Define server-side tRPC procedures for queries and mutations
- →Implement type-safe API endpoints without schemas or code generation
- →Utilize Zod for runtime input validation on the server
- →Connect client-side React components to server procedures with full type inference
- →Manage authentication and authorization using tRPC middleware
- →Handle errors with TRPCError and standard codes
How it works
tRPC enables end-to-end type safety by allowing developers to define server procedures in TypeScript, which are then consumed by the client with full type inference, eliminating the need for separate schema definitions.
Inputs & outputs
When to use trpc
- →Set up tRPC router
- →Define protected procedures
- →Implement database queries with Zod validation
- →Connect client-side calls to server procedures
About this skill
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
When not to use it
- →When building APIs that require REST routes
- →When GraphQL schemas are a project requirement
- →When OpenAPI specifications are mandated for API documentation
Prerequisites
Limitations
- →Requires TypeScript for full type inference benefits
- →Primarily designed for full-stack TypeScript applications
- →Relies on React Query for client-side data fetching patterns
How it compares
tRPC provides a unique approach to API development by use TypeScript's inference capabilities to achieve type safety across the stack without code generation or traditional API schemas, unlike REST or GraphQL.
Compared to similar skills
trpc side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| trpc (this skill) | 0 | 4mo | Review | Intermediate |
| telegram-mini-app | 62 | 6mo | Review | Advanced |
| stripe-integration | 48 | 2mo | No flags | Advanced |
| nodejs-backend-patterns | 12 | 2mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by ComeOnOliver
View all by ComeOnOliver →You might also like
telegram-mini-app
davila7
Expert in building Telegram Mini Apps (TWA) - web apps that run inside Telegram with native-like experience. Covers the TON ecosystem, Telegram Web App API, payments, user authentication, and building viral mini apps that monetize. Use when: telegram mini app, TWA, telegram web app, TON app, mini app.
stripe-integration
wshobson
Implement Stripe payment processing for robust, PCI-compliant payment flows including checkout, subscriptions, and webhooks. Use when integrating Stripe payments, building subscription systems, or implementing secure checkout flows.
nodejs-backend-patterns
wshobson
Build production-ready Node.js backend services with Express/Fastify, implementing middleware patterns, error handling, authentication, database integration, and API design best practices. Use when creating Node.js servers, REST APIs, GraphQL backends, or microservices architectures.
agent-dev-backend-api
ruvnet
Agent skill for dev-backend-api - invoke with $agent-dev-backend-api
shopify-apps
alinaqi
Shopify app development - Remix, Admin API, checkout extensions
ccxt-typescript
ccxt
CCXT cryptocurrency exchange library for TypeScript and JavaScript developers (Node.js and browser). Covers both REST API (standard) and WebSocket API (real-time). Helps install CCXT, connect to exchanges, fetch market data, place orders, stream live tickers/orderbooks, handle authentication, and manage errors. Use when working with crypto exchanges in TypeScript/JavaScript projects, trading bots, arbitrage systems, or portfolio management tools. Includes both REST and WebSocket examples.