Prisma 5+ ORM with schema-first design, type-safe client, migrations, and database integrations (Supabase, PlanetScale, Neon). Use for TypeScript/JavaScript database access.
Generates type-safe Prisma ORM schemas, migrations, and database operations for TypeScript/JavaScript projects.
/plugin marketplace add FortiumPartners/ensemble/plugin install ensemble-development@ensembleThis skill inherits all available tools. When active, it can use any tool Claude has access to.
README.mdREFERENCE.mdVALIDATION.mdexamples/multi_database.example.tsexamples/nestjs_prisma.example.tsexamples/schema_patterns.example.prismaexamples/supabase_integration.example.tstemplates/README.mdtemplates/client.template.tstemplates/migration.template.tstemplates/model.template.prismatemplates/repository.template.tstemplates/rls_migration.template.sqltemplates/schema.template.prismatemplates/seed.template.tstemplates/supabase_schema.template.prismaVersion: 1.1.0 | Target: <500 lines | Purpose: Fast reference for Prisma operations
What is Prisma: Type-safe ORM with schema-first design for TypeScript/JavaScript. Auto-generates client from schema with full IntelliSense support.
When to Use This Skill:
Auto-Detection Triggers:
schema.prisma file present@prisma/client in dependenciesprisma in devDependenciesProgressive Disclosure:
my_project/
├── prisma/
│ ├── schema.prisma # Schema definition
│ ├── migrations/ # Migration history
│ └── seed.ts # Database seeding
├── src/
│ └── lib/prisma.ts # Client singleton
└── package.json
// PostgreSQL (local)
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// Supabase (with pooling) - see Database Integrations
datasource db {
provider = "postgresql"
url = env("DATABASE_URL") // Pooled connection
directUrl = env("DIRECT_URL") // Direct for migrations
}
generator client {
provider = "prisma-client-js"
}
model User {
id String @id @default(cuid())
email String @unique
name String
bio String? // Optional
role Role @default(USER)
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
posts Post[] // Relation
@@index([email])
}
enum Role {
USER
ADMIN
}
| Type | Example | Notes |
|---|---|---|
String | name String | Text |
String? | bio String? | Optional text |
Int | count Int | Integer |
Float | price Float | Decimal |
Boolean | active Boolean | true/false |
DateTime | createdAt DateTime | Timestamp |
Json | metadata Json | JSON object |
String[] | tags String[] | PostgreSQL array |
More patterns: See REFERENCE.md - Schema Design Patterns for soft delete, audit fields, polymorphic relations, and multi-tenancy patterns.
npx prisma init # Initialize Prisma
npx prisma generate # Generate client after schema changes
npx prisma db push # Push schema (no migrations)
npx prisma migrate dev --name init # Create migration
npx prisma migrate reset # Reset database
npx prisma studio # Open GUI
npx prisma generate # Generate client (required in CI)
npx prisma migrate deploy # Apply pending migrations
npx prisma migrate status # Check migration status
npx prisma db pull # Pull schema from existing DB
npx prisma validate # Validate schema
npx prisma format # Format schema file
// src/lib/prisma.ts
import { PrismaClient } from "@prisma/client";
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined;
};
export const prisma = globalForPrisma.prisma ?? new PrismaClient();
if (process.env.NODE_ENV !== "production") {
globalForPrisma.prisma = prisma;
}
// Create
const user = await prisma.user.create({
data: { email: "user@example.com", name: "John" },
});
// Read
const user = await prisma.user.findUnique({
where: { id: "user_id" },
});
// Update
const updated = await prisma.user.update({
where: { id: "user_id" },
data: { name: "New Name" },
});
// Upsert
const upserted = await prisma.user.upsert({
where: { email: "user@example.com" },
update: { name: "Updated" },
create: { email: "user@example.com", name: "New" },
});
// Delete
const deleted = await prisma.user.delete({
where: { id: "user_id" },
});
const users = await prisma.user.findMany({
where: {
email: { contains: "@example.com" },
role: { in: ["ADMIN", "USER"] },
createdAt: { gte: new Date("2024-01-01") },
OR: [
{ name: { startsWith: "John" } },
{ name: { startsWith: "Jane" } },
],
},
});
// Offset pagination
const users = await prisma.user.findMany({
skip: (page - 1) * pageSize,
take: pageSize,
orderBy: { createdAt: "desc" },
});
// Cursor pagination (more efficient)
const users = await prisma.user.findMany({
take: 10,
cursor: { id: "last_seen_id" },
skip: 1,
});
// Select specific fields
const users = await prisma.user.findMany({
select: { id: true, name: true, email: true },
});
// Include relations
const users = await prisma.user.findMany({
include: { posts: { where: { published: true }, take: 5 } },
});
More patterns: See REFERENCE.md - Query Optimization for N+1 prevention, cursor pagination, and aggregation patterns.
model User {
id String @id @default(cuid())
posts Post[]
}
model Post {
id String @id @default(cuid())
author User @relation(fields: [authorId], references: [id])
authorId String
@@index([authorId])
}
model Post {
id String @id @default(cuid())
categories Category[]
}
model Category {
id String @id @default(cuid())
posts Post[]
}
// Create with relation
const user = await prisma.user.create({
data: {
email: "author@example.com",
posts: { create: { title: "First Post" } },
},
include: { posts: true },
});
// Filter by relation
const usersWithPosts = await prisma.user.findMany({
where: { posts: { some: { published: true } } },
});
More patterns: See REFERENCE.md - Advanced Relations for self-relations, polymorphic patterns, and explicit many-to-many.
const result = await prisma.$transaction(async (tx) => {
const order = await tx.order.create({ data: orderData });
await tx.inventory.update({
where: { id: productId },
data: { stock: { decrement: 1 } },
});
if ((await tx.inventory.findUnique({ where: { id: productId } }))!.stock < 0) {
throw new Error("Insufficient stock");
}
return order;
});
const [users, posts] = await prisma.$transaction([
prisma.user.findMany(),
prisma.post.findMany(),
]);
More patterns: See REFERENCE.md - Transactions & Concurrency for isolation levels, optimistic locking, and deadlock prevention.
datasource db {
provider = "postgresql"
url = env("DATABASE_URL") // Transaction pooler
directUrl = env("DIRECT_URL") // Direct for migrations
}
DATABASE_URL="postgres://postgres.[ref]:password@aws-0-region.pooler.supabase.com:6543/postgres?pgbouncer=true"
DIRECT_URL="postgres://postgres.[ref]:password@aws-0-region.supabase.com:5432/postgres"
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
relationMode = "prisma" // Required: no foreign keys
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
directUrl = env("DIRECT_URL")
}
More patterns: See REFERENCE.md - Database Integrations for Supabase Auth integration, connection pooling, and edge runtime setup.
| Code | Description | Resolution |
|---|---|---|
| P2002 | Unique constraint failed | Duplicate value |
| P2003 | Foreign key constraint failed | Missing relation |
| P2025 | Record not found | Update/delete on missing record |
| P2024 | Connection pool timeout | Too many connections |
import { Prisma } from "@prisma/client";
try {
await prisma.user.create({ data });
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
if (error.code === "P2002") {
throw new ConflictError("Email already exists");
}
if (error.code === "P2025") {
throw new NotFoundError("Record not found");
}
}
throw error;
}
More patterns: See REFERENCE.md - Error Handling for comprehensive error mapping and retry strategies.
import { mockDeep, DeepMockProxy } from "jest-mock-extended";
import { PrismaClient } from "@prisma/client";
export const prismaMock = mockDeep<PrismaClient>();
jest.mock("./lib/prisma", () => ({
prisma: prismaMock,
}));
// In tests
prismaMock.user.create.mockResolvedValue(mockUser);
beforeEach(async () => {
await prisma.$executeRaw`TRUNCATE TABLE "User" CASCADE`;
});
afterAll(async () => {
await prisma.$disconnect();
});
More patterns: See REFERENCE.md - Testing Strategies for integration testing, test containers, and CI/CD setup.
# Development
npx prisma generate # Regenerate client
npx prisma db push # Push schema changes
npx prisma migrate dev # Create migration
npx prisma studio # GUI browser
# Production
npx prisma generate # Required in CI
npx prisma migrate deploy # Apply migrations
// CRUD
prisma.model.create({ data })
prisma.model.findUnique({ where })
prisma.model.findMany({ where, orderBy, take, skip })
prisma.model.update({ where, data })
prisma.model.delete({ where })
prisma.model.upsert({ where, create, update })
// Relations
include: { relation: true }
include: { relation: { where, take } }
where: { relation: { some: {} } }
// Transactions
prisma.$transaction(async (tx) => { ... })
prisma.$transaction([query1, query2])
Progressive Disclosure: Start here for quick reference. Load REFERENCE.md for comprehensive patterns, advanced configurations, and production deployment.
Skill Version: 1.1.0
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.