# Turborepo (/docs/guides/deployment/turborepo)

Location: Guides > Deployment > Turborepo

Prisma is a powerful ORM for managing databases, and [Turborepo](https://turborepo.dev/docs) 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: [#what-youll-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.

Prerequisites [#prerequisites]

* [Node.js 20.19.0+](https://nodejs.org/)
* [TypeScript 5.4.0+](https://www.typescriptlang.org/)

1. Set up your project [#1-set-up-your-project]

To set up a Turborepo monorepo named `turborepo-prisma`, run the following command:

  

#### npm

```bash
npx create-turbo@latest turborepo-prisma
```

#### pnpm

```bash
pnpm dlx create-turbo@latest turborepo-prisma
```

#### yarn

```bash
yarn dlx create-turbo@latest turborepo-prisma
```

#### bun

```bash
bunx --bun create-turbo@latest turborepo-prisma
```

You'll be prompted to select your package manager, this guide will use `npm`:

> [!NOTE]
> * *Which package manager do you want to use?* `npm`

After the setup, navigate to the project root directory:

```bash
cd turborepo-prisma
```

2. Add a new database package to the monorepo [#2-add-a-new-database-package-to-the-monorepo]

2.1 Create the package and install Prisma [#21-create-the-package-and-install-prisma]

Create a `database` directory inside `packages` and navigate into it:

```bash
mkdir -p packages/database
cd packages/database
```

Then initialize it with a `package.json`:

```json title="packages/database/package.json"
{
  "name": "@repo/db",
  "version": "0.0.0"
}
```

Then install the required Prisma ORM dependencies:

  

#### npm

```bash
npm install prisma --save-dev
npm install @prisma/client @prisma/adapter-pg pg dotenv
```

#### pnpm

```bash
pnpm add prisma --save-dev
pnpm add @prisma/client @prisma/adapter-pg pg dotenv
```

#### yarn

```bash
yarn add prisma --dev
yarn add @prisma/client @prisma/adapter-pg pg dotenv
```

#### bun

```bash
bun add prisma --dev
bun add @prisma/client @prisma/adapter-pg pg dotenv
```

> [!NOTE]
> If you are using a different database provider (MySQL, SQL Server, SQLite), install the corresponding driver adapter package instead of `@prisma/adapter-pg`. For more information, see [Database drivers](/orm/core-concepts/supported-databases/database-drivers).

2.2. Initialize Prisma and define models [#22-initialize-prisma-and-define-models]

Inside the `database` directory, initialize Prisma by running:

  

#### npm

```bash
npx prisma init
```

#### pnpm

```bash
pnpm dlx prisma init
```

#### yarn

```bash
yarn dlx prisma init
```

#### bun

```bash
bunx --bun prisma init
```

This will create several files inside `packages/database`:

* A `prisma` directory with a `schema.prisma` file.
* A `prisma.config.ts` file for configuring Prisma.
* A `.env` file containing a local `DATABASE_URL` in the `packages/database` directory.

Create a Prisma Postgres database and replace the generated `DATABASE_URL` in your `.env` file with the `postgres://...` connection string from the CLI output:

```bash
npx create-db
```

In the `packages/database/prisma/schema.prisma` file, add the following models:

```prisma title="packages/database/prisma/schema.prisma"
generator client {
  provider = "prisma-client"
  output   = "../generated/prisma"
}

datasource db {
  provider = "postgresql"
}

model User { // [!code ++]
  id    Int     @id @default(autoincrement()) // [!code ++]
  email String  @unique // [!code ++]
  name  String? // [!code ++]
  posts Post[] // [!code ++]
} // [!code ++]
 // [!code ++]
model Post { // [!code ++]
  id        Int     @id @default(autoincrement()) // [!code ++]
  title     String // [!code ++]
  content   String? // [!code ++]
  published Boolean @default(false) // [!code ++]
  authorId  Int // [!code ++]
  author    User    @relation(fields: [authorId], references: [id]) // [!code ++]
} // [!code ++]
```

The `prisma.config.ts` file created in the `packages/database` directory should look like this:

```typescript title="packages/database/prisma.config.ts"
import "dotenv/config";
import { defineConfig, env } from "prisma/config";

export default defineConfig({
  schema: "prisma/schema.prisma",
  migrations: {
    path: "prisma/migrations",
  },
  datasource: {
    url: env("DATABASE_URL"),
  },
});
```

> [!WARNING]
> It is recommended to add `packages/database/generated` to your root `.gitignore` because generated Prisma Client code is a build artifact that can be recreated with `db:generate`.

The importance of generating Prisma types in a custom directory [#the-importance-of-generating-prisma-types-in-a-custom-directory]

In the `schema.prisma` file, we specify a custom [`output`](/orm/reference/prisma-schema-reference#fields-for-prisma-client-provider) path where Prisma will generate its types. This ensures Prisma's types are resolved correctly across different package managers.

> [!NOTE]
> In this guide, the types will be generated in the `database/generated/prisma` directory.

2.3. Add scripts and run migrations [#23-add-scripts-and-run-migrations]

Let's add some scripts to the `package.json` inside `packages/database`:

```json title="packages/database/package.json"
{
  "name": "@repo/db",
  "version": "0.0.0",
  "type": "module", // [!code ++]
  "scripts": {
    // [!code ++]
    "db:generate": "prisma generate", // [!code ++]
    "db:migrate": "prisma migrate dev", // [!code ++]
    "db:deploy": "prisma migrate deploy" // [!code ++]
  }, // [!code ++]
  "devDependencies": {
    "prisma": "^7.0.0"
  },
  "dependencies": {
    "@prisma/client": "^7.0.0",
    "@prisma/adapter-pg": "^7.0.0",
    "pg": "^8.0.0",
    "dotenv": "^16.0.0"
  }
}
```

Let's also add these scripts to `turbo.json` in the root and ensure that `DATABASE_URL` is added to the environment:

```json title="turbo.json"
{
  "$schema": "https://turborepo.dev/schema.json",
  "ui": "tui",
  "globalEnv": ["DATABASE_URL"], // [!code ++]
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "inputs": ["$TURBO_DEFAULT$", ".env*"],
      "outputs": [".next/**", "!.next/cache/**"]
    },
    "lint": {
      "dependsOn": ["^lint"]
    },
    "check-types": {
      "dependsOn": ["^check-types"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    },
    "db:generate": { // [!code ++]
      "cache": false // [!code ++]
    }, // [!code ++]
    "db:migrate": { // [!code ++]
      "cache": false // [!code ++]
    }, // [!code ++]
    "db:deploy": { // [!code ++]
      "cache": false // [!code ++]
    } // [!code ++]
  }
}
```

Run your first migration and generate Prisma Client

Navigate to the project root and run the following command to create and apply your first migration:

  

#### npm

```bash
npx turbo run db:migrate -- --name init
```

#### pnpm

```bash
pnpm dlx turbo run db:migrate -- --name init
```

#### yarn

```bash
yarn dlx turbo run db:migrate -- --name init
```

#### bun

```bash
bunx --bun turbo run db:migrate -- --name init
```

In Prisma 7, `migrate dev` no longer runs `prisma generate` automatically, so run generate explicitly:

  

#### npm

```bash
npx turbo run db:generate
```

#### pnpm

```bash
pnpm dlx turbo run db:generate
```

#### yarn

```bash
yarn dlx turbo run db:generate
```

#### bun

```bash
bunx --bun turbo run db:generate
```

Use the same `npx turbo run db:generate` command after future schema changes.

2.4. Export the Prisma client and types [#24-export-the-prisma-client-and-types]

Next, export the generated types and an instance of `PrismaClient` so it can be 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`:

```ts title="packages/database/src/client.ts"
import { PrismaClient } from "../generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";

const adapter = new PrismaPg({
  connectionString: process.env.DATABASE_URL,
});

const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };

export const prisma =
  globalForPrisma.prisma ||
  new PrismaClient({
    adapter,
  });

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:

```ts title="packages/database/src/index.ts"
export { prisma } from "./client"; // exports instance of prisma
export * from "../generated/prisma/client"; // exports generated types from prisma
```

Follow the [Just-in-Time packaging pattern](https://turborepo.dev/docs/core-concepts/internal-packages#just-in-time-packages) and create an entrypoint to the package inside `packages/database/package.json`:

> [!WARNING]
> If you're not using a bundler, use the [Compiled Packages](https://turborepo.dev/docs/core-concepts/internal-packages#compiled-packages) strategy instead.

```json title="packages/database/package.json"
{
  "name": "@repo/db",
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "db:generate": "prisma generate",
    "db:migrate": "prisma migrate dev",
    "db:deploy": "prisma migrate deploy"
  },
  "devDependencies": {
    "prisma": "^7.0.0"
  },
  "dependencies": {
    "@prisma/client": "^7.0.0",
    "@prisma/adapter-pg": "^7.0.0",
    "pg": "^8.0.0",
    "dotenv": "^16.0.0"
  },
  "exports": {
    // [!code ++]
    ".": "./src/index.ts" // [!code ++]
  } // [!code ++]
}
```

By completing these steps, you'll make the Prisma types and `PrismaClient` instance accessible throughout the monorepo.

3. Import the database package in the web app [#3-import-the-database-package-in-the-web-app]

The `turborepo-prisma` project should have an app called `web` at `apps/web`. Add the `database` dependency to `apps/web/package.json`:

  

#### npm

```json
{
  // ...
  "dependencies": {
    "@repo/db": "*" // [!code ++]
    // ...
  }
  // ...
}
```

#### pnpm

```json
{
  // ...
  "dependencies": {
    "@repo/db": "workspace:*" // [!code ++]
    // ...
  }
  // ...
}
```

#### bun

```json
{
  // ...
  "dependencies": {
    "@repo/db": "workspace:*" // [!code ++]
    // ...
  }
  // ...
}
```

Run your package manager's install command from the project root to link the workspace dependency:

  

#### npm

```bash
npm install
```

#### pnpm

```bash
pnpm install
```

#### yarn

```bash
yarn install
```

#### bun

```bash
bun install
```

Let's import the instantiated `prisma` client from the `database` package in the `web` app.

In the `apps/web/app` directory, open the `page.tsx` file and add the following code:

```tsx title="apps/web/app/page.tsx"
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 into it the contents of the `.env` file from the `/database` directory containing the `DATABASE_URL`:

```text title="apps/web/.env"
DATABASE_URL="Same database URL as used in the database directory"
```

> [!NOTE]
> 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`](https://dotenvx.com/docs/monorepos/turborepo).
> 
> 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](https://dotenvx.com/docs/monorepos/turborepo).
> 
> Keep in mind that Turborepo [recommends using separate `.env` files for each package](https://turborepo.dev/docs/crafting-your-repository/using-environment-variables#use-env-files-in-packages) to promote modularity and avoid potential conflicts.

4. Configure task dependencies in Turborepo [#4-configure-task-dependencies-in-turborepo]

The `db:generate` script is essential for `dev` and `build` tasks in a monorepo setup.

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`. Keep `db:deploy` uncached for staging/production migration runs in CI. Here's how to configure this in your `turbo.json` file:

```json title="turbo.json"
{
  "$schema": "https://turborepo.dev/schema.json",
  "ui": "tui",
  "globalEnv": ["DATABASE_URL"],
  "tasks": {
    "build": {
      "dependsOn": ["^build", "^db:generate"], // [!code highlight]
      "inputs": ["$TURBO_DEFAULT$", ".env*"],
      "outputs": [".next/**", "!.next/cache/**"]
    },
    "lint": {
      "dependsOn": ["^lint"]
    },
    "check-types": {
      "dependsOn": ["^check-types"]
    },
    "dev": {
      "dependsOn": ["^db:generate"], // [!code ++]
      "cache": false,
      "persistent": true
    },
    "db:generate": {
      "cache": false
    },
    "db:migrate": {
      "cache": false
    },
    "db:deploy": {
      "cache": false
    }
  }
}
```

5. Run the project in development [#5-run-the-project-in-development]

Then from the project root run the project:

  

#### npm

```bash
npx turbo run dev --filter=web
```

#### pnpm

```bash
pnpm dlx turbo run dev --filter=web
```

#### yarn

```bash
yarn dlx turbo run dev --filter=web
```

#### bun

```bash
bunx --bun turbo run dev --filter=web
```

Navigate to the `http://localhost:3000` and you should see the message:

```
No user added yet
```

> [!NOTE]
> You can add users to your database by creating a seed script or manually by using [Prisma Studio](/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

>     ```bash
>     npx prisma studio
>     ```
>
> 
>   #### pnpm

>     ```bash
>     pnpm dlx prisma studio
>     ```
>
> 
>   #### yarn

>     ```bash
>     yarn dlx prisma studio
>     ```
>
> 
>   #### bun

>     ```bash
>     bunx --bun prisma studio
>     ```
>
> 
> 
> This command starts a server with a GUI at [http://localhost:5555](http://localhost:5555), allowing you to view and modify your data.

Congratulations, you're done setting up Prisma for Turborepo!

Next Steps [#next-steps]

* Expand your Prisma models to handle more complex data relationships.
* Implement additional CRUD operations to enhance your application's functionality.
* Check out [Prisma Postgres](https://www.prisma.io/postgres) to see how you can scale your application.

More Info [#more-info]

* [Turborepo Docs](https://turborepo.dev/docs)
* [Next.js Docs](https://nextjs.org/docs)
* [Prisma ORM Docs](/orm)

## Related pages

- [`Bun workspaces`](https://www.prisma.io/docs/guides/deployment/bun-workspaces): Learn step-by-step how to integrate Prisma ORM in a Bun workspaces monorepo to build scalable and modular applications efficiently
- [`Cloudflare D1`](https://www.prisma.io/docs/guides/deployment/cloudflare-d1): Learn how to use Prisma ORM with Cloudflare D1
- [`Cloudflare Workers`](https://www.prisma.io/docs/guides/deployment/cloudflare-workers): Learn how to use Prisma ORM and Prisma Postgres in a Cloudflare Workers project
- [`Docker`](https://www.prisma.io/docs/guides/deployment/docker): Learn step-by-step configure a Prisma ORM app in Docker
- [`pnpm workspaces`](https://www.prisma.io/docs/guides/deployment/pnpm-workspaces): Learn step-by-step how to integrate Prisma ORM in a pnpm workspaces monorepo to build scalable and modular applications efficiently