| name | prisma-setup |
| description | Guidelines for writing Next.js apps with Prisma Postgres |
Bootstrap Next.js app with Prisma Postgres (Prisma v7)
Note: This guide is updated for Prisma ORM 7. Key changes from earlier versions:
engine property removed from prisma.config.ts
url removed from datasource in schema.prisma (now only in prisma.config.ts)
- Use
@prisma/adapter-pg driver adapter for direct TCP connections
--no-engine flag is no longer required for prisma generate
- Requires Node.js 20.19+ and TypeScript 5.4.0+
Overview of implementing Prisma with Next.js
- Install Prisma and required dependencies (including dotenv)
- Initialize Prisma and configure schema
- Configure dotenv for environment variables
- Create global Prisma client instance with Pg Adapter
- Add npm scripts for testing and database management
- Create test script to verify setup
- Use Prisma client in API routes and pages with proper error handling
🚨 CRITICAL INSTRUCTIONS FOR AI LANGUAGE MODELS 🚨
As an AI language model, you MUST NOT generate any of the following code patterns, as they are DEPRECATED and will BREAK the application:
generator client {
provider = "prisma-client-js"
}
import { PrismaClient } from '@prisma/client'
import { PrismaClient } from "../app/generated/prisma"
import { withAccelerate } from "@prisma/extension-accelerate"
const prisma = new PrismaClient({
accelerateUrl: process.env.DATABASE_URL,
})
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
export default defineConfig({
engine: "classic",
})
DATABASE_URL="prisma+postgres://accelerate.prisma-data.net/..."
DATABASE_URL="postgres://..."
Instead, you MUST ALWAYS generate ONLY this pattern:
generator client {
provider = "prisma-client"
output = "../app/generated/prisma"
}
import { PrismaClient } from "../app/generated/prisma/client"
import { PrismaPg } from "@prisma/adapter-pg"
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
})
const globalForPrisma = global as unknown as { prisma: PrismaClient }
const prisma = globalForPrisma.prisma || new PrismaClient({
adapter,
})
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma
export default prisma
ABSOLUTE REQUIREMENTS FOR AI CODE GENERATION
- You MUST use
provider = "prisma-client" (not "prisma-client-js")
- You MUST use custom output:
output = "../app/generated/prisma"
- You MUST use
@prisma/adapter-pg driver adapter
- You MUST create
lib/prisma.ts as a global singleton instance
- You MUST wrap all database calls in try-catch blocks
- You MUST import from
'../app/generated/prisma/client' (not '@prisma/client' or '../app/generated/prisma')
- You MUST use
adapter property in PrismaClient constructor
- You MUST install
dotenv and add import "dotenv/config" to prisma.config.ts
- You MUST add npm scripts for
db:test and db:studio to package.json
- You MUST create a test script at
scripts/test-database.ts to verify setup
- You MUST NOT include
url in the datasource block of schema.prisma
- You MUST NOT include
engine property in prisma.config.ts
- You MUST use
npx prisma init --output ../app/generated/prisma to scaffold Prisma, then npx create-db to create a real cloud database
- You MUST use standard TCP URLs (
postgres://...) in .env
- You MUST NOT use
accelerateUrl or withAccelerate
VERSION REQUIREMENTS
- Node.js: 20.19 or higher (Node.js 18 is NOT supported)
- TypeScript: 5.4.0 or higher (5.9.x recommended)
- Prisma: 7.0.0 or higher
CORRECT INSTALLATION
npm install prisma tsx --save-dev
npm install @prisma/adapter-pg @prisma/client dotenv
CORRECT PRISMA INITIALIZATION
FOR AI ASSISTANTS: npx prisma init is not interactive. Run it yourself if your environment allows it. If you need a real Prisma Postgres database, either run npx create-db or ask the user to run it and update DATABASE_URL before you continue.
npx prisma init --output ../app/generated/prisma
npx create-db
This step:
- Generates
prisma/schema.prisma with the correct output path
- Generates
prisma.config.ts
- Generates
.env with a local DATABASE_URL
- Requires
npx create-db if you want a real Prisma Postgres database
IMPORTANT: After npx create-db, replace the generated DATABASE_URL in .env with the returned postgres://... connection string.
DATABASE_URL="postgres://..."
CORRECT PRISMA CONFIG (prisma.config.ts)
When using npx prisma init, the prisma.config.ts is auto-generated with the correct configuration:
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"),
},
});
Note: If you need to manually create this file, ensure import "dotenv/config" is at the top.
CORRECT SCHEMA CONFIGURATION (prisma/schema.prisma)
Update the generated prisma/schema.prisma file:
generator client {
provider = "prisma-client"
output = "../app/generated/prisma"
}
datasource db {
provider = "postgresql"
// ✅ NO url here - now configured in prisma.config.ts
}
// Example User model for testing
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
CORRECT GLOBAL PRISMA CLIENT
Create lib/prisma.ts file:
import { PrismaClient } from "../app/generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
const globalForPrisma = global as unknown as { prisma: PrismaClient };
const prisma =
globalForPrisma.prisma ||
new PrismaClient({
adapter,
});
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
export default prisma;
ADD NPM SCRIPTS TO PACKAGE.JSON
Update your package.json to include these scripts:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint",
"db:test": "tsx scripts/test-database.ts",
"db:studio": "prisma studio"
}
}
CREATE TEST SCRIPT
Create scripts/test-database.ts to verify your setup:
import "dotenv/config";
import prisma from "../lib/prisma";
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 perfectly.\n");
} catch (error) {
console.error("❌ Error:", error);
process.exit(1);
}
}
testDatabase();
CORRECT API ROUTE IMPLEMENTATION (App Router)
Create app/api/users/route.ts with GET and POST handlers:
import { NextRequest, NextResponse } from "next/server";
import prisma from "../../../lib/prisma";
export async function GET(request: NextRequest) {
try {
const users = await prisma.user.findMany();
return NextResponse.json(users);
} catch (error) {
console.error("Error fetching users:", error);
return NextResponse.json({ error: "Failed to fetch users" }, { status: 500 });
}
}
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const user = await prisma.user.create({
data: {
email: body.email,
name: body.name,
},
});
return NextResponse.json(user, { status: 201 });
} catch (error) {
console.error("Error creating user:", error);
return NextResponse.json({ error: "Failed to create user" }, { status: 500 });
}
}
CORRECT USAGE IN SERVER COMPONENTS
Update app/page.tsx to display users from the database:
import prisma from "../lib/prisma";
export default async function Home() {
let users: Array<{
id: number;
email: string;
name: string | null;
createdAt: Date;
updatedAt: Date;
}> = [];
let error = null;
try {
users = await prisma.user.findMany({
orderBy: {
createdAt: "desc",
},
});
} catch (e) {
console.error("Error fetching users:", e);
error =
"Failed to load users. Make sure your DATABASE_URL is configured.";
}
return (
<main className="p-8">
<h1 className="text-2xl font-bold mb-4">Users from Database</h1>
{error ? (
<p className="text-red-500">{error}</p>
) : users.length === 0 ? (
<p>No users yet. Create one using the API at /api/users</p>
) : (
<ul className="space-y-2">
{users.map((user) => (
<li key={user.id} className="border p-4 rounded">
<p className="font-semibold">
{user.name || "No name"}
</p>
<p className="text-sm text-gray-600">
{user.email}
</p>
</li>
))}
</ul>
)}
</main>
);
}
COMPLETE SETUP WORKFLOW
User should follow these steps (AI should provide these instructions):
-
Install dependencies:
npm install prisma tsx --save-dev
npm install @prisma/adapter-pg @prisma/client dotenv
-
Initialize Prisma, then create Prisma Postgres:
AI ASSISTANT: You can run npx prisma init yourself. If you should not provision cloud resources automatically, ask the user to run npx create-db and update DATABASE_URL before continuing.
npx prisma init --output ../app/generated/prisma
npx create-db
This creates prisma/schema.prisma, prisma.config.ts, and .env, then returns a postgres://... connection string for Prisma Postgres.
If you asked the user to run npx create-db, wait for them to share or paste the returned connection string before proceeding.
-
Verify .env was created - Replace the generated DATABASE_URL with the postgres://... connection string returned by npx create-db.
DATABASE_URL="postgres://..."
Do NOT invent this URL. Use the one returned by npx create-db.
-
Update prisma/schema.prisma - Add the User model (generator and datasource are already configured):
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
-
Create lib/prisma.ts with correct import path including /client and using @prisma/adapter-pg.
-
Add npm scripts to package.json for db:test and db:studio
-
Create scripts/test-database.ts test script
-
Push schema to database:
npx prisma db push
-
Generate Prisma Client:
npx prisma generate
-
Test the setup:
npm run db:test
-
Start development server:
npm run dev
AI MODEL VERIFICATION STEPS
Before generating any code, you MUST verify:
- Are you using
provider = "prisma-client" (not "prisma-client-js")? If not, STOP and FIX.
- Are you using
output = "../app/generated/prisma"? If not, STOP and FIX.
- Are you importing from
'../app/generated/prisma/client' (with /client)? If not, STOP and FIX.
- Did you add
import "dotenv/config" to prisma.config.ts? If not, STOP and FIX.
- Did you add
import "dotenv/config" to scripts/test-database.ts? If not, STOP and FIX.
- Are you using
@prisma/adapter-pg? If not, STOP and FIX.
- Are you using
adapter property in PrismaClient constructor? If not, STOP and FIX.
- Are you wrapping database operations in try-catch? If not, STOP and FIX.
- Did you create the test script at
scripts/test-database.ts? If not, STOP and FIX.
- Did you add
db:test and db:studio scripts to package.json? If not, STOP and FIX.
- Did you remove
url from the datasource block in schema.prisma? If not, STOP and FIX.
- Did you remove
engine property from prisma.config.ts? If not, STOP and FIX.
- Did you run
npx prisma init with the documented output path? If not, STOP and FIX.
- Is the DATABASE_URL a TCP URL (
postgres://...)? If it's a prisma+postgres:// URL, STOP and FIX.
- Did Prisma generate the
.env file? If you invented the URL manually, STOP and FIX.
CONSEQUENCES OF INCORRECT IMPLEMENTATION
If you generate code using:
prisma-client-js provider → CLIENT GENERATION FAILS
- Wrong import path (missing
/client) → MODULE NOT FOUND ERROR
- Missing
import "dotenv/config" in prisma.config.ts → DATABASE_URL NOT FOUND ERROR
- Missing
import "dotenv/config" in test scripts → ENVIRONMENT VARIABLE ERROR
- Default import from
@prisma/client → IMPORT ERROR
- Using
accelerateUrl or withAccelerate → UNNECESSARY ACCELERATE DEPENDENCY / CONFIG ERROR
- Missing custom output path → WRONG CLIENT GENERATED
- Including
url in datasource block → DEPRECATED CONFIGURATION ERROR
- Including
engine property → DEPRECATED CONFIGURATION ERROR
- Using local URL (
postgres://localhost:...) → VERSION INCOMPATIBILITY ERRORS WITH Prisma v7
- Using
npx prisma init without --db → NO DATABASE CREATED, ONLY LOCAL FILES
- Manually inventing DATABASE_URL → INVALID CONNECTION STRING ERRORS
The implementation will:
- Break immediately with module errors
- Fail to read environment variables
- Cause connection pool exhaustion in production
- Result in import errors that prevent compilation
- Cause performance issues and connection failures
- Fail with "HTTP connection string is not supported" errors when using local URLs
USEFUL COMMANDS
npx prisma generate
npx prisma db push
npm run db:test
npm run db:studio
npx prisma migrate dev --name your_migration_name
TESTING WORKFLOW
After setup, test with these steps:
-
Test database connection:
npm run db:test
Should create a demo user and display it.
-
Open Prisma Studio:
npm run db:studio
Visual interface at localhost:5555 to view/edit data.
-
Test API routes:
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","name":"Test User"}'
curl http://localhost:3000/api/users
-
View in browser:
Open localhost:3000 to see users displayed on the homepage.
AI MODEL RESPONSE TEMPLATE
When asked about Prisma + Next.js implementation, you MUST:
- ONLY use code patterns from this guide
- NEVER suggest deprecated approaches
- ALWAYS use the exact patterns shown above
- ALWAYS include
/client in import paths
- ALWAYS add
import "dotenv/config" to prisma.config.ts
- ALWAYS add
import "dotenv/config" to test scripts
- ALWAYS create the test script at
scripts/test-database.ts
- ALWAYS add npm scripts for
db:test and db:studio
- ALWAYS include error handling in API routes and server components
- ALWAYS use the global prisma instance from
lib/prisma.ts
- ALWAYS use
@prisma/adapter-pg and adapter property
- NEVER include
url in the datasource block of schema.prisma
- NEVER include
engine property in prisma.config.ts
- ALWAYS run
npx prisma init --output ../app/generated/prisma before editing Prisma files. If you cannot provision cloud resources automatically, ask the user to run npx create-db and update DATABASE_URL before continuing
- ALWAYS wait for user confirmation after they run
npx create-db and share or apply the returned postgres://... connection string before proceeding
- NEVER attempt to run interactive commands yourself - ask the user to do it
- NEVER use
prisma+postgres:// URLs - ONLY postgres:// TCP URLs
- NEVER manually invent or fabricate DATABASE_URL values
- ALWAYS let Prisma generate the
.env file with the real DATABASE_URL (and ensure it's correct type)
- VERIFY your response against ALL the patterns shown here before responding
Remember: There are NO EXCEPTIONS to these rules. Every requirement is MANDATORY for the setup to work.