$devvkit learn --librarie trpc-guide
tRPC Guide
[typescript][api][rpc]
JavaScript / TypeScript
Install
npm install @trpc/server @trpc/client @trpc/react-query zod
tRPC eliminates the HTTP API layer. Write TypeScript functions on the server, call them from client.
Types flow from server to client with zero code generation — autocompletion for every API call.
Works with React, Next.js, Express. HTTP under the hood with batching and WebSocket subscriptions.
Server Setup
Init server— Create tRPC instance.
import { initTRPC } from '@trpc/server';
const t = initTRPC.create();
export const router = t.router;
export const publicProcedure = t.procedure;Router Definition
Query router— Define read endpoint.
export const userRouter = router({
list: publicProcedure.query(() => db.user.findMany()),
byId: publicProcedure.input(z.string()).query(({input}) => db.user.findUnique({where:{id:input}})),
});Mutation— Define write endpoint.
createUser: publicProcedure.input(z.object({name:z.string(),email:z.string().email()}))
.mutation(({input}) => db.user.create({data: input})),Merge routers— Combine routers.
export const appRouter = router({ user: userRouter, post: postRouter });
export type AppRouter = typeof appRouter;Client Integration
Vanilla client— Call procedures.
const client = createTRPCClient<AppRouter>({ links: [httpBatchLink({url:'http://localhost:3000/trpc'})] });
await client.user.list.query();
await client.user.createUser.mutate({name:'Alice',email:'a@b.com'});React Integration
React Query— React hooks.
export const trpc = createTRPCReact<AppRouter>();
function Users() {
const {data:users} = trpc.user.list.useQuery();
const create = trpc.user.createUser.useMutation({onSuccess:() => trpc.user.list.useUtils().invalidate()});
}Next.js adapter— App Router setup.
// app/api/trpc/[trpc]/route.ts
import { fetchRequestHandler } from '@trpc/server/adapters/fetch';
export { handler as GET, handler as POST };Error Handling
Error handling— Typed TRPCError.
if (!user) throw new TRPCError({ code: 'NOT_FOUND', message: 'User not found' });Advanced
Auth middleware— Protected procedure.
const authProcedure = publicProcedure.use(async ({ctx, next}) => {
if (!ctx.user) throw new TRPCError({ code: 'UNAUTHORIZED' });
return next({ ctx: { ...ctx, user: ctx.user } });
});