Claude
Skills
Sign in
Back

trpc-type-safety

Included with Lifetime
$97 forever

tRPC end-to-end type-safe APIs for TypeScript with React Query integration and full-stack type safety

Web Dev

What this skill does

# tRPC - End-to-End Type Safety

---
progressive_disclosure:
  entry_point: summary
  sections:
    - id: summary
      title: "tRPC Overview"
      tokens: 70
      next: [when_to_use, quick_start]
    - id: when_to_use
      title: "When to Use tRPC"
      tokens: 150
      next: [quick_start, core_concepts]
    - id: quick_start
      title: "Quick Start"
      tokens: 300
      next: [core_concepts, router_definition]
    - id: core_concepts
      title: "Core Concepts"
      tokens: 400
      next: [router_definition, procedures]
    - id: router_definition
      title: "Router Definition"
      tokens: 350
      next: [procedures, context]
    - id: procedures
      title: "Procedures (Query & Mutation)"
      tokens: 400
      next: [input_validation, context]
    - id: input_validation
      title: "Input Validation with Zod"
      tokens: 350
      next: [context, middleware]
    - id: context
      title: "Context Management"
      tokens: 400
      next: [middleware, error_handling]
    - id: middleware
      title: "Middleware"
      tokens: 400
      next: [error_handling, client_setup]
    - id: error_handling
      title: "Error Handling"
      tokens: 350
      next: [client_setup, react_integration]
    - id: client_setup
      title: "Client Setup"
      tokens: 400
      next: [react_integration, nextjs_integration]
    - id: react_integration
      title: "React Query Integration"
      tokens: 450
      next: [nextjs_integration, subscriptions]
    - id: nextjs_integration
      title: "Next.js App Router Integration"
      tokens: 500
      next: [subscriptions, file_uploads]
    - id: subscriptions
      title: "Real-time Subscriptions"
      tokens: 400
      next: [file_uploads, batching]
    - id: file_uploads
      title: "File Uploads"
      tokens: 300
      next: [batching, typescript_inference]
    - id: batching
      title: "Batch Requests & Data Loaders"
      tokens: 350
      next: [typescript_inference, testing]
    - id: typescript_inference
      title: "TypeScript Inference Patterns"
      tokens: 300
      next: [testing, production_patterns]
    - id: testing
      title: "Testing Strategies"
      tokens: 400
      next: [production_patterns, comparison]
    - id: production_patterns
      title: "Production Patterns"
      tokens: 450
      next: [comparison, migration]
    - id: comparison
      title: "Comparison with REST & GraphQL"
      tokens: 250
      next: [migration, best_practices]
    - id: migration
      title: "Migration from REST"
      tokens: 300
      next: [best_practices]
    - id: best_practices
      title: "Best Practices & Performance"
      tokens: 400
---

## Summary

**tRPC** enables end-to-end type safety between TypeScript clients and servers without code generation. Define your API once, get automatic type inference everywhere.

**Key Benefits**: Zero codegen, TypeScript inference, React Query integration, minimal boilerplate.

---

## When to Use tRPC

**✅ Perfect For**:
- Full-stack TypeScript applications (Next.js, T3 stack)
- Projects where client and server share TypeScript codebase
- Teams wanting REST-like simplicity with GraphQL-like type safety
- Apps using React Query for data fetching
- Internal APIs where you control both client and server

**❌ Avoid When**:
- Public APIs consumed by non-TypeScript clients
- Microservices in different languages
- Mobile apps using Swift/Kotlin (use REST/GraphQL instead)
- Need API documentation for external developers (OpenAPI better)

**When to Choose**:
- **tRPC**: Full-stack TypeScript, monorepo, internal tools
- **REST**: Public APIs, language-agnostic, broad compatibility
- **GraphQL**: Complex data graphs, multiple clients, flexible queries

---

## Quick Start

### Installation

```bash
# Server dependencies
npm install @trpc/server zod

# React/Next.js client dependencies
npm install @trpc/client @trpc/react-query @tanstack/react-query
```

### Define Router (Server)

```typescript
// server/trpc.ts
import { initTRPC } from '@trpc/server';
import { z } from 'zod';

const t = initTRPC.create();

export const appRouter = t.router({
  hello: t.procedure
    .input(z.object({ name: z.string() }))
    .query(({ input }) => {
      return { greeting: `Hello ${input.name}` };
    }),

  createPost: t.procedure
    .input(z.object({ title: z.string(), content: z.string() }))
    .mutation(async ({ input }) => {
      // Save to database
      return { id: 1, ...input };
    }),
});

export type AppRouter = typeof appRouter;
```

### Use in Client (React)

```typescript
// client/trpc.ts
import { createTRPCReact } from '@trpc/react-query';
import type { AppRouter } from '../server/trpc';

export const trpc = createTRPCReact<AppRouter>();

// Component
function MyComponent() {
  const { data } = trpc.hello.useQuery({ name: 'World' });
  const createPost = trpc.createPost.useMutation();

  return <div>{data?.greeting}</div>; // Fully typed!
}
```

**Next**: Learn core concepts or dive into router definition.

---

## Core Concepts

### The tRPC Philosophy

tRPC provides **type-safe remote procedure calls** by sharing TypeScript types between client and server. No code generation—just TypeScript's inference.

### Key Components

1. **Router**: Collection of procedures (API endpoints)
2. **Procedure**: Single API operation (query or mutation)
3. **Context**: Request-scoped data (user, database, etc.)
4. **Middleware**: Intercept/modify requests (auth, logging)
5. **Input/Output**: Validated with Zod schemas

### Type Flow

```typescript
// Server defines types
const router = t.router({
  getUser: t.procedure
    .input(z.string())
    .query(({ input }) => ({ id: input, name: 'Alice' })),
});

// Client gets automatic types
const user = await trpc.getUser.query('123');
// user is typed as { id: string, name: string }
```

### Architecture Pattern

```
┌─────────────┐     Type-safe     ┌──────────────┐
│   Client    │ ←────────────────→ │    Server    │
│ (React)     │   No codegen!      │   (Node.js)  │
└─────────────┘                    └──────────────┘
      ↓                                    ↓
 React Query                          tRPC Router
 (caching)                            (procedures)
```

**Advantages**:
- Changes propagate instantly (no build step)
- Rename refactoring works across client/server
- Impossible to call wrong types
- Auto-complete for all API methods

---

## Router Definition

### Basic Router Structure

```typescript
import { initTRPC } from '@trpc/server';

const t = initTRPC.create();

export const appRouter = t.router({
  // Procedures go here
});

export type AppRouter = typeof appRouter;
```

### Nested Routers (Namespacing)

```typescript
const userRouter = t.router({
  getById: t.procedure
    .input(z.string())
    .query(({ input }) => getUser(input)),

  create: t.procedure
    .input(z.object({ name: z.string(), email: z.string() }))
    .mutation(({ input }) => createUser(input)),
});

const postRouter = t.router({
  list: t.procedure.query(() => getPosts()),
  create: t.procedure
    .input(z.object({ title: z.string() }))
    .mutation(({ input }) => createPost(input)),
});

export const appRouter = t.router({
  user: userRouter,
  post: postRouter,
});

// Client usage:
// trpc.user.getById.useQuery('123')
// trpc.post.list.useQuery()
```

### Router Merging

```typescript
import { adminRouter } from './admin';
import { publicRouter } from './public';

export const appRouter = t.mergeRouters(publicRouter, adminRouter);
```

### Router Organization Best Practices

```
server/
├── trpc.ts           # tRPC instance, context, middleware
├── routers/
│   ├── user.ts       # User-related procedures
│   ├── post.ts       # Post-related procedures
│   └── index.ts      # Combine all routers
└── index.ts          # Export AppRouter type
```

---

## Procedures (Query & Mutation)

### Query Procedures (Read Operations)

```typescript
const router = t.router({
  // Simple query
  getUser: t.procedure

Related in Web Dev