Skip to content
tRPC

Merging Routers

On this page

Writing all API-code in the same file can become unwieldy. It's easy to merge routers together in order to break them up.

Merging with child routers

routers/user.ts
import { 
const router: RouterBuilder<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}>
router
, const publicProcedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>publicProcedure } from '../trpc';
import { import zz } from 'zod'; export const
const userRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    list: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
userRouter
=
router<{
    list: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>(_: {
    list: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}): BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    list: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
router
({
list: QueryProcedure<{
    input: void;
    output: never[];
    meta: object;
    errorShape: DefaultErrorShape;
}>
list
: const publicProcedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>publicProcedure.
ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.query<never[]>(resolver: ProcedureResolver<object, object, object, UnsetMarker, UnsetMarker, never[]>): QueryProcedure<{
    input: void;
    output: never[];
    meta: object;
    errorShape: DefaultErrorShape;
}>
query
(() => {
// [..] return []; }), });
routers/post.ts
import { 
const router: RouterBuilder<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}>
router
, const publicProcedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>publicProcedure } from '../trpc';
import { import zz } from 'zod'; export const
const postRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    create: MutationProcedure<{
        input: {
            title: string;
        };
        output: void;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    list: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
postRouter
=
router<{
    create: MutationProcedure<{
        input: {
            title: string;
        };
        output: void;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    list: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>(_: {
    create: MutationProcedure<{
        input: {
            title: string;
        };
        output: void;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    list: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}): BuiltRouter<...>
router
({
create: MutationProcedure<{
    input: {
        title: string;
    };
    output: void;
    meta: object;
    errorShape: DefaultErrorShape;
}>
create
: const publicProcedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>publicProcedure
.
ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.input<z.ZodObject<{
    title: z.ZodString;
}, z.core.$strip>>(schema: z.ZodObject<{
    title: z.ZodString;
}, z.core.$strip>): ProcedureBuilder<object, object, object, {
    title: string;
}, {
    title: string;
}, UnsetMarker, UnsetMarker, false, DefaultErrorShape>
input
(
import zz.
function object<{
    title: z.ZodString;
}>(shape?: {
    title: z.ZodString;
} | undefined, params?: string | {
    error?: string | z.core.$ZodErrorMap<NonNullable<z.core.$ZodIssueUnrecognizedKeys | z.core.$ZodIssueInvalidType<unknown>>> | undefined;
    message?: string | undefined | undefined;
} | undefined): z.ZodObject<{
    title: z.ZodString;
}, z.core.$strip>
object
({
title: z.ZodStringtitle: import zz.function string(params?: string | z.core.$ZodStringParams): z.ZodString (+1 overload)string(), }), ) .
ProcedureBuilder<object, object, object, { title: string; }, { title: string; }, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.mutation<void>(resolver: ProcedureResolver<object, object, object, {
    title: string;
}, UnsetMarker, void>): MutationProcedure<{
    input: {
        title: string;
    };
    output: void;
    meta: object;
    errorShape: DefaultErrorShape;
}>
mutation
((
opts: ProcedureResolverOptions<object, object, object, {
    title: string;
}>
opts
) => {
const {
const input: {
    title: string;
}
input
} =
opts: ProcedureResolverOptions<object, object, object, {
    title: string;
}>
opts
;
// [...] }),
list: QueryProcedure<{
    input: void;
    output: never[];
    meta: object;
    errorShape: DefaultErrorShape;
}>
list
: const publicProcedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>publicProcedure.
ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.query<never[]>(resolver: ProcedureResolver<object, object, object, UnsetMarker, UnsetMarker, never[]>): QueryProcedure<{
    input: void;
    output: never[];
    meta: object;
    errorShape: DefaultErrorShape;
}>
query
(() => {
// ... return []; }), });
routers/_app.ts
import { 
const router: RouterBuilder<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}>
router
} from '../trpc';
import {
const userRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    list: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
userRouter
} from './user';
import {
const postRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    create: MutationProcedure<{
        input: {
            title: string;
        };
        output: void;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    list: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
postRouter
} from './post';
const
const appRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    user: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        list: QueryProcedure<{
            input: void;
            output: never[];
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        create: MutationProcedure<{
            input: {
                title: string;
            };
            output: void;
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
        list: QueryProcedure<...>;
    }>>;
}>>
appRouter
=
router<{
    user: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        list: QueryProcedure<{
            input: void;
            output: never[];
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        create: MutationProcedure<{
            input: {
                title: string;
            };
            output: void;
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
        list: QueryProcedure<...>;
    }>>;
}>(_: {
    user: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        list: QueryProcedure<{
            input: void;
            output: never[];
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        create: MutationProcedure<{
            input: {
                title: string;
            };
            output: void;
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
        list: QueryProcedure<...>;
    }>>;
}): BuiltRouter<...>
router
({
user: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    list: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
user
:
const userRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    list: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
userRouter
,
post: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    create: MutationProcedure<{
        input: {
            title: string;
        };
        output: void;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    list: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
post
:
const postRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    create: MutationProcedure<{
        input: {
            title: string;
        };
        output: void;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    list: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
postRouter
,
});
const appRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    user: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        list: QueryProcedure<{
            input: void;
            output: never[];
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        create: MutationProcedure<{
            input: {
                title: string;
            };
            output: void;
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
        list: QueryProcedure<...>;
    }>>;
}>>
appRouter
.user
user: DecorateCreateRouterOptions<{
    list: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>
const appRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    user: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        list: QueryProcedure<{
            input: void;
            output: never[];
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        create: MutationProcedure<{
            input: {
                title: string;
            };
            output: void;
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
        list: QueryProcedure<...>;
    }>>;
}>>
appRouter
.post
post: DecorateCreateRouterOptions<{
    create: MutationProcedure<{
        input: {
            title: string;
        };
        output: void;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    list: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>
export type
type AppRouter = Router<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    user: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        list: QueryProcedure<{
            input: void;
            output: never[];
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        create: MutationProcedure<{
            input: {
                title: string;
            };
            output: void;
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
        list: QueryProcedure<...>;
    }>>;
}>> & DecorateCreateRouterOptions<...>
AppRouter
= typeof
const appRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    user: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        list: QueryProcedure<{
            input: void;
            output: never[];
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>;
    post: BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        create: MutationProcedure<{
            input: {
                title: string;
            };
            output: void;
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
        list: QueryProcedure<...>;
    }>>;
}>>
appRouter
;

Merging with t.mergeRouters

If you prefer having all procedures flat in one single namespace, you can instead use t.mergeRouters

routers/user.ts
import { 
const router: RouterBuilder<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}>
router
, const publicProcedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>publicProcedure } from '../trpc';
import { import zz } from 'zod'; export const
const userRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    userList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
userRouter
=
router<{
    userList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>(_: {
    userList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}): BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    userList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
router
({
userList: QueryProcedure<{
    input: void;
    output: never[];
    meta: object;
    errorShape: DefaultErrorShape;
}>
userList
: const publicProcedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>publicProcedure.
ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.query<never[]>(resolver: ProcedureResolver<object, object, object, UnsetMarker, UnsetMarker, never[]>): QueryProcedure<{
    input: void;
    output: never[];
    meta: object;
    errorShape: DefaultErrorShape;
}>
query
(() => {
// [..] return []; }), });
routers/post.ts
import { 
const router: RouterBuilder<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}>
router
, const publicProcedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>publicProcedure } from '../trpc';
import { import zz } from 'zod'; export const
const postRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    postCreate: MutationProcedure<{
        input: {
            title: string;
        };
        output: void;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    postList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
postRouter
=
router<{
    postCreate: MutationProcedure<{
        input: {
            title: string;
        };
        output: void;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    postList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>(_: {
    postCreate: MutationProcedure<{
        input: {
            title: string;
        };
        output: void;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    postList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}): BuiltRouter<...>
router
({
postCreate: MutationProcedure<{
    input: {
        title: string;
    };
    output: void;
    meta: object;
    errorShape: DefaultErrorShape;
}>
postCreate
: const publicProcedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>publicProcedure
.
ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.input<z.ZodObject<{
    title: z.ZodString;
}, z.core.$strip>>(schema: z.ZodObject<{
    title: z.ZodString;
}, z.core.$strip>): ProcedureBuilder<object, object, object, {
    title: string;
}, {
    title: string;
}, UnsetMarker, UnsetMarker, false, DefaultErrorShape>
input
(
import zz.
function object<{
    title: z.ZodString;
}>(shape?: {
    title: z.ZodString;
} | undefined, params?: string | {
    error?: string | z.core.$ZodErrorMap<NonNullable<z.core.$ZodIssueUnrecognizedKeys | z.core.$ZodIssueInvalidType<unknown>>> | undefined;
    message?: string | undefined | undefined;
} | undefined): z.ZodObject<{
    title: z.ZodString;
}, z.core.$strip>
object
({
title: z.ZodStringtitle: import zz.function string(params?: string | z.core.$ZodStringParams): z.ZodString (+1 overload)string(), }), ) .
ProcedureBuilder<object, object, object, { title: string; }, { title: string; }, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.mutation<void>(resolver: ProcedureResolver<object, object, object, {
    title: string;
}, UnsetMarker, void>): MutationProcedure<{
    input: {
        title: string;
    };
    output: void;
    meta: object;
    errorShape: DefaultErrorShape;
}>
mutation
((
opts: ProcedureResolverOptions<object, object, object, {
    title: string;
}>
opts
) => {
const {
const input: {
    title: string;
}
input
} =
opts: ProcedureResolverOptions<object, object, object, {
    title: string;
}>
opts
;
// [...] }),
postList: QueryProcedure<{
    input: void;
    output: never[];
    meta: object;
    errorShape: DefaultErrorShape;
}>
postList
: const publicProcedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>publicProcedure.
ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.query<never[]>(resolver: ProcedureResolver<object, object, object, UnsetMarker, UnsetMarker, never[]>): QueryProcedure<{
    input: void;
    output: never[];
    meta: object;
    errorShape: DefaultErrorShape;
}>
query
(() => {
// ... return []; }), });
routers/_app.ts
import { const mergeRouters: <TRouters extends AnyRouter[]>(...routerList: TRouters) => MergeRouters<TRouters>mergeRouters } from '../trpc';

import { 
const userRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    userList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
userRouter
} from './user';
import {
const postRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    postCreate: MutationProcedure<{
        input: {
            title: string;
        };
        output: void;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    postList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
postRouter
} from './post';
const appRouter =
mergeRouters<[BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    userList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>, BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    postCreate: MutationProcedure<{
        input: {
            title: string;
        };
        output: void;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    postList: QueryProcedure<...>;
}>>]>(routerList_0: BuiltRouter<...>, routerList_1: BuiltRouter<...>): BuiltRouter<...>
mergeRouters
(
const userRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    userList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
userRouter
,
const postRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    postCreate: MutationProcedure<{
        input: {
            title: string;
        };
        output: void;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    postList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
postRouter
);
const appRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    postCreate: MutationProcedure<{
        input: {
            title: string;
        };
        output: void;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    postList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}> & DecorateCreateRouterOptions<{
    userList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
export type
type AppRouter = Router<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    postCreate: MutationProcedure<{
        input: {
            title: string;
        };
        output: void;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    postList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}> & DecorateCreateRouterOptions<{
    userList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>> & DecorateCreateRouterOptions<...> & DecorateCreateRouterOptions<...>
AppRouter
= typeof
const appRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    postCreate: MutationProcedure<{
        input: {
            title: string;
        };
        output: void;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
    postList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}> & DecorateCreateRouterOptions<{
    userList: QueryProcedure<{
        input: void;
        output: never[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
appRouter
;

Dynamically load routers

You can use the lazy function to dynamically load your routers. This can be useful to reduce cold starts of your application. There's no difference in how you use the router after it's been lazy loaded vs. how you use a normal router.

routers/greeting.ts
import { 
const router: RouterBuilder<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}>
router
, const publicProcedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>publicProcedure } from '../trpc';
export const
const greetingRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    hello: QueryProcedure<{
        input: void;
        output: string;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
greetingRouter
=
router<{
    hello: QueryProcedure<{
        input: void;
        output: string;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>(_: {
    hello: QueryProcedure<{
        input: void;
        output: string;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}): BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    hello: QueryProcedure<{
        input: void;
        output: string;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
router
({
hello: QueryProcedure<{
    input: void;
    output: string;
    meta: object;
    errorShape: DefaultErrorShape;
}>
hello
: const publicProcedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>publicProcedure.
ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.query<string>(resolver: ProcedureResolver<object, object, object, UnsetMarker, UnsetMarker, string>): QueryProcedure<{
    input: void;
    output: string;
    meta: object;
    errorShape: DefaultErrorShape;
}>
query
(() => 'world'),
});
routers/user.ts
import { 
const router: RouterBuilder<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}>
router
, const publicProcedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>publicProcedure } from '../trpc';
export const
const userRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    list: QueryProcedure<{
        input: void;
        output: string[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
userRouter
=
router<{
    list: QueryProcedure<{
        input: void;
        output: string[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>(_: {
    list: QueryProcedure<{
        input: void;
        output: string[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}): BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    list: QueryProcedure<{
        input: void;
        output: string[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
router
({
list: QueryProcedure<{
    input: void;
    output: string[];
    meta: object;
    errorShape: DefaultErrorShape;
}>
list
: const publicProcedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>publicProcedure.
ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.query<string[]>(resolver: ProcedureResolver<object, object, object, UnsetMarker, UnsetMarker, string[]>): QueryProcedure<{
    input: void;
    output: string[];
    meta: object;
    errorShape: DefaultErrorShape;
}>
query
(() => ['John', 'Jane', 'Jim']),
});
routers/_app.ts
import { 
function lazy<TRouter extends AnyRouter>(importRouter: () => Promise<TRouter | {
    [key: string]: TRouter;
}>): Lazy<NoInfer<TRouter>>
lazy
} from '@trpc/server';
import {
const router: RouterBuilder<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}>
router
} from '../trpc';
export const
const appRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    greeting: () => Promise<NoInfer<BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        hello: QueryProcedure<{
            input: void;
            output: string;
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>>>;
    user: () => Promise<NoInfer<BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<...>>>>;
}>>
appRouter
=
router<{
    greeting: () => Promise<NoInfer<BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        hello: QueryProcedure<{
            input: void;
            output: string;
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>>>;
    user: () => Promise<NoInfer<BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        list: QueryProcedure<{
            input: void;
            output: string[];
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>>>;
}>(_: {
    greeting: () => Promise<NoInfer<BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        hello: QueryProcedure<{
            input: void;
            output: string;
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>>>;
    user: () => Promise<NoInfer<BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        list: QueryProcedure<{
            input: void;
            output: string[];
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>>>;
}): BuiltRouter<...>
router
({
// Option 1: Short-hand when the module has exactly 1 router exported
greeting: () => Promise<NoInfer<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    hello: QueryProcedure<{
        input: void;
        output: string;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>>>
greeting
:
lazy<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    hello: QueryProcedure<{
        input: void;
        output: string;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>>(importRouter: () => Promise<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    hello: QueryProcedure<{
        input: void;
        output: string;
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>> | {
    ...;
}>): () => Promise<...>
lazy
(() => import('./greeting.js')),
// Option 2: if exporting more than 1 router
user: () => Promise<NoInfer<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    list: QueryProcedure<{
        input: void;
        output: string[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>>>
user
:
lazy<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    list: QueryProcedure<{
        input: void;
        output: string[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>>(importRouter: () => Promise<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    list: QueryProcedure<{
        input: void;
        output: string[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>> | {
    ...;
}>): () => Promise<...>
lazy
(() => import('./user.js').
Promise<typeof import("./user.js")>.then<BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    list: QueryProcedure<{
        input: void;
        output: string[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>, {
    [key: string]: never;
}>(onfulfilled?: ((value: typeof import("./user.js")) => BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    list: QueryProcedure<{
        input: void;
        output: string[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>> | PromiseLike<...>) | null | undefined, onrejected?: ((reason: any) => {
    [key: string]: never;
} | PromiseLike<...>) | ... 1 more ... | undefined): Promise<...>
then
((m: typeof import("./user.js")m) => m: typeof import("./user.js")m.
const userRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    list: QueryProcedure<{
        input: void;
        output: string[];
        meta: object;
        errorShape: DefaultErrorShape;
    }>;
}>>
userRouter
)),
}); export type
type AppRouter = Router<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    greeting: () => Promise<NoInfer<BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        hello: QueryProcedure<{
            input: void;
            output: string;
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>>>;
    user: () => Promise<NoInfer<BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<...>>>>;
}>> & DecorateCreateRouterOptions<...>
AppRouter
= typeof
const appRouter: BuiltRouter<{
    ctx: object;
    meta: object;
    errorShape: DefaultErrorShape;
    transformer: false;
}, DecorateCreateRouterOptions<{
    greeting: () => Promise<NoInfer<BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<{
        hello: QueryProcedure<{
            input: void;
            output: string;
            meta: object;
            errorShape: DefaultErrorShape;
        }>;
    }>>>>;
    user: () => Promise<NoInfer<BuiltRouter<{
        ctx: object;
        meta: object;
        errorShape: DefaultErrorShape;
        transformer: false;
    }, DecorateCreateRouterOptions<...>>>>;
}>>
appRouter
;