The Complete Guide to Building with Prisma ORM in 2026: From Setup to Production
Prisma remained the most popular ORM for TypeScript projects in 2025-2026, especially with Next.js and serverless backends. Its type-safe database access and automatic migrations make it the go-to choice for TypeScript developers.
Here's the practical guide.
Setup
npm install prisma --save-dev
npx prisma init
Schema Definition
// prisma/schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(uuid())
email String @unique
name String?
posts Post[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([email])
}
model Post {
id String @id @default(uuid())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([authorId])
}
Generate Client and Migrate
npx prisma generate # Generate TypeScript types
npx prisma migrate dev # Create migration and apply
Basic Queries
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
// Create
const user = await prisma.user.create({
data: {
email: "alice@example.com",
name: "Alice",
posts: {
create: {
title: "My First Post",
content: "Hello world!",
},
},
},
include: { posts: true },
});
// Find many with filters
const users = await prisma.user.findMany({
where: {
email: { contains: "@example.com" },
posts: { some: { published: true } },
},
orderBy: { createdAt: "desc" },
take: 10,
skip: 0,
});
// Find unique
const post = await prisma.post.findUnique({
where: { id: "post-id-here" },
include: { author: true },
});
Update and Delete
// Update
await prisma.user.update({
where: { id: "user-id" },
data: {
name: "Alice Updated",
posts: {
updateMany: {
where: { published: false },
data: { published: true },
},
},
},
});
// Delete
await prisma.post.delete({
where: { id: "post-id" },
});
// Cascade delete
// In schema: author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
Transactions
const result = await prisma.$transaction(async (tx) => {
const user = await tx.user.create({
data: { email: "bob@example.com", name: "Bob" },
});
await tx.post.create({
data: {
title: "Bob's Post",
authorId: user.id,
published: true,
},
});
return user;
});
With Next.js App Router
// app/users/route.ts
import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
export async function GET() {
const users = await prisma.user.findMany({
include: { posts: true },
});
return NextResponse.json(users);
}
export async function POST(request: Request) {
const body = await request.json();
const user = await prisma.user.create({
data: {
email: body.email,
name: body.name,
},
});
return NextResponse.json(user, { status: 201 });
}
Raw Queries
// When you need raw SQL
const result = await prisma.$queryRaw`
SELECT * FROM "User"
WHERE "email" LIKE ${"%@example.com"}
ORDER BY "createdAt" DESC
`;
This article contains affiliate links. If you sign up through the links above, I may earn a commission at no additional cost to you.
Ready to Build Your Online Business?
Get started with Systeme.io for free — All-in-one platform for building your online business with AI tools.
Top comments (0)