Using Prisma ORM

Modern database toolkit for Next.js

🗄️ What is Prisma?

Prisma is a modern database toolkit that makes database access easy with type-safe queries. It provides an intuitive API, automatic migrations, and works seamlessly with Next.js for building data-driven applications.


const user = await prisma.user.create({
  data: { name: 'John', email: '[email protected]' }
})
                                    

Key Prisma Features

Type Safety

Auto-generated TypeScript types

IntelliSense Type Checking Auto-complete
🔄

Migrations

Automatic database schema management

Version Control Auto-sync Rollback
📊

Prisma Studio

Visual database browser and editor

GUI Edit Data Browse
🌐

Multi-Database

Support for multiple databases

PostgreSQL MySQL SQLite

🔹 Installation & Setup

Install Prisma and initialize it in your Next.js project. This creates the necessary configuration files and sets up the Prisma schema where you'll define your database models.

# Install Prisma
npm install prisma @prisma/client

# Initialize Prisma
npx prisma init

🔸 Configure Database

# .env
DATABASE_URL="postgresql://user:password@localhost:5432/mydb"

Result:

✅ Prisma installed

✅ Schema file created

✅ Database connected

🔹 Define Schema

Create your database models in the Prisma schema file. Models define tables, fields, relationships, and constraints using an intuitive syntax that's easy to read and maintain.

// prisma/schema.prisma
generator client {
  provider = "prisma-client-js"
}

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

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

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

Schema features:

  • @id - Primary key field
  • @unique - Unique constraint
  • @default - Default values
  • @relation - Define relationships

🔹 Run Migrations

Create and apply database migrations based on your schema changes. Migrations track all database changes over time, allowing you to version control your database structure.

# Create migration
npx prisma migrate dev --name init

# Apply migrations to production
npx prisma migrate deploy

# Generate Prisma Client
npx prisma generate

Result:

✅ Database tables created

✅ Migration files generated

✅ Prisma Client updated

🔹 Prisma Client Setup

Create a singleton Prisma Client instance to use across your application. This prevents creating multiple database connections and ensures optimal performance in development and production.

🔸 Create Client Instance

// lib/prisma.js
import { PrismaClient } from '@prisma/client'

const globalForPrisma = global

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

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

🔸 Usage in API Routes

// app/api/users/route.js
import { prisma } from '@/lib/prisma'
import { NextResponse } from 'next/server'

export async function GET() {
  const users = await prisma.user.findMany()
  return NextResponse.json(users)
}

🔹 CRUD Operations

Perform Create, Read, Update, and Delete operations with Prisma's intuitive API. All operations are type-safe and provide excellent IntelliSense support in your editor.

🔸 Create

const user = await prisma.user.create({
  data: {
    email: '[email protected]',
    name: 'John Doe',
  },
})

🔸 Read

// Find all users
const users = await prisma.user.findMany()

// Find one user
const user = await prisma.user.findUnique({
  where: { email: '[email protected]' },
})

// Find with filter
const users = await prisma.user.findMany({
  where: { name: { contains: 'John' } },
})

🔸 Update

const user = await prisma.user.update({
  where: { id: 1 },
  data: { name: 'Jane Doe' },
})

🔸 Delete

const user = await prisma.user.delete({
  where: { id: 1 },
})

🔹 Relations & Includes

Query related data easily with Prisma's include and select options. This allows you to fetch nested data in a single query, reducing database round trips.

🔸 Include Related Data

const user = await prisma.user.findUnique({
  where: { id: 1 },
  include: {
    posts: true, // Include all posts
  },
})

🔸 Nested Includes

const user = await prisma.user.findUnique({
  where: { id: 1 },
  include: {
    posts: {
      where: { published: true },
      orderBy: { createdAt: 'desc' },
    },
  },
})

🔸 Select Specific Fields

const users = await prisma.user.findMany({
  select: {
    id: true,
    email: true,
    name: true,
  },
})

🔹 Server Actions with Prisma

Use Prisma in Next.js Server Actions for seamless data mutations. Server Actions provide a simple way to handle form submissions and data updates without creating API routes.

// app/actions.js
'use server'
import { prisma } from '@/lib/prisma'
import { revalidatePath } from 'next/cache'

export async function createPost(formData) {
  const title = formData.get('title')
  const content = formData.get('content')

  await prisma.post.create({
    data: {
      title,
      content,
      authorId: 1,
    },
  })

  revalidatePath('/posts')
}

// app/new-post/page.js
import { createPost } from '@/app/actions'

export default function NewPost() {
  return (
    <form action={createPost}>
      <input name="title" placeholder="Title" />
      <textarea name="content" placeholder="Content" />
      <button type="submit">Create Post</button>
    </form>
  )
}

🔹 Prisma Studio

Use Prisma Studio to visually browse and edit your database. This GUI tool makes it easy to view data, test queries, and manage records without writing SQL.

# Open Prisma Studio
npx prisma studio

Prisma Studio features:

  • Visual database browser
  • Edit records directly
  • Filter and search data
  • View relationships
  • Runs on localhost:5555

🧠 Test Your Knowledge

What command generates the Prisma Client?