trpc▌
mindrally/skills · updated Apr 8, 2026
You are an expert in tRPC v11, TypeScript, and Next.js development. tRPC enables end-to-end typesafe APIs, allowing you to build and consume APIs without schemas, code generation, or runtime errors.
tRPC Best Practices
You are an expert in tRPC v11, TypeScript, and Next.js development. tRPC enables end-to-end typesafe APIs, allowing you to build and consume APIs without schemas, code generation, or runtime errors.
Requirements
- TypeScript >= 5.7.2
- Strict TypeScript mode enabled
Project Structure
src/
pages/
_app.tsx # createTRPCNext setup
api/
trpc/
[trpc].ts # tRPC HTTP handler
server/
routers/
_app.ts # Main router
[feature].ts # Feature-specific routers
context.ts # App context
trpc.ts # Procedure helpers
utils/
trpc.ts # Typesafe React hooks
Server-Side Setup
Initialize tRPC Backend
Initialize tRPC backend once per application. Export reusable router and procedure helpers:
// server/trpc.ts
import { initTRPC } from '@trpc/server';
import superjson from 'superjson';
const t = initTRPC.context<Context>().create({
transformer: superjson,
});
export const router = t.router;
export const publicProcedure = t.procedure;
export const protectedProcedure = t.procedure.use(isAuthed);
export const adminProcedure = t.procedure.use(isAdmin);
Create Feature Routers
Organize routers by feature/domain. Use Zod for input validation:
// server/routers/user.ts
import { z } from 'zod';
import { router, publicProcedure, protectedProcedure } from '../trpc';
export const userRouter = router({
getById: publicProcedure
.input(z.object({ id: z.string() }))
.query(async ({ input, ctx }) => {
return ctx.db.user.findUnique({ where: { id: input.id } });
}),
update: protectedProcedure
.input(z.object({
name: z.string().min(1),
email: z.string().email(),
}))
.mutation(async ({ input, ctx }) => {
return ctx.db.user.update({
where: { id: ctx.user.id },
data: input,
});
}),
});
Main App Router
// server/routers/_app.ts
import { router } from '../trpc';
import { userRouter } from './user';
import { postRouter } from './post';
export const appRouter = router({
user: userRouter,
post: postRouter,
});
export type AppRouter = typeof appRouter;
Client-Side Setup
Configure tRPC Client
// utils/trpc.ts
import { httpBatchLink } from '@trpc/client';
import { createTRPCNext } from '@trpc/next';
import superjson from 'superjson';
import type { AppRouter } from '../server/routers/_app';
function getBaseUrl() {
if (typeof window !== 'undefined') return '';
if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`;
return `http://localhost:${process.env.PORT ?? 3000}`;
}
export const trpc = createTRPCNext<AppRouter>({
config() {
return {
transformer: superjson,
links: [
httpBatchLink({
url: `${getBaseUrl()}/api/trpc`,
maxURLLength: 2083,
}),
],
};
},
ssr: false,
});
Key Best Practices
1. Input Validation
Always use Zod for type safety and runtime validation on all procedure inputs:
.input(z.object({
email: z.string().email(),
age: z.number().min(0).max(120),
}))
2. Router Organization
Structure routers by feature/domain rather than one monolithic router. Each feature should have its own router file.
3. Middleware Implementation
Implement middleware for authentication, logging, and cross-cutting concerns:
const isAuthed = t.middleware(({ ctx, next }) => {
if (!ctx.user) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}
return next({ ctx: { user: ctx.user } });
});
4. Error Handling
Use TRPCError for consistent, informative error responses:
import { TRPCError } from '@trpc/server';
throw new TRPCError({
code: 'NOT_FOUND',
message: 'User not found',
});
5. Data Transformers
Apply SuperJSON for automatic serialization of dates, Maps, Sets, and other JavaScript types:
import superjson from 'superjson';
const t = initTRPC.create({
transformer: superjson,
});
6. React Query Integration
Leverage tRPC's built-in React Query utilities for data fetching, mutations, and caching:
// Queries
const { data, isLoading } = trpc.user.getById.useQuery({ id: '123' });
// Mutations
const mutation = trpc.user.update.useMutation({
onSuccess: () => {
utils.user.getById.invalidate();
},
});
// Prefetching
await utils.user.getById.prefetch({ id: '123' });
7. Context Creation
Share resources (database connections, user sessions) across procedures via context:
// server/context.ts
export async function createContext({ req, res }: CreateNextContextOptions) {
const user = await getUser(req);
return {
db: prisma,
user,
req,
res,
};
}
export type Context = Awaited<ReturnType<typeof createContext>>;
8. Type Exports
Export only type signatures to client code, never router implementations:
// Only export the type
export type AppRouter = typeof appRouter;
// Never export the actual router to client code
9. Authorization Levels
Create distinct procedure types for different authorization levels:
export const publicProcedure = t.procedure;
export const protectedProcedure = t.procedure.use(isAuthed);
export const adminProcedure = t.procedure.use(isAuthed).use(isAdmin);
10. Performance Optimization
- Enable request batching with httpBatchLink
- Configure maxURLLength to prevent URL length issues
- Implement prefetching for static/predictable data
- Use React Query's caching strategies
Anti-Patterns to Avoid
- Do not use
anytypes - leverage tRPC's full type inference - Do not skip input validation
- Do not expose internal errors to clients
- Do not mix server and client code
- Do not create overly large routers - split by feature
Ratings
4.5★★★★★10 reviews- ★★★★★Shikha Mishra· Oct 10, 2024
trpc is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
- ★★★★★Piyush G· Sep 9, 2024
Keeps context tight: trpc is the kind of skill you can hand to a new teammate without a long onboarding doc.
- ★★★★★Chaitanya Patil· Aug 8, 2024
Registry listing for trpc matched our evaluation — installs cleanly and behaves as described in the markdown.
- ★★★★★Sakshi Patil· Jul 7, 2024
trpc reduced setup friction for our internal harness; good balance of opinion and flexibility.
- ★★★★★Ganesh Mohane· Jun 6, 2024
I recommend trpc for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
- ★★★★★Oshnikdeep· May 5, 2024
Useful defaults in trpc — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
- ★★★★★Dhruvi Jain· Apr 4, 2024
trpc has been reliable in day-to-day use. Documentation quality is above average for community skills.
- ★★★★★Rahul Santra· Mar 3, 2024
Solid pick for teams standardizing on skills: trpc is focused, and the summary matches what you get after install.
- ★★★★★Pratham Ware· Feb 2, 2024
We added trpc from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
- ★★★★★Yash Thakker· Jan 1, 2024
trpc fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.