# Turborepo + Prisma (/docs/ai/prompts/turborepo) > 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. Step-by-step guide for integrating Prisma ORM and Prisma Postgres in a Turborepo monorepo Location: AI > Prompts > Turborepo + Prisma ## How to use [#how-to-use] Include this prompt in your AI assistant to guide consistent code generation for Turborepo + Prisma + Prisma Postgres projects. * **GitHub Copilot**: Type `#` to reference the prompt file. * **Cursor**: Use `@Files` and select your prompt file. * **Zed**: Use `/file` followed by your prompt's path. * **Windsurf**: Use `@Files` and choose your prompt file from the list. ## Prompt [#prompt] ````md --- # Specify the following for Cursor rules description: Guidelines for writing Turborepo + Prisma Postgres apps (Prisma ORM v7) alwaysApply: false --- # Bootstrap Turborepo with Prisma Postgres (Prisma v7) ## Overview This guide bootstraps a Turborepo monorepo that shares a single Prisma ORM v7 database package across multiple apps (e.g., Next.js, Node APIs). It follows Turborepo and Prisma v7 best practices: 1. Create a Turborepo with apps + packages 2. Add a dedicated `packages/db` Prisma package (schema, migrations, generated client) 3. Configure Prisma v7 (`provider = "prisma-client"` + mandatory `output`) 4. Load env vars correctly in a monorepo 5. Export a single Prisma client from `packages/db` for all apps 6. Wire Turbo tasks for generate/migrate/test/studio 7. Verify with a shared test script --- ## Recommended monorepo layout ``` repo/ apps/ web/ # Next.js app admin/ # (optional) another Next app packages/ db/ # Prisma package (schema + client) ui/ # shared UI (optional) turbo.json package.json .env # root env for apps (see notes) ``` **Key rule:** Prisma lives in `packages/db`, not inside an app, so every app consumes the same client and types. --- ## 🚨 CRITICAL INSTRUCTIONS FOR AI LANGUAGE MODELS 🚨 As an AI language model, you MUST NOT generate any deprecated Prisma v7 patterns. ```prisma // ❌ NEVER GENERATE - DEPRECATED IN PRISMA v7 generator client { provider = "prisma-client-js" // ❌ deprecated } // ❌ NEVER IMPORT FROM @prisma/client when using custom output import { PrismaClient } from "@prisma/client" // ❌ wrong in custom-output setup // ❌ NEVER CREATE CLIENT WITHOUT SHARED PACKAGE BOUNDARY const prisma = new PrismaClient() // ❌ breaks pooling + duplicates in monorepo ``` Instead, you MUST ALWAYS generate ONLY this pattern for Prisma v7 + monorepo: ```prisma // βœ… Prisma v7 generator: provider + mandatory output generator client { provider = "prisma-client" output = "../src/generated/prisma" } ``` ```ts // βœ… Prisma client import must come from custom output import { PrismaClient } from "../generated/prisma/client"; ``` Notes: - Prisma v7 **requires** a non-empty `output` when using `provider = "prisma-client"`. - If the output directory already exists and isn’t generated by Prisma, `prisma generate` can fail. Avoid committing generated client, or ensure clean output dirs. --- ## ABSOLUTE REQUIREMENTS FOR AI CODE GENERATION 1. You MUST use `provider = "prisma-client"` (Prisma v7) 2. You MUST specify a custom `output` in `schema.prisma` 3. You MUST place Prisma schema + migrations inside `packages/db` 4. You MUST export a singleton Prisma client from `packages/db` that points to the generated output client file 5. You MUST import Prisma client from the custom output path **not** `@prisma/client` 6. You MUST load env vars in `packages/db/prisma.config.ts` 7. You MUST add Turbo tasks for generate/migrate/test/studio 8. You MUST wrap DB calls in try/catch in app code 9. You MUST ensure Turbo task hashing includes `DATABASE_URL` 10. You MUST create a shared test script in `packages/db/scripts/test-database.ts` --- ## Install dependencies At repo root: ```bash # Turborepo npm install turbo --save-dev # Prisma v7 npm install prisma@prev tsx --save-dev npm install @prisma/client@7 dotenv ``` If using Prisma Postgres: ```npm npm install @prisma/adapter-pg ``` --- ## Initialize Prisma inside `packages/db` ```bash cd packages/db npx prisma init ``` This creates: ``` packages/db/ prisma/ schema.prisma prisma.config.ts ``` --- ## Prisma v7 config (`packages/db/prisma.config.ts`) **CRITICAL:** load env vars at the top. ```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"), }, }); ``` --- ## Prisma schema (`packages/db/prisma/schema.prisma`) ```prisma generator client { provider = "prisma-client" output = "../src/generated/prisma" } datasource db { provider = "postgresql" } model User { id Int @id @default(autoincrement()) email String @unique name String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } ``` --- ## Shared Prisma client singleton (`packages/db/src/client.ts`) ```ts import { PrismaClient } from "../generated/prisma/client"; //Prisma Driver Adapter for Postgres import { PrismaPg } from "@prisma/adapter-pg"; // Create a new Driver Adapter instance for PrismaPostgres 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; } export default prisma; ``` --- ## Export DB package API (`packages/db/src/index.ts`) ```ts export { prisma } from "./client"; export * from "../generated/prisma"; ``` And in `packages/db/package.json`: ```json { "name": "@repo/db", "private": true, "main": "src/index.ts", "types": "src/index.ts", "scripts": { "db:generate": "prisma generate", "db:push": "prisma db push", "db:migrate": "prisma migrate dev", "db:studio": "prisma studio", "db:test": "tsx scripts/test-database.ts" } } ``` --- ## Root Turbo pipeline (`turbo.json`) ```json { "globalEnv": ["DATABASE_URL"], "tasks": { "dev": { "cache": false, "persistent": true, "dependsOn": ["^db:generate"] }, "build": { "dependsOn": ["^db:generate"], "outputs": [".next/**", "dist/**"] }, "db:generate": { "cache": false }, "db:migrate": { "cache": false }, "db:studio": { "cache": false }, "db:test": { "cache": false, "dependsOn": ["db:generate"] } } } ``` --- ## Root scripts (`package.json`) ```json { "scripts": { "dev": "turbo dev", "build": "turbo build", "lint": "turbo lint", "db:generate": "turbo run db:generate", "db:push": "turbo run db:push", "db:migrate": "turbo run db:migrate", "db:studio": "turbo run db:studio", "db:test": "turbo run db:test" } } ``` --- ## Shared test script (`packages/db/scripts/test-database.ts`) ```ts import "dotenv/config"; import prisma from "../src/client"; async function testDatabase() { console.log("πŸ” Testing Prisma Postgres connection...\n"); try { console.log("βœ… Connected to database!"); console.log("\nπŸ“ Creating a test user..."); const newUser = await prisma.user.create({ data: { email: "demo@example.com", name: "Demo User", }, }); console.log("βœ… Created user:", newUser); console.log("\nπŸ“‹ Fetching all users..."); const allUsers = await prisma.user.findMany(); console.log(`βœ… Found ${allUsers.length} user(s):`); allUsers.forEach((user) => { console.log(` - ${user.name} (${user.email})`); }); console.log("\nπŸŽ‰ All tests passed! Your database is working.\n"); } catch (error) { console.error("❌ Error:", error); process.exit(1); } finally { await prisma.$disconnect(); } } testDatabase(); ``` --- ## Using Prisma in apps (example: `apps/web` Next.js) In any app, add a dependency on `@repo/db` (workspace): ```json { "dependencies": { "@repo/db": "*" } } ``` Then in server-side code: ```ts import { prisma } from "@repo/db"; import { NextResponse } from "next/server"; export async function GET() { try { const users = await prisma.user.findMany(); return NextResponse.json(users); } catch (e) { console.error(e); return NextResponse.json({ error: "Failed to fetch users" }, { status: 500 }); } } ``` --- ## Complete setup workflow 1. **Create Turborepo** (or use existing): ```npm npx create-turbo@latest ``` 2. **Add `packages/db`**, install Prisma v7 deps. 3. **Initialize Prisma in `packages/db`**: ```bash cd packages/db npx prisma init ``` 4. **Update `prisma.config.ts`** to include `import "dotenv/config"`. 5. **Update schema** with Prisma v7 generator + output. 6. **Create `src/client.ts`** singleton and export via `src/index.ts`. 7. **Wire Turbo tasks** in `turbo.json`. 8. **Add `.env`** at root **and/or** `packages/db/.env`. 9. **Push schema**: ```bash npm run db:push ``` 10. **Test**: ```bash npm run db:test ``` 11. **Start dev**: ```bash npm run dev ``` --- ## AI Model verification checklist Before generating any code, verify: 1. `provider = "prisma-client"`? 2. `output = "../src/generated/prisma"` present? 3. All Prisma files in `packages/db`? 4. Client imports from `../generated/prisma/client` (or via `@repo/db`)? 5. `import "dotenv/config"` in `packages/db/prisma.config.ts`? 6. Turbo tasks depend on `db:generate`? 7. `DATABASE_URL` listed in `globalEnv`? 8. All DB ops wrapped in try/catch? 9. Test script exists in `packages/db/scripts/test-database.ts`? No exceptions. If any check fails, STOP and FIX. --- ## AI MODEL RESPONSE TEMPLATE (UPDATED FOR TURBOREPO + PRISMA v7) When asked about implementing Prisma v7 inside a Turborepo monorepo (with any framework such as Next.js, Node, etc.), you MUST: 1. **Assume Prisma lives in a shared package** - Always place schema, config, and migrations in `packages/db`. - Never suggest adding Prisma directly into an app unless the user explicitly says they don’t want a shared package. 2. **Use only Prisma v7 generator patterns** - The schema MUST include: ```prisma generator client { provider = "prisma-client" output = "./generated/prisma" } ``` - Never use `prisma-client-js`. 3. **Use correct import paths for custom output** - Any PrismaClient import MUST come from the generated output: ```ts import { PrismaClient } from "./generated/prisma/client"; ``` - If importing from apps, you MUST import via the package boundary: ```ts import { prisma } from "@repo/db"; ``` - Never import from `@prisma/client` in this setup. 4. **Always include a shared singleton client in `packages/db`** - Provide a `packages/db/src/client.ts` with global caching for dev hot-reload. - If Accelerate is requested or implied, use `$extends(withAccelerate())`. - If Accelerate is not requested, omit it. 5. **Always load environment variables properly** - `packages/db/prisma.config.ts` MUST start with `import "dotenv/config"`. - Use `process.env.DATABASE_URL` in runtime code. - Remind users that `.env` should exist at root and/or `packages/db`. 6. **Always wire Turbo dependencies** - Turbo tasks `dev` and `build` MUST depend on `^db:generate`. - `DATABASE_URL` MUST be listed in `globalEnv` to ensure correct task hashing. 7. **Provide correct repo-level scripts** - Root scripts should proxy to Turbo (`turbo run db:*`). - The Prisma package `packages/db` should own `db:generate`, `db:migrate`, `db:studio`, and `db:test`. 8. **Include a real verification step** - Provide (or reference) `packages/db/scripts/test-database.ts`. - Ensure it imports dotenv and disconnects Prisma on completion. 9. **Use safe runtime patterns** - All DB calls in apps MUST be wrapped in try/catch. - In Next.js App Router examples, use server-only imports and return `NextResponse`. 10. **Self-verify before replying** - Re-check all items in the β€œAI Model verification checklist.” - If any item is missing or incorrect, STOP and FIX before responding. Remember: There are NO exceptions to these rules. Every requirement is mandatory for a correct Turborepo + Prisma v7 setup. ```` ## Running the application [#running-the-application] Run the application locally: **1. Generate the Prisma Client:** ```bash npx turbo db:generate ``` **2. View your database in Prisma Studio:** #### bun ```bash bunx turbo db:studio ``` #### pnpm ```bash pnpm dlx turbo db:studio ``` #### yarn ```bash yarn dlx turbo db:studio ``` #### npm ```bash npx turbo db:studio ``` Prisma Studio opens at `localhost:5555` where you can inspect your `User` table and see the test user stored in your database. ## Related pages - [`Astro + Prisma`](https://www.prisma.io/docs/ai/prompts/astro): Step-by-step guide for integrating Prisma ORM and Prisma Postgres in an Astro.js project - [`Migrate to Prisma v7`](https://www.prisma.io/docs/ai/prompts/prisma-7): Step-by-step guide for migration your app to use the version 7 of Prisma ORM - [`Next.js + Prisma`](https://www.prisma.io/docs/ai/prompts/nextjs): Step-by-step guide for integrating Prisma ORM and Prisma Postgres in an NextJS project - [`Nuxt + Prisma`](https://www.prisma.io/docs/ai/prompts/nuxt): Step-by-step guide for integrating Prisma ORM and Prisma Postgres in a Nuxt project