Building a Full-Stack App with Next.js & Prisma: Part 1 – Setting Up the Database Client



This content originally appeared on DEV Community and was authored by Ankit

0) Mental Model – What happens on a request?

  1. User hits a route → middleware.ts checks whether they’re logged in and whether the route is public/protected/auth.
  2. If sign-in is needed, user goes to /auth/sign-in and chooses Google or GitHub.
  3. NextAuth + PrismaAdapter look up the user; if new, create User + Account; if existing, link the provider.
  4. Callbacks enrich the JWT and session with id and role.
  5. Client now has session.user.id and session.user.role for RBAC and UI.

1) Database Client (Prisma) — lib/db.ts

import { PrismaClient } from "@prisma/client"

const globalForPrisma = globalThis as unknown as { prisma: PrismaClient }

export const db = globalForPrisma.prisma || new PrismaClient()

if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = db

At first glance, this may look a bit tricky. Let’s break it down.

import { PrismaClient } from "@prisma/client"
  • PrismaClient is the main tool you use to talk to your database
  • Think of it like a “bridge” that connects your code with your database (MySQL, PostgreSQL, SQLite, etc.).
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient }
  • In Next.js (or any serverless environment), new instances of the code can spin up frequently.
  • If you create a new database client every time, you risk having too many open connections.
  • To prevent this, we attach Prisma to the global object (globalThis), so it can be reused.

This ensures that if Prisma is already created, we don’t create it again.

export const db = globalForPrisma.prisma || new PrismaClient()
  • Here, we check:
    • If a Prisma instance already exists (globalForPrisma.prisma), use it.
    • Otherwise, create a new one (new PrismaClient()).

This is the key step that prevents multiple Prisma clients from being created unnecessarily.

if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = db
  • In development mode, your app refreshes and hot-reloads often.
  • Without this line, Prisma would create a new connection each time, eventually causing errors like: “Too many connections”.
  • This line ensures the same db instance is reused during development.

In production, Next.js doesn’t hot-reload, so we don’t need this safeguard.

So Why Does This Matters

  • ✅ Prevents performance issues caused by too many connections.
  • ✅ Works well with Next.js serverless functions.
  • ✅ Shows professionalism: any recruiter or developer reviewing your code will see you understand real-world database issues.

Finally

This small snippet may look simple, but it solves a very common real-world problem.


This content originally appeared on DEV Community and was authored by Ankit