prisma
SKILL.md
Prisma ORM
Prisma is a next-generation ORM for Node.js and TypeScript. It provides type-safe database access, auto-generated migrations, and an intuitive data modeling language.
Core Concepts
Schema Definition (schema.prisma)
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(cuid())
email String @unique
name String?
password String
role Role @default(USER)
posts Post[]
profile Profile?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([email])
}
model Profile {
id String @id @default(cuid())
bio String?
avatar String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String @unique
}
model Post {
id String @id @default(cuid())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId String
tags Tag[]
comments Comment[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([authorId])
@@index([published, createdAt])
}
model Tag {
id String @id @default(cuid())
name String @unique
posts Post[]
}
model Comment {
id String @id @default(cuid())
content String
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
postId String
createdAt DateTime @default(now())
}
enum Role {
USER
ADMIN
MODERATOR
}
Client Setup
Singleton Pattern (Next.js)
// lib/prisma.ts
import { PrismaClient } from '@prisma/client';
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined;
};
export const prisma =
globalForPrisma.prisma ??
new PrismaClient({
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
});
if (process.env.NODE_ENV !== 'production') {
globalForPrisma.prisma = prisma;
}
With Extensions
const prisma = new PrismaClient().$extends({
result: {
user: {
fullName: {
needs: { firstName: true, lastName: true },
compute(user) {
return `${user.firstName} ${user.lastName}`;
},
},
},
},
});
CRUD Operations
Create
// Single record
const user = await prisma.user.create({
data: {
email: 'user@example.com',
name: 'John Doe',
profile: {
create: { bio: 'Developer' },
},
},
include: { profile: true },
});
// Multiple records
const users = await prisma.user.createMany({
data: [
{ email: 'user1@example.com', name: 'User 1' },
{ email: 'user2@example.com', name: 'User 2' },
],
skipDuplicates: true,
});
// With nested creation
const post = await prisma.post.create({
data: {
title: 'Hello World',
author: { connect: { id: userId } },
tags: {
connectOrCreate: [
{ where: { name: 'tech' }, create: { name: 'tech' } },
{ where: { name: 'news' }, create: { name: 'news' } },
],
},
},
});
Read
// Find unique
const user = await prisma.user.findUnique({
where: { email: 'user@example.com' },
include: { posts: true },
});
// Find many with filtering
const posts = await prisma.post.findMany({
where: {
published: true,
author: { email: { contains: '@example.com' } },
OR: [{ title: { contains: 'prisma' } }, { content: { contains: 'prisma' } }],
},
orderBy: { createdAt: 'desc' },
take: 10,
skip: 0,
select: {
id: true,
title: true,
author: { select: { name: true } },
},
});
// Pagination
const [posts, total] = await Promise.all([
prisma.post.findMany({
take: 10,
skip: (page - 1) * 10,
orderBy: { createdAt: 'desc' },
}),
prisma.post.count(),
]);
Update
// Single update
const user = await prisma.user.update({
where: { id: userId },
data: { name: 'Updated Name' },
});
// Update or create (upsert)
const user = await prisma.user.upsert({
where: { email: 'user@example.com' },
update: { name: 'Updated' },
create: { email: 'user@example.com', name: 'New User' },
});
// Update many
const result = await prisma.post.updateMany({
where: { authorId: userId },
data: { published: false },
});
// Atomic operations
const post = await prisma.post.update({
where: { id: postId },
data: {
views: { increment: 1 },
likes: { decrement: 1 },
},
});
Delete
// Single delete
await prisma.user.delete({
where: { id: userId },
});
// Delete many
await prisma.post.deleteMany({
where: {
published: false,
createdAt: { lt: new Date('2024-01-01') },
},
});
Transactions
Sequential Operations
const [posts, totalPosts, users] = await prisma.$transaction([
prisma.post.findMany({ where: { published: true } }),
prisma.post.count({ where: { published: true } }),
prisma.user.findMany(),
]);
Interactive Transactions
const result = await prisma.$transaction(
async (tx) => {
// Decrement sender balance
const sender = await tx.account.update({
where: { id: senderId },
data: { balance: { decrement: amount } },
});
if (sender.balance < 0) {
throw new Error('Insufficient funds');
}
// Increment receiver balance
const receiver = await tx.account.update({
where: { id: receiverId },
data: { balance: { increment: amount } },
});
return { sender, receiver };
},
{
maxWait: 5000,
timeout: 10000,
}
);
Relations
One-to-One
model User {
id String @id
profile Profile?
}
model Profile {
id String @id
user User @relation(fields: [userId], references: [id])
userId String @unique
}
One-to-Many
model User {
id String @id
posts Post[]
}
model Post {
id String @id
author User @relation(fields: [authorId], references: [id])
authorId String
}
Many-to-Many
model Post {
id String @id
tags Tag[]
}
model Tag {
id String @id
posts Post[]
}
Migrations
# Create migration
npx prisma migrate dev --name init
# Apply migrations (production)
npx prisma migrate deploy
# Reset database
npx prisma migrate reset
# Generate client
npx prisma generate
# Open Prisma Studio
npx prisma studio
Best Practices
- Use cuid() or uuid() for IDs instead of autoincrement
- Always include indexes for frequently queried fields
- Use select/include to avoid over-fetching
- Singleton pattern in Next.js to prevent connection exhaustion
- Interactive transactions for complex operations
- Soft deletes with
deletedAtfield for important data
References
- references/schema.md - Schema patterns
- references/query-patterns.md - Advanced queries
- references/migrations.md - Migration strategies
Weekly Installs
3
Repository
fractionestate/…v-skillsFirst Seen
Jan 31, 2026
Security Audits
Installed on
gemini-cli3
opencode2
replit2
antigravity2
claude-code2
github-copilot2