Usage with React
info
- 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 & backend in the same monorepo.
Add tRPC to existing React project
Server Side
1. Install dependencies
bashyarn add @trpc/server zod
bashyarn add @trpc/server zod
- Zod: most examples use Zod for input validation and we highly recommended it, though it isn't required. You can use a validation library of your choice (Yup, Superstruct, io-ts, etc). In fact, any object containing a
parse,createorvalidateSyncmethod 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:
json// tsconfig.json{// ..."compilerOptions": {// ..."strict": true}}
json// tsconfig.json{// ..."compilerOptions": {// ..."strict": true}}
If strict mode is too much, at least enable strictNullChecks:
json// tsconfig.json{// ..."compilerOptions": {// ..."strictNullChecks": true}}
json// tsconfig.json{// ..."compilerOptions": {// ..."strictNullChecks": true}}
3. Implement your appRouter
Follow the Quickstart and read the @trpc/server docs for guidance on this. Once you have your API implemented and listening via HTTP, continue to the next step.
Client Side
tRPC works fine with Create React App!
1. Install dependencies
bashyarn add @trpc/client @trpc/server @trpc/react react-query@3
bashyarn add @trpc/client @trpc/server @trpc/react react-query@3
- @trpc/server: This is a peer dependency of
@trpc/clientso you have to install it again! - Tanstack's React Query: @trpc/react 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 createReactQueryHooks.
utils/trpc.tstsx// utils/trpc.tsimport { createReactQueryHooks } from '@trpc/react';import type { AppRouter } from '../path/to/router.ts';export const trpc = createReactQueryHooks<AppRouter>();// => { useQuery: ..., useMutation: ...}
utils/trpc.tstsx// utils/trpc.tsimport { createReactQueryHooks } from '@trpc/react';import type { AppRouter } from '../path/to/router.ts';export const trpc = createReactQueryHooks<AppRouter>();// => { useQuery: ..., useMutation: ...}
3. Add tRPC providers
In your App.tsx
App.tsxtsximport React from 'react';import { useState } from 'react';import { QueryClient, QueryClientProvider } from 'react-query';import { trpc } from './utils/trpc';export function App() {const [queryClient] = useState(() => new QueryClient());const [trpcClient] = useState(() =>trpc.createClient({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 React from 'react';import { useState } from 'react';import { QueryClient, QueryClientProvider } from 'react-query';import { trpc } from './utils/trpc';export function App() {const [queryClient] = useState(() => new QueryClient());const [trpcClient] = useState(() =>trpc.createClient({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.useQuery(['hello', { 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.useQuery(['hello', { text: 'client' }]);if (!hello.data) return <div>Loading...</div>;return (<div><p>{hello.data.greeting}</p></div>);}