When we build full-stack TypeScript apps that comprise a RESTful API and a frontend, it becomes challenging to statically type the API endpoints and share the types between the server and client.
Before the release of tRPC, GraphQL was the dominant library for building totally type-safe applications. This approach works amazing but we have to depend on code generation and extra dependencies for it to work.
In addition to the complexities associated with GraphQL, we still have to maintain the schemas defined on the backend and install extra dependencies to smoothen the process.
This article will teach you how to set up a tRPC API server and client with Next.js, PostgreSQL, React Query, Prisma, Redis, and Docker-compose.
tRPC API Server and Client with Next.js, PostgreSQL, and Prisma
- How to Setup tRPC API Server & Client with Next.js and Prisma
- Build tRPC API with Next.js & PostgreSQL: Access & Refresh Tokens
- Full-Stack Next.js tRPC App: User Registration & Login Example
- Build a tRPC CRUD API Example with Next.js
Related articles:
- Build tRPC API with React.js, Node.js & MongoDB: Project Setup
- Build tRPC API with React.js & Node.js: Access and Refresh Tokens
- Full-Stack App tRPC, React.js, & Node.js: JWT Authentication
- Build Full-Stack tRPC CRUD Application with Node.js, and React.js

Prerequisites
Before going further, you should:
- Have Node.js installed on your PC
- Have basic knowledge of JavaScript and TypeScript
- Have basic knowledge of SQL, how to use pgAdmin and how ORMs work
- Be comfortable with React.js and TailwindCss
What you will learn
- How to create a PostgreSQL database with Docker and Docker-compose
- Data modeling with Prisma
- How to create a simple tRPC server with Next.js
- How to use Next.js as a monolithic repository
- How to make tRPC requests with Next.js
Step 1 – Setup Next.js as a Monolithic Repository
In this section, you will generate a simple Next.js boilerplate application with the Next.js scaffolding tool and make some tweaks to convert the project to a monorepo.
In this example, you can name your project trpc-nextjs
.
Once the project has been generated, change the directory into it in the terminal and open it with your preferred text editor (VS Code):
Create an src folder and move the pages
, styles
and public
folders into it. Once that is done, your src folder structure should look somewhat like this:
src/
├── pages/
│ ├── api/
│ │ └── hello.ts
│ ├── index.tsx
│ └── _app.tsx
├── public/
│ ├── favicon.ico
│ └── vercel.svg
└── styles/
├── globals.css
└── Home.module.css
If you are contemplating why we moved the folders into a newly-created src folder, don’t worry since Next.js supports it. This will make your project easier to use and maintain throughout its life cycle.
After that, open the tsconfig.json
file and replace its content with the following configurations recommended by the tRPC team.
tsconfig.json
Now run yarn dev
or npm run dev
to start the Next.js development server and open the URL in the browser to make sure everything is working correctly.
Step 2 – Setup Redis and PostgreSQL with Docker
In this step, you will set up Redis and PostgreSQL servers with Docker and Docker-compose. To do that, you will create a docker-compose.yml
file and add the Docker-compose configurations needed to start the Redis and PostgreSQL Docker containers.
Adding the Docker-compose Configurations
Now create a docker-compose.yml
file in the project folder and add the following configurations:
docker-compose.yml
Adding the PostgreSQL Docker Image Credentials
Here, you will add the credentials required by the PostgreSQL Docker image to a .env
file. This file will contain the Postgres user, database name, Postgres password, and Postgres host.
Create a .env
file in the project folder and add the following environment variables.
.env
Starting the Redis and PostgreSQL Docker Containers
In this section, you will start the Redis and PostgreSQL Docker containers. To do that, open your terminal and run the following command:
You can run docker ps
to see the running Docker containers in the terminal.
Also, you can stop the containers with this command:
Step 3 – Setup Prisma with PostgreSQL
Prisma is an ORM used mostly in Node.js projects to query and mutate either SQL or NoSQL databases.
Now let’s install the Prisma client and CLI tool with the following command:
Then initialize a new Prisma project with this command:
The above command will generate a prisma
folder containing a schema.prisma
file in the root project folder.
Also, the Prisma CLI will add the database URL to the .env
file. Open the .env
file and update the DATABASE_URL
added by the Prisma CLI with the PostgreSQL credentials.
.env
Creating the Database Models with Prisma
For testing purposes, let’s create a simple model with Prisma. In the next tutorial, we will add more complex models to help us implement JWT authentication with Next.js.
In the above code, we created a User
model and used the @@map(name: "users")
Prisma attribute to change the table name in the SQL code.
Also, we added an ID and name columns to the users
table. The @default(uuid())
Prisma attribute sets a default UUID value for the ID column in the Postgres database.
Migrating the Prisma Schema to the PostgreSQL Database
The Prisma CLI provides us with an imperative database schema migration tool that will enable us to:
- Keep the Prisma schema in sync with the database schema
- Maintain existing data in the database
Open the package.json
file and add the following Prisma scripts:
package.json
--name
– sets the name of the migration file. Feel free to change the migration name.--create-only
– this command creates the migration without applying itdb:migrate
– this command creates a new Prisma migration file based on the defined schema and also generates the TypeScript types.db:push
– this command pushes the Prisma migration file to the PostgreSQL database.
Now make sure the PostgreSQL Docker container is running and execute the following command to create the Prisma migration and push the changes to the database.
If you are familiar with pgAdmin, log in with the Postgres credentials defined in the .env
file to see the SQL table added by Prisma.

Step 4 – Creating the Next.js tRPC Server
In this step, you will create the tRPC server and write the code needed to connect the tRPC server to the Redis and PostgreSQL Docker containers.
To do that, install the following dependencies:
Installing the tRPC dependencies
@trpc/server
– a library for creating the tRPC procedures (endpoints) and routers@trpc/next
– a tRPC binding that connects the tRPC router to Next.jssuperjson
– used as the Next.js tRPC transformer to safely serialize JavaScript expressions to a superset of JSON.redis
– a JavaScript library for communicating with a Redis server
Connecting to the Redis and PostgreSQL Containers
Now that we have the Redis and PostgreSQL Docker containers running, let’s create some utility functions to connect them to the Next.js tRPC server.
Connecting to the Redis Server
Create a src/server/utils/connectRedis.ts
file and add the following code to connect the Next.js server to the Redis Docker container.
src/server/utils/connectRedis.ts
In the above, we evoked the redisClient.set()
method to add a message with a “tRPC” key to the Redis database. Later, we will retrieve the message and send it to the Next.js tRPC client.
Connecting to the PostgreSQL Server
Create a src/server/utils/prisma.ts
file and add these code snippets to connect the Next.js server to the Postgres database.
src/server/utils/prisma.ts
Creating the tRPC Context and Routes
With that out of the way, let’s create the tRPC context and the routes. The context is used to pass contextual data to the resolvers.
To be precise, the context function will be evoked for every incoming request and the results will be passed to all the resolvers.
Creating the tRPC Context
src/server/createContext.ts
In the above, we inferred the data types from the createContext()
function. The inferred type will be passed as a generic to the tRPC router to get the typed context object.
Initialize the tRPC Server
At this point, we are now ready to initialize the tRPC server. To do this, we’ll evoke the initTRPC method, append the Context we created above, call the .create()
method and pass superjson
as the transformer.
src/server/createRouter.ts
Create the tRPC Router
Here, let’s create a router to manage the tRPC endpoints. The router will enable us to add:
- Query procedures (endpoints) – to fetch data
- Mutation procedures (endpoints) – to modify data. This will allow us to perform the Create/Update/Delete operations.
- Subscription procedures (endpoints) – to subscribe to data via WebSockets
So, create a src/server/routers/app.routes.ts
file and add the following code:
src/server/routers/app.routes.ts
Quite a lot happening in the above, let’s break it down:
- First, we evoked the
connectDB()
utility function to connect the Next.js tRPC server to the Postgres database. - Next, we added a “getHello” query procedure to the router and returned the message we stored in the Redis database to the client.
- Lastly, we exported the AppRouter type that will be used by the tRPC client to know the different queries, mutations, and subscriptions available on the Next.js tRPC server.
Adding the tRPC Routes to the Next.js API Router
With all the above configurations in place, let’s create a dynamic Next.js API route for the tRPC router.
src/pages/api/trpc[trpc].ts
Testing the Next.js tRPC Server
We are now ready to test the tRPC server. Make sure the Docker containers are running and run yarn dev
or npm run dev
to start the Next.js tRPC server.
Enter this URL in the browser and within a few seconds, you should see the message we stored in the Redis database.
If by any chance the message field is null, refresh the browser for it to work.

Step 5 – Setup tailwindCss in Next.js
Follow the steps below to add tailwindCss to the Next.js tRPC client.
Step 1: Install the tailwindCss library
Run the command below to install TailwindCSS and its peer dependencies:
The above command will also generate the tailwind.config.js
and postcss.config.js
configuration files
Step 2: Adding Template Paths
Open the tailwind.config.js
file and add the path to the Next.js template files. Also, you can add your custom colors and fonts if any.
tailwind.config.js
Step 3: Add the tailwindCss directives
Now replace the content of the src/styles/globals.css
file with the following TailwindCSS directives and CSS styles.
src/styles/globals.css
Step 2: Import the CSS file
To use the tailwindCss classes, you need to import the globals.css
file into the src/pages/_app.tsx
file.
src/pages/_app.tsx
Step 6 – Creating the Next.js tRPC Client
Now that we have the tRPC server running, let’s create the tRPC client to help us make the procedure calls to the server.
To begin install the following dependencies:
tailwind-merge
– for merging tailwindCss classes in JS@tanstack/react-query
– a server state management tool@tanstack/react-query-devtools
– A GUI for@tanstack/react-query
@trpc/react-query
– serves as a thin wrapper around React Query@trpc/client
– for creating the tRPC client
Now create a src/client/utils/trpc.ts
file and add the following code to generate the tRPC hooks based on the queries, mutations, and subscriptions defined on the Next.js tRPC server.
src/client/utils/trpc.ts
Next, replace the content of the src/pages/_app.tsx
file with the following:
src/pages/_app.tsx
We used the withTRPC
higher-order component to configure the Next.js app to work with tRPC.
Now replace the content of the src/pages/index.tsx
file with the following code.
src/pages/index.tsx
The above code will evoke the getHello procedure on the Next.js tRPC API to retrieve the message we stored in the Redis database and display it in the UI.
Run yarn dev
or npm run dev
and open the URL http://localhost:3000/
in the browser. Within a few seconds, you should see a preview like this.

Conclusion
With this tRPC client and server example in TypeScript, you’ve learned how to set up a tRPC client and server with Next.js, PostgreSQL, Prisma, React Query, and Redis.
You can find the source code of the Next.js tRPC client and server on my GitHub
Great tutorial! With the new Next13 now, do you have idea on how we can use tRPC in both Client & Server components? Or do we have to refactor our tRPC setup to only run on Server-side or both sides? According to this doc (https://trpc.io/docs/v10/server-side-calls), we seems to be able to make queries/mutations & use them on the server-side. But I don’t know whether we can combine both tRPC setup for client-side & server-side.
Basically running mutation on the client side (on Client component). Upon successful mutation, then we can invalidate queries immediately. And this query is on the server-side (running on Server component)
The tRPC team are still experimenting with the tRPC + Next 13 combo so we just have to wait for their recommendation. You can find the experiments on https://github.com/trpc/next-13.
After the setup of the docker-compose file, there’s a typo in the code snippet to install trpc server dependencies. Also had a conflict with peer deps so added flag.
should say
“`
npm install @trpc/server@next @trpc/next@next superjson redis –legacy-peer-deps
“`
Thanks for pointing that out, I’ll fix the typo right away.
I’ve not had a dependency conflict before because I always use Yarn. However, I’ll look into it and see if I can resolve the conflict with the peer dependencies.
Great content man !!! Thx for sharing your knowledge ^^
if i have trpc server outside nextjs stack i can set up the client without issue? anyone tried ?
Although you can run a tRPC server outside of the Next.js stack, the challenge lies in how to pass the inferred type of the tRPC router available on the server to the tRPC client running in Next.js.
The key to enabling the type safety feature of tRPC is providing the tRPC router type to the tRPC client so that it knows the different queries and mutations defined on the tRPC server and the required arguments when making procedure calls.
Additionally, tRPC provides an adapter that is specific to Next.js. If you build your tRPC server outside of the Next.js stack using another adapter, such as an Express.js adapter, you won’t be able to provide its router type to the tRPC client running in Next.js.
That’s why, when working with tRPC in Node.js and React, it’s common practice to utilize Yarn Workspace. By doing so, we can install the tRPC router type as a dependency in the React.js project, which then allows us to pass it to the tRPC client.