home / skills / dimitrigilbert / ai-skills / trpc

trpc skill

/trpc

This skill helps you implement a versatile tRPC setup across backend and frontend, providing type-safe routers, clients, and error handling.

npx playbooks add skill dimitrigilbert/ai-skills --skill trpc

Review the files below or copy the command above to add this skill to your agents.

Files (11)
SKILL.md
2.3 KB
---
name: trpc
description: Generic tRPC implementation guide. Works with any framework (Next.js, Express, Fastify, Hono, Bun) and any package manager (pnpm, npm, yarn, bun).
---

# tRPC Quick Start

## Backend Router

```typescript
import { initTRPC, TRPCError } from "@trpc/server";
import { z } from "zod";

export const t = initTRPC.create();
export const router = t.router;
export const publicProcedure = t.procedure;

export const myRouter = router({
  getItem: publicProcedure
    .input(z.object({ id: z.string() }))
    .query(async ({ input }) => {
      return await getItem(input.id);
    }),

  updateItem: publicProcedure
    .input(z.object({ id: z.string(), data: z.any() }))
    .mutation(async ({ input }) => {
      return await updateItem(input.id, input.data);
    }),
});

export const appRouter = router({
  healthCheck: publicProcedure.query(() => "OK"),
  my: myRouter,
});

export type AppRouter = typeof appRouter;
```

## Frontend Client

```typescript
import { createTRPCClient, httpBatchLink } from "@trpc/client";
import { createTRPCOptionsProxy } from "@trpc/tanstack-react-query";
import type { AppRouter } from "./path/to/router";
import { QueryClient } from "@tanstack/react-query";

export const queryClient = new QueryClient();
export const trpcClient = createTRPCClient<AppRouter>({
  links: [httpBatchLink({ url: "/api/trpc" })],
});

export const trpc = createTRPCOptionsProxy<AppRouter>({
  client: trpcClient,
  queryClient,
});
```

## Usage

```typescript
const { data } = useQuery(trpc.my.getItem.queryOptions({ id }));
const mutation = useMutation(trpc.my.updateItem.mutationOptions());
```

## Error Handling

```typescript
throw new TRPCError({
  code: "NOT_FOUND",
  message: "Resource not found",
});
```

## Advanced

- **Subscriptions**: See [SUBSCRIPTIONS.md](references/SUBSCRIPTIONS.md)
- **Server Adapters**: See [ADAPTERS.md](references/ADAPTERS.md)
- **Context**: See [CONTEXT.md](references/CONTEXT.md)
- **Router Merging**: See [ROUTERS.md](references/ROUTERS.md)
- **Middleware**: See [MIDDLEWARE.md](references/MIDDLEWARE.md)
- **Frontend Patterns**: See [FRONTEND.md](references/FRONTEND.md)
- **Client Links**: See [LINKS.md](references/LINKS.md)
- **Schemas**: See [SCHEMAS.md](references/SCHEMAS.md)
- **Client Errors**: See [CLIENT_ERRORS.md](references/CLIENT_ERRORS.md)
- **Install**: See [INSTALL.md](references/INSTALL.md)

Overview

This skill is a compact, framework-agnostic guide for building type-safe tRPC APIs and clients with TypeScript. It demonstrates a minimal backend router, a frontend client integration using TanStack Query, basic usage patterns, and error handling. The material works with any server framework (Next.js, Express, Fastify, Hono, Bun) and any package manager.

How this skill works

It shows how to initialize tRPC on the server, define procedures and nested routers, and export a router type for client inference. On the client it creates a typed tRPC client with http batching and a TanStack Query integration proxy for query/mutation hooks. It also demonstrates throwing TRPCError for consistent server-side error codes.

When to use it

  • You want end-to-end type safety between client and server without writing REST contracts.
  • You need a lightweight RPC layer that works across multiple frameworks and runtimes.
  • You plan to use TanStack Query for caching, optimistic updates, and background refetching.
  • You prefer centralizing validation with zod schemas and sharing types across boundaries.

Best practices

  • Define a single AppRouter type and export it so the client can infer routes and inputs/outputs.
  • Use zod (or similar) for all procedure .input() validation to ensure runtime and compile-time safety.
  • Group related procedures into nested routers for clearer route organization and easier merging.
  • Use http batching in production to reduce request overhead for many small queries.
  • Throw TRPCError with appropriate codes (e.g., NOT_FOUND, UNAUTHORIZED) to standardize client error handling.

Example use cases

  • Health checks and public read endpoints (e.g., healthCheck returning 'OK').
  • CRUD APIs where each operation is a procedure with zod-validated inputs (getItem, updateItem).
  • Realtime features via subscriptions combined with standard queries and mutations.
  • Multi-framework deployments where the same router implementation is reused across Next.js, Express, Fastify, Hono, or Bun.

FAQ

How do I share types between server and client?

Export the AppRouter type from the server module and use it as the generic when creating the client (createTRPCClient<AppRouter>), so routes and IO types are inferred automatically.

Can I use tRPC without TanStack Query?

Yes. TanStack Query is recommended for caching and hooks, but you can call the trpc client directly or integrate with other data-fetching libraries if desired.