Using Prisma with Turborepo
Prisma is a powerful ORM for managing databases, and Turborepo simplifies monorepo workflows. By combining these tools, you can create a scalable, modular architecture for your projects.
This guide will show you how to set up Prisma as a standalone package in a Turborepo monorepo, enabling efficient configuration, type sharing, and database management across multiple apps.
What you'll learn:
- How to set up Prisma in a Turborepo monorepo.
- Steps to generate and reuse PrismaClient across packages.
- Integrating the Prisma package into other applications in the monorepo.
This guide was tested using Turborepo version 2.3.3
and Prisma ORM version 6.1.0
.
1. Create your monorepo using turborepo
To set up a Turborepo monorepo named hello-world
, run the following command:
npx create-turbo@latest hello-world
After the setup, choose a package manager for the project. Navigate to the project root directory and install Turborepo as a development dependency:
- npm
- yarn
- pnpm
cd ./hello-world
npm install turbo --save-dev
cd ./hello-world
yarn add turbo --dev --ignore-workspace-root-check
cd ./hello-world
pnpm add turbo --save-dev --ignore-workspace-root-check
For more information about installing Turborepo, refer to the official Turborepo guide.
2. Add a new database
package to the hello-world
monorepo
Create a database
package within the packages
directory. Then, create a package.json
file for the package by running:
cd packages/
mkdir database
cd database
touch package.json
Define the package.json
file as follows:
{
"name": "@repo/db",
"version": "0.0.0"
}
Next, install the required dependencies to use Prisma ORM. Use your preferred package manager:
- npm
- yarn
- pnpm
npm install prisma --save-dev
npm install @prisma/client
yarn add prisma --dev
yarn add @prisma/client
pnpm add prisma --save-dev
pnpm add @prisma/client
3. Initialize prisma by running prisma init
Inside the database
directory, initialize prisma by running:
- npm
- yarn
- pnpm
npx prisma init
yarn prisma init
pnpm prisma init
This should create several files inside packages/database
:
schema.prisma
is where your Prisma schema lives. Here, you'll be able to modify the shape of your database. Theprisma init
command by default will create a configuration forPostgreSQL
to be used. You can modify the schema to use any other supported database by Prisma ORM..gitignore
adds some ignored files to git.env
lets you manually specify yourDATABASE_URL
for prisma.
Make sure to replace the DATABASE_URL
inside packages/database/.env
with a valid database url.
Add a model to your Prisma schema in database/prisma/schema.prisma
:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
output = "../generated/client"
}
model User {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
email String @unique
name String?
}
The importance of generating Prisma types in a custom directory
In the schema.prisma
file, we specify a custom output
path where Prisma will generate its types. This ensures Prisma's types are resolved correctly across different package managers.
In this guide, the types will be generated in the
database/generated/client
directory.
4. Create scripts to execute Prisma CLI commands
Let's add some scripts to the package.json
inside packages/database
:
{
"scripts": {
"db:generate": "prisma generate",
"db:migrate": "prisma migrate dev --skip-generate",
"db:deploy": "prisma migrate deploy"
}
}
Let's also add these scripts to turbo.json
in the root:
{
"tasks": {
"db:generate": {
"cache": false
},
"db:migrate": {
"cache": false,
"persistent": true // This is necessary to interact with the CLI and assign names to your database migrations.
},
"db:deploy": {
"cache": false
}
}
}
1. Migrate your prisma.schema
and generate types
Navigate to the project root and run the following command to automatically migrate our database:
- npm
- yarn
- pnpm
npx turbo db:migrate
yarn turbo db:migrate
pnpm turbo db:migrate
2. Generate your prisma.schema
To generate the types from Prisma schema, from the project root run:
- npm
- yarn
- pnpm
npx turbo db:generate
yarn turbo db:generate
pnpm turbo db:generate
5. Export prisma types and an instance of PrismaClient
to be used across the monorepo
Next, export the generated types and an instance of PrismaClient
so it can used in your applications.
In the packages/database
directory, create a src
folder and add a client.ts
file. This file will define an instance of PrismaClient
:
import { PrismaClient } from "../generated/client";
const globalForPrisma = global as unknown as { prisma: PrismaClient };
export const prisma =
globalForPrisma.prisma || new PrismaClient();
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
Then create an index.ts
file in the src
folder to re-export the generated prisma types and the PrismaClient
instance:
export { prisma } from './client' // exports instance of prisma
export * from "../generated/client" // exports generated types from prisma
Follow the Just-in-Time packaging pattern and create an entrypoint to the package inside packages/database/package.json
:
{
"exports": {
".": "./src/index.ts"
}
}
By completing these steps, you'll make the Prisma types and PrismaClient
instance accessible throughout the monorepo.
6. Importing the database
package into the web
app in the monorepo
The hello-world
project should have an app called web
at apps/web
. Add the database
dependency to apps/web/package.json
:
- npm
- yarn
- pnpm
{
"dependencies": {
"@repo/db": "*"
}
}
{
"dependencies": {
"@repo/db": "*"
}
}
{
"dependencies": {
"@repo/db": "workspace:*"
}
}
Run your package manager's install command inside the apps/web
directory:
- npm
- yarn
- pnpm
cd apps/web
npm install
cd apps/web
yarn install
cd apps/web
pnpm install
Let's import the intantiated prisma
client from the database
package in the web
app in the page.tsx
file:
import styles from "./page.module.css";
import { prisma } from "@repo/db";
export default async function Home() {
const user = await prisma.user.findFirst()
return (
<div className={styles.page}>
{user?.name ?? "No user added yet"}
</div>
);
}
Then create a .env
file in the web
directory and copy of the contents of the .env
file in the database
directory containing the DATABASE_URL
.:
DATABASE_URL="Same database url as used in the database directory"
If you want to use a single .env
file in the root directory across your apps and packages in a Turborepo setup, consider using a package like dotenvx
.
To implement this, update the package.json
files for each package or app to ensure they load the required environment variables from the shared .env
file. For detailed instructions, refer to the dotenvx
guide for Turborepo.
Keep in mind that Turborepo recommends using separate .env
files for each package to promote modularity and avoid potential conflicts.
7. Setup dependent tasks
The db:generate
and db:deploy
scripts are not yet optimized for the monorepo setup but are essential for the dev
and build
tasks.
If a new developer runs turbo dev
on an application without first running db:generate
, they will encounter errors.
To prevent this, ensure that db:generate
is always executed before running dev
or build
. Additionally, make sure both db:deploy
and db:generate
are executed before db:build
. Here's how to configure this in your turbo.json
file:
{
"tasks": {
"dev": {
"dependsOn": ["^db:generate"],
"cache": false
// Additional configuration for dev tasks
},
"build": {
"dependsOn": ["^db:generate"],
// Additional configuration for build tasks
}
}
}
8. Run the project in development
Then from the project root run the project:
- npm
- yarn
- pnpm
npx turbo run dev --filter=web
yarn turbo run dev --filter=web
pnpm turbo run dev --filter=web
Navigate to the http://localhost:3000
and you should see the message:
No user added yet
You can add users to your database by creating a seed script or manually by using Prisma Studio.
To use Prisma Studio to add manually data via a GUI, navigate inside the packages/database
directory and run prisma studio
using your package manager:
- npm
- yarn
- pnpm
npx prisma studio
yarn prisma studio
pnpm prisma studio
This command starts a server with a GUI at http://localhost:5555, allowing you to view and modify your data.
Congratulations, you're done setting up Prisma for Turborepo!