Database connection in NextJS (App Router)

Published: (January 4, 2026 at 11:50 AM EST)
2 min read
Source: Dev.to

Source: Dev.to

Introduction

In this post we’ll explore a reliable way to connect a Next.js application (App Router) to a database using Prisma ORM.

What is Prisma ORM?

Prisma (Object‑Relational Mapping) simplifies communication with databases. Instead of writing raw SQL queries for MySQL, PostgreSQL, SQLite, or MongoDB, you work with a type‑safe client that abstracts the underlying syntax.

Benefits of using an ORM

  • No need to remember database‑specific query syntax.
  • Reduces debugging time caused by small mistakes.
  • Makes switching databases easier.

Connecting Prisma in the Next.js App Router

Below is a minimal yet production‑ready setup for a Prisma client that works well with Next.js’ App Router.

// lib/prisma.ts
import { PrismaClient } from "@/generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";

const globalForPrisma = globalThis as unknown as {
  prisma: PrismaClient | undefined;
};

const connectionString = `${process.env.DATABASE_URL}`;

const adapter = new PrismaPg({ connectionString });

export const prisma =
  globalForPrisma.prisma || new PrismaClient({ adapter });

if (process.env.NODE_ENV !== "production") {
  globalForPrisma.prisma = prisma;
}

How it works

  1. Adapter creationPrismaPg receives the connection string from process.env.DATABASE_URL.
  2. Singleton pattern – The client is stored in a global variable (globalForPrisma.prisma).
    • In production, the same Prisma instance is reused across requests on the same server instance, preventing the creation of a new DB connection for every request.
    • In development, hot‑reloading would otherwise create a new client on each reload. Storing the client globally ensures only one connection is opened during development.

Why the extra code?

When a Next.js app is deployed, multiple server instances may run concurrently. Each instance can handle many incoming requests, but we don’t want a separate database connection for every request.

  • Module caching: Importing the Prisma client module reuses the already‑created instance on the same server instance.
  • Global store (development): Hot‑module replacement in dev mode would otherwise instantiate a new client on every reload, leading to many unnecessary connections. The global cache prevents that.

By following this pattern, you keep the number of active database connections low while still enjoying Prisma’s type‑safe API.

Back to Blog

Related posts

Read more »