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:

- 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

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:

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

```terminal
touch pnpm-workspace.yaml
```

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

```yaml file=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). *Explictly* pin the lastest 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:

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

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

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

```terminal
cd packages/database
pnpm init 
```

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

```json file=database/package.json
// add-start
"devDependencies": {
  "prisma": "catalog:prisma"
}
// add-end 
```

Then install Prisma:

```terminal
pnpm install
```

Then, add additional dependencies:

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

:::info

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/overview/databases/database-drivers).

:::

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

```terminal
pnpm tsc --init
```

### 2.2. Setup Prisma ORM in your database package

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

```terminal
pnpm prisma init --db
```

Enter a name for your project and choose a database region.

:::info

We're going to be using [Prisma Postgres](/postgres/getting-started) in this guide. If you're not using a Prisma Postgres database, you won't need to add the `--db` flag.

:::

This command:

- Connects your CLI to your [Prisma Data Platform](https://console.prisma.io) account. If you're not logged in or don't have an account, your browser will open to guide you through creating a new account or signing into your existing one.
- Creates a `prisma` directory containing a `schema.prisma` file for your database models.
- Creates a `.env` file with your `DATABASE_URL` (e.g., for Prisma Postgres it should have something similar to `DATABASE_URL="prisma+postgres://accelerate.prisma-data.net/?api_key=eyJhbGciOiJIUzI..."`).


Edit the `schema.prisma` file to define a `User` model in your database and specify a [custom `output` directory](/orm/prisma-client/setup-and-configuration/generating-prisma-client#using-a-custom-output-path) to generate the Prisma Client. This ensures that generated types are resolved correctly:

```prisma file=prisma/schema.prisma
generator client {
  provider = "prisma-client"
  //add-start
  output = "../generated/client"
  //add-end
}

datasource db {
  provider = "postgresql"
}

//add-start
model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
}
//add-end
```

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

```typescript file=database/prisma.config.ts
// add-start
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'),
  },
});
// add-end
```

:::note

You'll need to install the `dotenv` package to load environment variables from the `.env` file:

```terminal
pnpm add dotenv
```

:::

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

```json file=database/package.json
{
  "scripts": {
    // delete-start
    "test": "echo \"Error: no test specified\" && exit 1",
    // delete-end
    // add-start
    "db:generate": "prisma generate",
    "db:migrate": "prisma migrate dev",
    "db:deploy": "prisma migrate deploy",
    "db:studio": "prisma studio"
    // add-end
  }
}
```

Use [Prisma Migrate](/orm/prisma-migrate) to migrate your database changes:

```terminal
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 file=database/client.ts
// add-start
import { PrismaClient } from "./generated/client";
import { PrismaPg } from "@prisma/adapter-pg";

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

// Use globalThis for broader environment compatibility
const globalForPrisma = globalThis as typeof globalThis & {
  prisma?: PrismaClient;
};

// Named export with global memoization
export const prisma: PrismaClient =
  globalForPrisma.prisma ?? new PrismaClient({
    adapter,
  });

if (process.env.NODE_ENV !== "production") {
  globalForPrisma.prisma = prisma;
}
// add-end
```

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

```ts file=database/index.ts
// add-start
export { prisma } from "./client";
export * from "./generated/client";
// add-end
```

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

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

Navigate to the `apps` directory:

```terminal
cd ../../apps
```

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

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

```terminal
cd web/
```

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

```terminal
cp ../../packages/database/.env .
```

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

```json file=web/package.json
"dependencies": {
  // add-start
  "database": "workspace:*",
  // add-end
  // additional dependencies
  // ...
}
```

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

```terminal
pnpm install
```

### 3.2. 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 file=app/page.tsx
// add-start
import { prisma } from "database";

export default async function Home() {
  const user = await prisma.user.findFirst({
    select: {
      name: true
    }
  })

  return (
    <div>
      {user?.name && <p>Hello from {user.name}</p>}
      {!user?.name && <p>No user has been added to the database yet. </p>}
    </div>
  );
}
// add-end
```

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

### 3.3. 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:

```package.json
"scripts": {
  // add-start
  "build": "pnpm --filter database db:deploy && pnpm --filter database db:generate  && pnpm --filter web build",
  "start": "pnpm --filter web start",
  "dev": "pnpm --filter database db:generate && pnpm --filter web dev",
  "studio": "pnpm --filter database db:studio"
  // add-end
}
```

### 3.4. Run your application

Then head back to the root of the monorepo:

```terminal
cd ../../
```

Start your development server by executing:

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

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

## 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](/guides/turborepo) guide.

---

# How to use Prisma ORM with multiple databases in a single app