Skip to content
tRPC

Set up a tRPC Client

On this page

1. Install the tRPC Client library

Use your preferred package manager to install the @trpc/client library, and also install @trpc/server which contains some required types.

pnpm add @trpc/server @trpc/client
npm install @trpc/server @trpc/client
yarn add @trpc/server @trpc/client
bun add @trpc/server @trpc/client

2. Import your App Router

Import your AppRouter type into the client application. This type holds the shape of your entire API.

utils/trpc.ts
import type { 
type AppRouter = Router<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        byId: QueryProcedure<{
            input: {
                id: string;
            };
            output: {
                id: string;
                title: string;
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>> & DecorateCreateRouterOptions<{
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        byId: QueryProcedure<{
            input: {
                id: string;
            };
            output: {
                id: string;
                title: string;
            };
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
}>
AppRouter
} from '../server/router';

3. Initialize the tRPC client

Create a tRPC client with the createTRPCClient method, and add a links array with a terminating link pointing at your API. To learn more about tRPC links, click here.

client.ts
import { function createTRPCClient<TRouter extends AnyRouter>(opts: CreateTRPCClientOptions<TRouter>): TRPCClient<TRouter>createTRPCClient, function httpBatchLink<TRouter extends AnyRouter>(opts: HTTPBatchLinkOptions<TRouter["_def"]["_config"]["$types"]>): TRPCLink<TRouter>httpBatchLink } from '@trpc/client';
import type { 
type AppRouter = Router<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{}>> & DecorateCreateRouterOptions<{}>
AppRouter
} from './server';
const
const client: TRPCClient<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{}>>>
client
=
createTRPCClient<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{}>>>(opts: CreateTRPCClientOptions<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{}>>>): TRPCClient<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<...>>>
createTRPCClient
<
type AppRouter = Router<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{}>> & DecorateCreateRouterOptions<{}>
AppRouter
>({
links: TRPCLink<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{}>>>[]
links
: [
httpBatchLink<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{}>>>(opts: HTTPBatchLinkOptions<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}>): TRPCLink<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{}>>>
httpBatchLink
({
url: string | URLurl: 'http://localhost:3000/trpc', // You can pass any HTTP headers you wish here async
headers?: HTTPHeaders | ((opts: {
    opList: NonEmptyArray<Operation>;
}) => HTTPHeaders | Promise<HTTPHeaders>) | undefined
headers
() {
return { authorization: stringauthorization: function getAuthCookie(): stringgetAuthCookie(), }; }, }), ], });

4. Use the tRPC Client

Under the hood this creates a typed JavaScript Proxy which allows you to interact with your tRPC API in a fully type-safe way:

client.ts
const 
const bilbo: {
    id: string;
    name: string;
}
bilbo
= await
const client: TRPCClient<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    getUser: QueryProcedure<{
        input: string;
        output: {
            id: string;
            name: string;
        };
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    createUser: MutationProcedure<{
        input: {
            name: string;
        };
        output: {
            name: string;
            id: string;
        };
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>>
client
.
getUser: {
    query: Resolver<{
        input: string;
        output: {
            id: string;
            name: string;
        };
        errorShape: DefaultErrorShape;
        transformer: false;
    }>;
}
getUser
.
query: (input: string, opts?: TRPCProcedureOptions) => TRPCTaggedPromise<{
    id: string;
    name: string;
}, DefaultErrorShape>
query
('id_bilbo');
// => { id: 'id_bilbo', name: 'Bilbo' }; const
const frodo: {
    name: string;
    id: string;
}
frodo
= await
const client: TRPCClient<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    getUser: QueryProcedure<{
        input: string;
        output: {
            id: string;
            name: string;
        };
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    createUser: MutationProcedure<{
        input: {
            name: string;
        };
        output: {
            name: string;
            id: string;
        };
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>>
client
.
createUser: {
    mutate: Resolver<{
        input: {
            name: string;
        };
        output: {
            name: string;
            id: string;
        };
        errorShape: DefaultErrorShape;
        transformer: false;
    }>;
}
createUser
.
mutate: (input: {
    name: string;
}, opts?: TRPCProcedureOptions) => TRPCTaggedPromise<{
    name: string;
    id: string;
}, DefaultErrorShape>
mutate
({ name: stringname: 'Frodo' });
// => { id: 'id_frodo', name: 'Frodo' };

You're all set!