Skip to main content
Version: 9.x

Usage with Express.js

Example app

DescriptionURLLinks
Express server & procedure calls with node.js.n/a

How to add tRPC to existing Express.js project

1. Install deps

bash
yarn add @trpc/server zod
bash
yarn add @trpc/server zod

Zod isn't a required dependency, but it's used in the sample router below.

2. Create a tRPC router

Implement your tRPC router. A sample router is given below:

server.ts
ts
import * as trpc from '@trpc/server';
import { z } from 'zod';
const appRouter = trpc
.router()
.query('getUser', {
input: z.string(),
async resolve(req) {
req.input; // string
return { id: req.input, name: 'Bilbo' };
},
})
.mutation('createUser', {
// validate input with Zod
input: z.object({ name: z.string().min(5) }),
async resolve(req) {
// use your ORM of choice
return await UserModel.create({
data: req.input,
});
},
});
// export type definition of API
export type AppRouter = typeof appRouter;
server.ts
ts
import * as trpc from '@trpc/server';
import { z } from 'zod';
const appRouter = trpc
.router()
.query('getUser', {
input: z.string(),
async resolve(req) {
req.input; // string
return { id: req.input, name: 'Bilbo' };
},
})
.mutation('createUser', {
// validate input with Zod
input: z.object({ name: z.string().min(5) }),
async resolve(req) {
// use your ORM of choice
return await UserModel.create({
data: req.input,
});
},
});
// export type definition of API
export type AppRouter = typeof appRouter;

If your router file starts getting too big, split your router into several subrouters each implemented in its own file. Then merge them into a single root appRouter.

3. Use the Express.js adapter

tRPC includes an adapter for Express.js out of the box. This adapter lets you convert your tRPC router into an Express.js middleware.

server.ts
ts
import * as trpcExpress from '@trpc/server/adapters/express';
const appRouter = /* ... */;
const app = express();
// created for each request
const createContext = ({
req,
res,
}: trpcExpress.CreateExpressContextOptions) => ({}) // no context
type Context = trpc.inferAsyncReturnType<typeof createContext>;
app.use(
'/trpc',
trpcExpress.createExpressMiddleware({
router: appRouter,
createContext,
})
);
app.listen(4000);
server.ts
ts
import * as trpcExpress from '@trpc/server/adapters/express';
const appRouter = /* ... */;
const app = express();
// created for each request
const createContext = ({
req,
res,
}: trpcExpress.CreateExpressContextOptions) => ({}) // no context
type Context = trpc.inferAsyncReturnType<typeof createContext>;
app.use(
'/trpc',
trpcExpress.createExpressMiddleware({
router: appRouter,
createContext,
})
);
app.listen(4000);

Your endpoints are now available via HTTP!

EndpointHTTP URI
getUserGET http://localhost:4000/trpc/getUser?input=INPUT

where INPUT is a URI-encoded JSON string.
createUserPOST http://localhost:4000/trpc/createUser

with req.body of type {name: string}