prisma-patterns
Makes your agent use the Prisma ORM efficiently in TypeScript backends. It helps with design, queries, transactions, and avoids common pitfalls.
What it does
This guide helps you use Prisma ORM more effectively in your programming projects. It shows best practices for organizing your data, writing fast queries, and avoiding common pitfalls.
When to use it
- ✓When creating or changing your database structure with Prisma.
- ✓When writing code that fetches or saves information from the database.
- ✓When debugging errors in transactions or when updating many data at once.
Example of what to ask your AI
“How can I ensure my database queries are fast and safe?”
Want more? Open the sections below.
How to use
The easiest way: copy the message below and paste it into Claude, ChatGPT, Cursor or any AI. It reads the skill and follows the instructions.
Skill link
Ready-to-paste message
How it works
The guide explains how to set up your database, choose the best ways to fetch data, and use transactions safely. It also warns about common traps that can cause slowness or errors.
Installation
Easiest way: copy the skill link and paste it into Claude, ChatGPT or Cursor asking it to follow the instructions.
In the terminal (Claude Code, Codex, Cursor), in your project folder:
npx skills add affaan-m/ECC --skill prisma-patternsOr download just the file:
curl -L https://raw.githubusercontent.com/affaan-m/ECC/main/pi/core/skills/prisma-patterns/SKILL.md -o SKILL.mdTechnical content (original SKILL.md)
Original text by the author, straight from GitHub.
Prisma Patterns
Production patterns and non-obvious traps for Prisma ORM in TypeScript backends.
Check your version before applying patterns. The Prisma API surface has evolved across major releases:
npx prisma --versionNotable API differences across versions:
relationJoinscan load relations via JOIN rather than separate queries, but may cause row explosion on large 1:N relations or deepinclude— benchmark both approachesomitfield modifier andprisma.$extendsClient Extensions API were added- Newer installs: the package may be named
prismainstead of@prisma/client;PrismaClientmay require a driver adapter (e.g.@prisma/adapter-pg);datasource.urlmay live inprisma.config.tsinstead ofschema.prisma- CLI commands (
migrate dev,migrate deploy,generate) are unchanged across versions
When to Activate
- Designing or modifying Prisma schema models and relations
- Writing queries, transactions, or pagination logic
- Using
updateMany,deleteMany, or any bulk operation - Running or planning database migrations
- Deploying to serverless environments (Vercel, Lambda, Cloudflare Workers)
- Implementing soft delete or multi-tenant row filtering
Core Concepts
ID Strategy
| Strategy | Use When | Avoid When |
|---|---|---|
@default(cuid()) |
Default choice — URL-safe, sortable, no collisions | Sequential IDs needed for external systems |
@default(uuid()) |
Interoperability with non-Prisma systems required | High-write tables (random UUIDs fragment B-tree indexes) |
@default(autoincrement()) |
Internal join tables, audit logs | Public-facing IDs (exposes record count) |
Schema Defaults
model User {
id String @id @default(cuid())
email String @unique // @unique already creates an index — no @@index needed
name String
role Role @default(USER)
posts Post[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
@@index([createdAt])
@@index([deletedAt, createdAt]) // composite for soft-delete + sort queries
}
- Add
@@indexon every foreign key and column used inWHEREorORDER BY. - Declare
deletedAt DateTime?upfront when soft delete is a foreseeable requirement — adding it later requires a migration on a live table. updatedAt @updatedAtis set automatically by Prisma onupdateandupsertonly (see Anti-Patterns for bulk update trap).
include vs select
include |
select |
|
|---|---|---|
| Returns | All scalar fields + specified relations | Only specified fields |
| Use when | You need most fields plus a relation | Hot paths, large tables, avoiding over-fetch |
| Performance | May over-fetch on wide tables | Minimal payload, faster on large datasets |
| Prisma 5 note | Uses JOIN by default (relationJoins) |
Same |
// include — all columns + relation
const user = await prisma.user.findUnique({
where: { id },
include: { posts: { select: { id: true, title: true } } },
});
// select — explicit allowlist
const user = await prisma.user.findUnique({
where: { id },
select: { id: true, email: true, name: true },
});
Never return raw Prisma entities from API responses — map to response DTOs to control exposed fields:
// BAD: leaks passwordHash, deletedAt, internal fields
return await prisma.user.findUniqueOrThrow({ where: { id } });
// GOOD: explicit DTO mapping
const user = await prisma.user.findUniqueOrThrow({ where: { id } });
return { id: user.id, name: user.name, email: user.email };
Transaction Form Selection
| Situation | Use |
|---|---|
| Independent operations, no inter-dependency | Array form |
| Later step depends on earlier result | Interactive form |
| External calls (email, HTTP) involved | Outside transaction entirely |
// Array form — batched in one round trip
const [user, post] = await prisma.$transaction([
prisma.user.update({ where: { id }, data: { name } }),
prisma.post.create({ data: { title, authorId: id } }),
]);
// Interactive form — use tx client only, never the outer prisma client
const post = await prisma.$transaction(async (tx) => {
const user = await tx.user.findUniqueOrThrow({ where: { id } });
if (user.role !== 'ADMIN') throw new Error('Forbidden');
return tx.post.create({ data: { title, authorId: user.id } });
});
PrismaClient Singleton
…
FAQ
What is Prisma ORM?
Prisma ORM is a tool that helps programmers interact with databases more easily and safely, especially in projects using TypeScript.
Why should I care about 'patterns' and 'traps'?
Following good patterns and avoiding traps ensures your application is fast, stable, and less prone to errors, saving time and effort in maintenance.
What are 'transactions'?
Transactions are like a package of database operations. Either all operations within the package succeed, or none of them do, ensuring data consistency.
Details
Original description by the author
Prisma ORM patterns for TypeScript backends — schema design, query optimization, transactions, pagination, and critical traps like updateMany returning count not records, $transaction timeouts, migrate dev resetting the DB, @updatedAt skipped on bulk writes, and serverless connection exhaustion. Use when writing a Prisma schema or query, or debugging transactions, migrations, or serverless connect
repo: affaan-m/ECC
Popularity
- GitHub stars
- 280k
- Ranking position
- #99
- License
- MIT
- Updated
- 10/15/2026
Comments
- …
More skills from this repository
accessibility
Helps your agent create interfaces that everyone can use. Ensures websites and apps work well for people with disabilities, like those who are blind or have reduced mobility.
affaan-m/ECC
agent-architecture-audit
Makes your agent check if everything is working correctly. It finds and fixes problems in AI systems, ensuring they perform as expected.
affaan-m/ECC
agent-eval
Helps your agent compare different AI coding tools. It measures which one is faster, cheaper, and more reliable for specific tasks.
affaan-m/ECC
agent-harness-construction
Makes your agent better understand how to perform tasks. It optimizes the tools and instructions the agent uses to increase its chances of success.
affaan-m/ECC
Similar skills
api-and-interface-design
Helps create well-defined APIs and interfaces. It's useful when designing how different parts of software will communicate.
addyosmani/agent-skills
mason
Helps your agent write clean and functional code. It follows defined rules to ensure everything works as expected.
sickn33/agentic-awesome-skills
max
Lets your agent improve existing code without changing what it does. It makes the code easier to read and maintain.
sickn33/agentic-awesome-skills