# pnpm workspaces (/docs/guides/deployment/pnpm-workspaces)

> For the complete Prisma documentation index, see [llms.txt](https://www.prisma.io/docs/llms.txt). A markdown version of any docs page is available by appending `.md` to its URL.

Learn step-by-step how to integrate Prisma ORM in a pnpm workspaces monorepo to build scalable and modular applications efficiently

Location: Guides > Deployment > pnpm workspaces

Prisma is a powerful ORM for managing your database, and when combined with [pnpm Workspaces](https://pnpm.io/workspaces), you can maintain a lean and modular monorepo architecture. In this guide, we’ll walk through setting up Prisma in its own package within a pnpm Workspaces monorepo, enabling maintainable type sharing and efficient database management across your apps.

### What you'll learn: [#what-youll-learn]

* How to initialize a monorepo using pnpm Workspaces.
* Steps to integrate Prisma as a standalone package.
* How to generate and share the Prisma Client across packages.
* Integrating the Prisma package into an application within your workspace.

## 1. Prepare your project and configure pnpm workspaces [#1-prepare-your-project-and-configure-pnpm-workspaces]

Before integrating Prisma, you need to set up your project structure. Start by creating a new directory for your project (for example, `my-monorepo`) and initialize a Node.js project:

```bash
mkdir my-monorepo
cd my-monorepo
pnpm init
```

Next, create a `pnpm-workspace.yaml` file to define your workspace structure and pin the Prisma version:

```bash
touch pnpm-workspace.yaml
```

Add the following configuration to `pnpm-workspace.yaml`:

```yaml title="pnpm-workspace.yaml"
packages:
  - "apps/*"
  - "packages/*"
catalogs:
  prisma:
    prisma: latest
```

> [!NOTE]
> The `catalogs` help you pin a certain version of prisma across your repositories. You can learn more about them [here](https://pnpm.io/catalogs). *Explicitly* pin the latest version of [prisma](https://www.npmjs.com/package/prisma) in the `pnpm-workspace.yaml` file. At the time of writing, this is version `6.3.1`.

Finally, create directories for your applications and shared packages:

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

## 2. Setup the shared database package [#2-setup-the-shared-database-package]

This section covers creating a standalone database package that uses Prisma. The package will house all database models and the generated Prisma Client, making it reusable across your monorepo.

### 2.1. Initialize the package and install dependencies [#21-initialize-the-package-and-install-dependencies]

Navigate to the `packages/database` directory and initialize a new package:

```bash
cd packages/database
pnpm init
```

Add Prisma as a development dependency in your `package.json` using the pinned `catalog`:

```json title="database/package.json"
"devDependencies": { // [!code ++]
  "prisma": "catalog:prisma" // [!code ++]
} // [!code ++]
```

Then install Prisma:

```bash
pnpm install
```

Then, add additional dependencies:

```bash
pnpm add typescript tsx @types/node @types/pg -D
pnpm add @prisma/adapter-pg pg
```

> [!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](https://www.prisma.io/docs/orm/core-concepts/supported-databases/database-drivers).

Initialize a `tsconfig.json` file for your `database` package:

```bash
pnpm tsc --init
```

### 2.2. Setup Prisma ORM in your database package [#22-setup-prisma-orm-in-your-database-package]

Initialize Prisma ORM with an instance of [Prisma Postgres](https://www.prisma.io/docs/postgres) in the `database` package by running the following command:

```bash
pnpm dlx prisma init
```

> [!NOTE]
> `prisma init` creates the Prisma scaffolding and a local `DATABASE_URL`. In the next step, create a Prisma Postgres database and replace that value with a direct `postgres://...` connection string.

This command:

* Creates a `prisma` directory containing a `schema.prisma` file for your database models.
* Creates a `.env` file with a local `DATABASE_URL`.

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
```

Edit the `schema.prisma` file to define a `User` model in your database and specify a [custom `output` directory](https://www.prisma.io/docs/orm/reference/prisma-schema-reference#fields-for-prisma-client-provider) to generate the Prisma Client. This ensures that generated types are resolved correctly:

```prisma title="prisma/schema.prisma"
generator client {
  provider = "prisma-client"
  output = "../generated/client" // [!code ++]
}

datasource db {
  provider = "postgresql"
}

model User { // [!code ++]
  id    Int     @id @default(autoincrement()) // [!code ++]
  email String  @unique // [!code ++]
  name  String? // [!code ++]
} // [!code ++]
```

Now, create a `prisma.config.ts` file in the `database` package to configure Prisma:

```typescript title="database/prisma.config.ts"
import "dotenv/config"; // [!code ++]
import { defineConfig, env } from "prisma/config"; // [!code ++]
// [!code ++]
export default defineConfig({
  // [!code ++]
  schema: "prisma/schema.prisma", // [!code ++]
  migrations: {
    // [!code ++]
    path: "prisma/migrations", // [!code ++]
  }, // [!code ++]
  datasource: {
    // [!code ++]
    url: env("DATABASE_URL"), // [!code ++]
  }, // [!code ++]
}); // [!code ++]
```

> [!NOTE]
> You'll need to install the `dotenv` package to load environment variables from the `.env` file:
> 
> ```bash
> pnpm add dotenv
> ```

Next, add helper scripts to your `package.json` to simplify Prisma commands:

```json title="database/package.json"
{
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1", // [!code --]
    "db:generate": "prisma generate", // [!code ++]
    "db:migrate": "prisma migrate dev", // [!code ++]
    "db:deploy": "prisma migrate deploy", // [!code ++]
    "db:studio": "prisma studio" // [!code ++]
  }
}
```

Use [Prisma Migrate](https://www.prisma.io/docs/orm/prisma-migrate) to migrate your database changes:

```bash
pnpm run db:migrate
```

When prompted by the CLI, enter a descriptive name for your migration.

Once the migration is successful, create a `client.ts` file to initialize Prisma Client with a driver adapter:

```ts title="database/client.ts"
import { PrismaClient } from "./generated/client"; // [!code ++]
import { PrismaPg } from "@prisma/adapter-pg"; // [!code ++]
// [!code ++]
const adapter = new PrismaPg({
  // [!code ++]
  connectionString: process.env.DATABASE_URL, // [!code ++]
}); // [!code ++]
// [!code ++]
// Use globalThis for broader environment compatibility // [!code ++]
const globalForPrisma = globalThis as typeof globalThis & {
  // [!code ++]
  prisma?: PrismaClient; // [!code ++]
}; // [!code ++]
// [!code ++]
// Named export with global memoization // [!code ++]
export const prisma: PrismaClient = // [!code ++]
  globalForPrisma.prisma ??
  new PrismaClient({
    // [!code ++]
    adapter, // [!code ++]
  }); // [!code ++]
// [!code ++]
if (process.env.NODE_ENV !== "production") {
  // [!code ++]
  globalForPrisma.prisma = prisma; // [!code ++]
} // [!code ++]
```

Then, create an `index.ts` file to re-export the instance of Prisma Client and all generated types:

```ts title="database/index.ts"
export { prisma } from "./client"; // [!code ++]
export * from "./generated/client"; // [!code ++]
```

At this point, your shared database package is fully configured and ready for use across your monorepo.

## 3. Set up and integrate your frontend application [#3-set-up-and-integrate-your-frontend-application]

Now that the database package is set up, create a frontend application (using Next.js) that uses the shared Prisma Client to interact with your database.

### 3.1. Bootstrap a Next.js application [#31-bootstrap-a-nextjs-application]

Navigate to the `apps` directory:

```bash
cd ../../apps
```

Create a new Next.js app named `web`:

```bash
pnpm create next-app@latest web --yes
```

> [!NOTE]
> important
> 
> The `--yes` flag uses default configurations to bootstrap the Next.js app (which in this guide uses the app router without a `src/` directory and `pnpm` as the installer).
> 
> Additionally, the flag may automatically initialize a Git repository in the `web` folder. If that happens, please remove the `.git` directory by running `rm -r .git`.

Then, navigate into the web directory:

```bash
cd web/
```

Copy the `.env` file from the database package to ensure the same environment variables are available:

```bash
cp ../../packages/database/.env .
```

Open the `package.json` file of your Next.js app and add the shared `database` package as a dependency:

```json title="web/package.json"
"dependencies": {
  "database": "workspace:*", // [!code ++]
  // additional dependencies
  // ...
}
```

Run the following command to install the `database` package:

```bash
pnpm install
```

### 3.2. Integrate the shared database package in your app code [#32-integrate-the-shared-database-package-in-your-app-code]

Modify your Next.js application code to use Prisma Client from the database package. Update `app/page.tsx` as follows:

```tsx title="app/page.tsx"
import { prisma } from "database"; // [!code ++]
// [!code ++]
export default async function Home() {
  // [!code ++]
  const user = await prisma.user.findFirst({
    // [!code ++]
    select: {
      // [!code ++]
      name: true, // [!code ++]
    }, // [!code ++]
  }); // [!code ++]
  // [!code ++]
  return (
    // [!code ++]
    <div>
      {" "}
      // [!code ++]
      {user?.name && <p>Hello from {user.name}</p>} // [!code ++]
      {!user?.name && <p>No user has been added to the database yet. </p>} // [!code ++]
    </div> // [!code ++]
  ); // [!code ++]
} // [!code ++]
```

This code demonstrates importing and using the shared Prisma Client to query your `User` model.

### 3.3. Add helper scripts and run your application [#33-add-helper-scripts-and-run-your-application]

Add the following scripts to the root `package.json` of your monorepo. They ensure that database migrations, type generation, and app builds run in the proper order:

```json
"scripts": {
  "build": "pnpm --filter database db:deploy && pnpm --filter database db:generate  && pnpm --filter web build", // [!code ++]
  "start": "pnpm --filter web start", // [!code ++]
  "dev": "pnpm --filter database db:generate && pnpm --filter web dev", // [!code ++]
  "studio": "pnpm --filter database db:studio" // [!code ++]
}
```

### 3.4. Run your application [#34-run-your-application]

Then head back to the root of the monorepo:

```bash
cd ../../
```

Start your development server by executing:

```bash
pnpm run dev
```

Open your browser at [`http://localhost:3000`](http://localhost:3000) to see your app in action.

### 3.5. (Optional) Add data to your database using Prisma Studio [#35-optional-add-data-to-your-database-using-prisma-studio]

There shouldn't be data in your database yet. You can execute `pnpm run studio` in your CLI to start a [Prisma Studio](https://www.prisma.io/docs/studio) in [`http://localhost:5555`](http://localhost:5555) to interact with your database and add data to it.

## Next Steps [#next-steps]

You have now created a monorepo that uses Prisma ORM effectively, with a shared database package integrated into a Next.js application.

For further exploration and to enhance your setup, consider reading the [How to use Prisma ORM with Turborepo](https://www.prisma.io/docs/guides/deployment/turborepo) guide.

## 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
- [`Turborepo`](https://www.prisma.io/docs/guides/deployment/turborepo): Learn step-by-step how to integrate Prisma ORM with Turborepo to build modular, scalable monorepo architectures efficiently