Skip to main content
Version: 10.x

Define Routers

To begin building your tRPC-based API, you'll first need to define your router. Once you've mastered the fundamentals, you can customize your routers for more advanced use cases.

Initialize tRPC

You should initialize tRPC exactly once per application. Multiple instances of tRPC will cause issues.

server/trpc.ts
ts
import { initTRPC } from '@trpc/server';
 
// You can use any variable name you like.
// We use t to keep things simple.
const t = initTRPC.create();
 
export const router = t.router;
export const middleware = t.middleware;
export const publicProcedure = t.procedure;
server/trpc.ts
ts
import { initTRPC } from '@trpc/server';
 
// You can use any variable name you like.
// We use t to keep things simple.
const t = initTRPC.create();
 
export const router = t.router;
export const middleware = t.middleware;
export const publicProcedure = t.procedure;

You'll notice we are exporting certain methods of the t variable here rather than t itself. This is to establish a certain set of procedures that we will use idiomatically in our codebase.

Defining a router

Next, let's define a router with a procedure to use in our application. We are now exposing an API "endpoint."

server/_app.ts
ts
import * as trpc from '@trpc/server';
import { publicProcedure, router } from './trpc';
 
const appRouter = router({
greeting: publicProcedure.query(() => 'hello tRPC v10!'),
});
 
// Export only the type of a router!
// This prevents us from importing server code on the client.
export type AppRouter = typeof appRouter;
server/_app.ts
ts
import * as trpc from '@trpc/server';
import { publicProcedure, router } from './trpc';
 
const appRouter = router({
greeting: publicProcedure.query(() => 'hello tRPC v10!'),
});
 
// Export only the type of a router!
// This prevents us from importing server code on the client.
export type AppRouter = typeof appRouter;

Advanced usage

When initializing your router, tRPC allows you to:

You can use method chaining to customize your t-object on initialization. For example:

ts
const t = initTRPC.context<Context>().meta<Meta>().create({
/* [...] */
});
ts
const t = initTRPC.context<Context>().meta<Meta>().create({
/* [...] */
});

Runtime Configuration

ts
export interface RuntimeConfig<TTypes extends RootConfigTypes> {
/**
* Use a data transformer
* @link https://trpc.io/docs/data-transformers
*/
transformer: TTypes['transformer'];
/**
* Use custom error formatting
* @link https://trpc.io/docs/error-formatting
*/
errorFormatter: ErrorFormatter<TTypes['ctx'], any>;
/**
* Allow `@trpc/server` to run in non-server environments
* @warning **Use with caution**, this should likely mainly be used within testing.
* @default false
*/
allowOutsideOfServer: boolean;
/**
* Is this a server environment?
* @warning **Use with caution**, this should likely mainly be used within testing.
* @default typeof window === 'undefined' || 'Deno' in window || process.env.NODE_ENV === 'test'
*/
isServer: boolean;
/**
* Is this development?
* Will be used to decide if the API should return stack traces
* @default process.env.NODE_ENV !== 'production'
*/
isDev: boolean;
}
ts
export interface RuntimeConfig<TTypes extends RootConfigTypes> {
/**
* Use a data transformer
* @link https://trpc.io/docs/data-transformers
*/
transformer: TTypes['transformer'];
/**
* Use custom error formatting
* @link https://trpc.io/docs/error-formatting
*/
errorFormatter: ErrorFormatter<TTypes['ctx'], any>;
/**
* Allow `@trpc/server` to run in non-server environments
* @warning **Use with caution**, this should likely mainly be used within testing.
* @default false
*/
allowOutsideOfServer: boolean;
/**
* Is this a server environment?
* @warning **Use with caution**, this should likely mainly be used within testing.
* @default typeof window === 'undefined' || 'Deno' in window || process.env.NODE_ENV === 'test'
*/
isServer: boolean;
/**
* Is this development?
* Will be used to decide if the API should return stack traces
* @default process.env.NODE_ENV !== 'production'
*/
isDev: boolean;
}