Skip to main content

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 & backend in the same monorepo.

Add tRPC to existing React project

Server Side

1. Install dependencies

yarn 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, 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.json
// ...
"compilerOptions": {
// ...
"strict": true

If strict mode is too much, at least enable strictNullChecks:

// 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

yarn add @trpc/client @trpc/server @trpc/react react-query
  • @trpc/server: This is a peer dependency of @trpc/client so you have to install it again!
  • React Query: @trpc/react provides a thin wrapper over 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.ts
import { 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

import 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(() =>
url: 'http://localhost:5000/trpc',

// optional
headers() {
return {
authorization: getAuthCookie(),
return (
<trpc.Provider client={trpcClient} queryClient={queryClient}>
<QueryClientProvider client={queryClient}>
{/* Your app here */}

4. Fetch data

import { trpc } from '../utils/trpc';

export default function IndexPage() {
const hello = trpc.useQuery(['hello', { text: 'client' }]);
if (! return <div>Loading...</div>;
return (