DEV Community

Sameer Saleem
Sameer Saleem

Posted on

The Ultimate Guide to Prisma ORM + PostgreSQL (2025 Edition)

1. Project Initialization

Start by setting up your Node.js environment with TypeScript. We use tsx for modern, fast execution.

mkdir prisma-postgres-2025
cd prisma-postgres-2025
npm init -y
npm install typescript tsx @types/node --save-dev
npx tsc --init

Enter fullscreen mode Exit fullscreen mode

2. Install Prisma and PostgreSQL Driver

In 2025, it is highly recommended to install the official PostgreSQL adapter for better performance in serverless and edge environments.

npm install prisma --save-dev
npm install @prisma/client @prisma/adapter-pg pg

Enter fullscreen mode Exit fullscreen mode

3. Initialize Prisma

Run the following to generate your boilerplate. This creates the prisma/schema.prisma file and a .env file.

npx prisma init --datasource-provider postgresql

Enter fullscreen mode Exit fullscreen mode

4. Configure Your Connection

Open your .env file. PostgreSQL connection strings follow this format:

# Format: postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=public
DATABASE_URL="postgresql://postgres:mypassword@localhost:5432/mydb?schema=public"

Enter fullscreen mode Exit fullscreen mode

5. Define Your Modern Schema

In prisma/schema.prisma, define your models. As Allyn noted, these act as the "proxy" to your database.

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
  posts Post[]
}

model Post {
  id        Int     @id @default(autoincrement())
  title     String
  content   String?
  published Boolean @default(false)
  author    User    @relation(fields: [authorId], references: [id])
  authorId  Int
}

Enter fullscreen mode Exit fullscreen mode

6. Apply Migrations

Use Prisma Migrate to push your schema to PostgreSQL. This creates the actual tables and generates your type-safe client.

npx prisma migrate dev --name init

Enter fullscreen mode Exit fullscreen mode

7. Instantiate the Client (Singleton Pattern)

To prevent "Too many connections" errors in PostgreSQL (especially during development with hot-reloading), use this singleton pattern:

// db.ts
import { PrismaClient } from '@prisma/client'

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

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

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

Enter fullscreen mode Exit fullscreen mode

8. Performing CRUD Operations

Now you can write fully type-safe queries. Prisma handles the PostgreSQL JOINs and relations automatically.

import { prisma } from './db'

async function run() {
  // Create a user and a post in one transaction
  const user = await prisma.user.create({
    data: {
      email: 'hello@dev.to',
      name: 'Dev Reader',
      posts: {
        create: { title: 'Learning Prisma in 2025' }
      }
    }
  })

  // Read: Fetch all users and include their posts
  const allUsers = await prisma.user.findMany({
    include: { posts: true }
  })

  console.log(JSON.stringify(allUsers, null, 2))
}

run()

Enter fullscreen mode Exit fullscreen mode

🚀 What’s New for PostgreSQL in 2025?

  • Rust-Free Engine: Prisma 6/7 moved to a TypeScript-based engine. This means faster cold starts and smaller Docker images when deploying your Postgres app.
  • TypedSQL: You can now write raw SQL in .sql files, and Prisma will generate TypeScript types for them—giving you the power of raw SQL with the safety of an ORM.
  • Prisma Studio: As mentioned by Allyn, run npx prisma studio to get a visual dashboard of your PostgreSQL data. It’s the easiest way to debug your records without a separate DB manager.

Pro-Tip: If you are using a hosted PostgreSQL provider like Supabase or Neon, ensure you use their "Connection Pooling" strings in your .env to handle high traffic efficiently.

Top comments (0)