Building a Full-Stack App with Next.js 15 and Prisma
A deep dive into setting up a type-safe data layer with Prisma ORM and PostgreSQL inside a Next.js App Router project — pitfalls included.
When I set out to migrate my portfolio's project list from a static TypeScript array to a real database, I underestimated just how many sharp edges the Prisma 7 → Prisma 5 downgrade journey would involve. Here's what I learned.
Why Prisma?
Prisma provides an end-to-end type-safe ORM experience. The generated client mirrors your schema, so TypeScript catches mismatches at compile time — not at 2 AM in production.
The Generator Trap
Prisma 7 ships with a new prisma-client generator that requires either Prisma Accelerate or a driver adapter. If you're pointing straight at PostgreSQL (as most projects do), you'll hit a cryptic runtime error about accelerateUrl being undefined. The fix? Downgrade to Prisma 5 and use the battle-tested prisma-client-js generator.
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
The Singleton Pattern
Next.js dev mode re-evaluates modules on every request in certain scenarios, which can exhaust your connection pool quickly. The fix is a global singleton:
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
export const prisma =
globalForPrisma.prisma ?? new PrismaClient({ log: ['error', 'warn'] });
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;
Takeaways
- Pin major Prisma versions in package.json until the ecosystem catches up.
- Always run
prisma migrate deployin your build command on Render/Vercel. - Keep your seed file idempotent with
upsert— never plaincreate.