Usage with React
- If you're using Next.js, read the Usage with Next.js guide instead.
- In order to infer types from your Node.js backend, you should have the frontend and backend in the same monorepo.
Add tRPC to an existing React project
Server Side
1. Install dependencies
- npm
- yarn
- pnpm
bashnpm install @trpc/server zod
bashnpm install @trpc/server zod
bashyarn add @trpc/server zod
bashyarn add @trpc/server zod
bashpnpm add @trpc/server zod
bashpnpm add @trpc/server zod
Why Zod?
Zod is an input validator to ensure that our backend only processes requests that fit our API. You can use other validation libraries like Yup, Superstruct, io-ts if you prefer. In fact, any object containing a parse, create, or validateSync method will work.
2. Enable strict mode
If you want to use Zod for input validation, make sure you have enabled strict mode in your tsconfig.json:
tsconfig.jsondiff"compilerOptions": {+ "strict": true}
tsconfig.jsondiff"compilerOptions": {+ "strict": true}
If strict mode is too harsh, at least enable strictNullChecks:
tsconfig.jsondiff"compilerOptions": {+ "strictNullChecks": true}
tsconfig.jsondiff"compilerOptions": {+ "strictNullChecks": true}
3. Implement your appRouter
Follow the Quickstart to build your "hello world" router. Once you have your API implemented and listening via HTTP, you're ready to set up your React client.
Client Side
tRPC works great with Create React App!
1. Install dependencies
- npm
- yarn
- pnpm
bashnpm install @trpc/client @trpc/server @trpc/react-query @tanstack/react-query
bashnpm install @trpc/client @trpc/server @trpc/react-query @tanstack/react-query
bashyarn add @trpc/client @trpc/server @trpc/react-query @tanstack/react-query
bashyarn add @trpc/client @trpc/server @trpc/react-query @tanstack/react-query
bashpnpm add @trpc/client @trpc/server @trpc/react-query @tanstack/react-query
bashpnpm add @trpc/client @trpc/server @trpc/react-query @tanstack/react-query
Why @trpc/server?
@trpc/server is a peer dependency of @trpc/client so you will need to make sure that it is available on your client!
Why @tanstack/react-query?
@trpc/react-query provides a thin wrapper over @tanstack/react-query. It is required as a peer dependency.
2. Create tRPC hooks
Create a set of strongly-typed React hooks from your AppRouter type signature with createTRPCReact.
utils/trpc.tstsx// utils/trpc.tsimport { createTRPCReact } from '@trpc/react-query';import type { AppRouter } from '../path/to/router.ts';export const trpc = createTRPCReact<AppRouter>();
utils/trpc.tstsx// utils/trpc.tsimport { createTRPCReact } from '@trpc/react-query';import type { AppRouter } from '../path/to/router.ts';export const trpc = createTRPCReact<AppRouter>();
3. Add tRPC providers
App.tsxtsximport { QueryClient, QueryClientProvider } from '@tanstack/react-query';import { httpBatchLink } from '@trpc/client';import React, { useState } from 'react';import { trpc } from './utils/trpc';export function App() {const [queryClient] = useState(() => new QueryClient());const [trpcClient] = useState(() =>trpc.createClient({links: [httpBatchLink({url: 'http://localhost:5000/trpc',// optionalheaders() {return {authorization: getAuthCookie(),};},}),],}),);return (<trpc.Provider client={trpcClient} queryClient={queryClient}><QueryClientProvider client={queryClient}>{/* Your app here */}</QueryClientProvider></trpc.Provider>);}
App.tsxtsximport { QueryClient, QueryClientProvider } from '@tanstack/react-query';import { httpBatchLink } from '@trpc/client';import React, { useState } from 'react';import { trpc } from './utils/trpc';export function App() {const [queryClient] = useState(() => new QueryClient());const [trpcClient] = useState(() =>trpc.createClient({links: [httpBatchLink({url: 'http://localhost:5000/trpc',// optionalheaders() {return {authorization: getAuthCookie(),};},}),],}),);return (<trpc.Provider client={trpcClient} queryClient={queryClient}><QueryClientProvider client={queryClient}>{/* Your app here */}</QueryClientProvider></trpc.Provider>);}
4. Fetch data
pages/IndexPage.tsxtsximport { trpc } from '../utils/trpc';export default function IndexPage() {const hello = trpc.hello.useQuery({ text: 'client' });if (!hello.data) return <div>Loading...</div>;return (<div><p>{hello.data.greeting}</p></div>);}
pages/IndexPage.tsxtsximport { trpc } from '../utils/trpc';export default function IndexPage() {const hello = trpc.hello.useQuery({ text: 'client' });if (!hello.data) return <div>Loading...</div>;return (<div><p>{hello.data.greeting}</p></div>);}