rembrembdocs

tip

We highly encourage you to check out the Example Apps to get a feel of tRPC and getting up & running as seamless as possible.

Installation

⚠️ Requirements: tRPC requires TypeScript > 4.1 as it relies on Template Literal Types.

npm install @trpc/server

For implementing tRPC endpoints and routers. Install in your server codebase.

npm install @trpc/client @trpc/server

For making typesafe API calls from your client. Install in your client codebase (@trpc/server is a peer dependency of @trpc/client).

npm install @trpc/react react-query@3

For generating a powerful set of React hooks for querying your tRPC API. Powered by react-query.

npm install @trpc/next

A set of utilities for integrating tRPC with Next.js.

Installation Snippets

npm:

bash

npm install @trpc/server @trpc/client @trpc/react react-query@3 @trpc/next

yarn:

bash

yarn add @trpc/server @trpc/client @trpc/react react-query@3 @trpc/next

Defining a router

Let's walk through the steps of building a typesafe API with tRPC. To start, this API will only contain two endpoints:

ts

getUser(id: string) => { id: string; name: string; }

createUser(data: {name:string}) => { id: string; name: string; }

Create a router instance

First we define a router somewhere in our server codebase:

server.ts

ts

import * as trpc from '@trpc/server';

const appRouter = trpc.router();

// only export *type signature* of router!

// to avoid accidentally importing your API

// into client-side code

export type AppRouter = typeof appRouter;

Add a query endpoint

Use the .query() method to add a query endpoint to the router. Arguments:

.query(name: string, params: QueryParams)

server.ts

ts

import * as trpc from '@trpc/server';

const appRouter = trpc.router().query('getUser', {

input: (val: unknown) => {

`if (typeof val === 'string') return val;`

``throw new Error(`Invalid input: ${typeof val}`);``

},

async resolve(req) {

`req.input; // string`

`return { id: req.input, name: 'Bilbo' };`

},

});

export type AppRouter = typeof appRouter;

Add a mutation endpoint

Similarly to GraphQL, tRPC makes a distinction between query and mutation endpoints. Let's add a createUser mutation:

ts

createUser(payload: {name: string}) => {id: string; name: string};

server.ts

ts

import * as trpc from '@trpc/server';

import { z } from 'zod';

const appRouter = trpc

.router()

.query('getUser', {

`input: (val: unknown) => {`

  `if (typeof val === 'string') return val;`

  ``throw new Error(`Invalid input: ${typeof val}`);``

`},`

`async resolve(req) {`

  `req.input; // string`

  `return { id: req.input, name: 'Bilbo' };`

`},`

})

.mutation('createUser', {

`// validate input with Zod`

`input: z.object({ name: z.string().min(5) }),`

`async resolve(req) {`

  `// use your ORM of choice`

  `return await UserModel.create({`

    `data: req.input,`

  `});`

`},`

});

export type AppRouter = typeof appRouter;

Next steps

tRPC includes more sophisticated client-side tooling designed for React projects generally and Next.js specifically. Read the appropriate guide next: