Install the "prisma-patterns" agent skill from https://github.com/affaan-m/ECC/tree/main/skills/prisma-patterns into .claude/skills/prisma-patterns/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "prisma-patterns", then confirm the skill loads.
Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
Type this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
skills CLI
$ npx skills add affaan-m/ECC --skill prisma-patterns -a codex
Project install goes to .agents/skills/; add -g for ~/.codex/skills/.
Install the "prisma-patterns" agent skill from https://github.com/affaan-m/ECC/tree/main/skills/prisma-patterns into .agents/skills/prisma-patterns/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "prisma-patterns", then confirm the skill loads.
Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
skills CLI
$ npx skills add affaan-m/ECC --skill prisma-patterns -a cursor
Project install goes to .agents/skills/; add -g for ~/.cursor/skills/.
Install the "prisma-patterns" agent skill from https://github.com/affaan-m/ECC/tree/main/skills/prisma-patterns into .cursor/skills/prisma-patterns/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "prisma-patterns", then confirm the skill loads.
Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
skills CLI
$ npx skills add affaan-m/ECC --skill prisma-patterns -a gemini-cli
Project install goes to .agents/skills/; add -g for ~/.gemini/skills/.
Install the "prisma-patterns" agent skill from https://github.com/affaan-m/ECC/tree/main/skills/prisma-patterns into .gemini/skills/prisma-patterns/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "prisma-patterns", then confirm the skill loads.
Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
GitHub CLI
$ gh skill install affaan-m/ECC prisma-patterns
Installs for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
skills CLI
$ npx skills add affaan-m/ECC --skill prisma-patterns -a github-copilot
Project install goes to .agents/skills/; add -g for ~/.copilot/skills/.
Install the "prisma-patterns" agent skill from https://github.com/affaan-m/ECC/tree/main/skills/prisma-patterns into .github/skills/prisma-patterns/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "prisma-patterns", then confirm the skill loads.
GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
skills CLI
$ npx skills add affaan-m/ECC --skill prisma-patterns -a opencode
OpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
Install the "prisma-patterns" agent skill from https://github.com/affaan-m/ECC/tree/main/skills/prisma-patterns into .opencode/skills/prisma-patterns/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "prisma-patterns", then confirm the skill loads.
OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
Facts
Skill name
prisma-patterns
GitHub stars
275k
Used in
1 other repo
Token cost
~3.8k tokens
SKILL.md length
866 words
Files
1
Skills in repo
645
Repo updated
First seen
Licence
MIT
At a glance
Prisma ORM patterns for TypeScript backends — schema design, query optimization, transactions, pagination, and critical traps like updateMany returning count not records, $transaction timeouts…
Writing a Prisma schema
SKILL.md covers When to Activate, Core Concepts, Code Examples and Anti-Patterns, plus 2 more sections
Calls npx
Debugging transactions
What it does
Prisma Patterns is an agent skill from affaan-m/ECC. 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 connection limits.
Its SKILL.md is about 3.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Databases, covering ORMs and data access, Serverless and Query optimization. It works with Prisma and TypeScript. The repository describes itself as: The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond. The licence is MIT.
When your agent uses it
Writing a Prisma schema
Debugging transactions
Serverless connection limits
Example prompts
“/prisma-patterns”
Requirements
Node.js
What it can do on your machine
Read from SKILL.md and the folder at commit ef648e0. It shows what the files ask for, not the result of running them.
Tool permissions
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Runs code
Shell commands in SKILL.md call:
npx
From the folder's file list and the shell code blocks in SKILL.md.
Network
No URLs in SKILL.md. Its commands use npx, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Credentials
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Context cost
Prisma Patterns loads about 3.8k tokens when it runs. Until then it costs about 107 tokens; SKILL.md has 866 words of instructions outside code blocks.
Always· name and description, kept in context so the agent knows when to use it
~107
When it runs· the whole SKILL.md, loaded when a task matches
~3.8k
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
Safety
Auto-check: notes
The automated check noted patterns worth knowing about, such as sudo or a known installer.
NoteMentions a .env fileSKILL.md:237
# .env — preferred: embed params in the URL
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
Download SKILL.mdSave it as .claude/skills/prisma-patterns/SKILL.md (or your agent's skills folder).
name
prisma-patterns
description
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 connection limits.
metadata.origin
ECC
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:
bash
npx prisma --version
Notable API differences across versions:
relationJoins can load relations via JOIN rather than separate queries, but may cause row explosion on large 1:N relations or deep include — benchmark both approaches
omit field modifier and prisma.$extends Client Extensions API were added
Newer installs: the package may be named prisma instead of @prisma/client; PrismaClient may require a driver adapter (e.g. @prisma/adapter-pg); datasource.url may live in prisma.config.ts instead of schema.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
prisma
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 @@index on every foreign key and column used in WHERE or ORDER BY.
Declare deletedAt DateTime? upfront when soft delete is a foreseeable requirement — adding it later requires a migration on a live table.
updatedAt @updatedAt is set automatically by Prisma on update and upsert only (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
ts
// 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:
// 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
Each PrismaClient instance opens its own connection pool. Instantiate once.
ts
// lib/prisma.ts
// Option A — adapter-based initialization (required by newer Prisma installs)
import { PrismaClient } from '@prisma/client'; // or the generated client path for your setup
import { PrismaPg } from '@prisma/adapter-pg';
function createPrismaClient() {
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});
return new PrismaClient({
adapter,
log: process.env.NODE_ENV === 'development' ? ['query', 'error'] : ['error'],
});
}
const globalForPrisma = globalThis as unknown as { prisma?: PrismaClient };
export const prisma = globalForPrisma.prisma ?? createPrismaClient();
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;
// Option B — direct initialization (older installs, no adapter needed)
// import { PrismaClient } from '@prisma/client';
// export const prisma = globalForPrisma.prisma ?? new PrismaClient({ ... });
Use Option A if your Prisma install requires an adapter argument in the PrismaClient constructor.
Use Option B if new PrismaClient() works without arguments. Let the compiler tell you which is correct.
The globalThis pattern prevents duplicate instances during hot reload (Next.js, nodemon, ts-node-dev).
N+1 Problem
Loading relations inside a loop issues one query per row.
ts
// BAD: N+1 — one extra query per user
const users = await prisma.user.findMany();
for (const user of users) {
const posts = await prisma.post.findMany({ where: { authorId: user.id } });
}
// GOOD: single query
const users = await prisma.user.findMany({ include: { posts: true } });
With Prisma 5+ relationJoins, the include form uses a single JOIN. On large 1:N sets this may increase result set size — benchmark both approaches if the relation can return many rows per parent.
Code Examples
Cursor Pagination (preferred for feeds and large datasets)
Fetch limit + 1 and pop — canonical way to detect hasNextPage without an extra count query. Always include a unique field (e.g. id) as a secondary orderBy to prevent unstable pagination when multiple rows share the same timestamp. Use offset pagination only when users need to jump to arbitrary pages (admin tables).
Soft Delete
ts
// Always filter explicitly — do not rely on middleware (hides behavior, hard to debug)
const activeUsers = await prisma.user.findMany({ where: { deletedAt: null } });
await prisma.user.update({ where: { id }, data: { deletedAt: new Date() } });
await prisma.user.update({ where: { id }, data: { deletedAt: null } }); // restore
Show full SKILL.md (354 more words)Show less
Error Handling
ts
import { Prisma } from '@prisma/client'; // or the generated client path for your setup
try {
await prisma.user.create({ data: { email } });
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
if (e.code === 'P2002') throw new ConflictError('Email already exists');
if (e.code === 'P2025') throw new NotFoundError('Record not found');
if (e.code === 'P2003') throw new BadRequestError('Referenced record does not exist');
}
throw e;
}
Common codes: P2002 unique violation · P2025 not found · P2003 foreign key violation.
Catch at the service boundary and translate to domain errors. Never expose raw Prisma messages to API consumers.
Connection Pool — Serverless
Embed connection params directly in DATABASE_URL — string concatenation breaks if the URL already has query parameters (e.g. ?schema=public):
bash
# .env — preferred: embed params in the URL
DATABASE_URL="postgresql://user:pass@host/db?connection_limit=1&pool_timeout=20"
# With an external pooler (PgBouncer, Supabase pooler)
DATABASE_URL="postgresql://user:pass@host/db?pgbouncer=true&connection_limit=1"
ts
// Vercel, AWS Lambda, and similar serverless runtimes:
// cap pool to 1 per instance; connection_limit and pool_timeout controlled via DATABASE_URL
// Adapter-based setup (if your Prisma install requires an adapter):
import { PrismaClient } from '@prisma/client';
import { PrismaPg } from '@prisma/adapter-pg';
const prisma = new PrismaClient({
adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL }),
});
// Direct setup (if your Prisma install does not require an adapter):
// const prisma = new PrismaClient();
Same applies to deleteMany — returns { count: n }, never the deleted rows.
$transaction interactive form times out after 5 seconds
ts
// BAD: external call inside transaction exceeds 5s default → "Transaction already closed"
await prisma.$transaction(async (tx) => {
const user = await tx.user.findUniqueOrThrow({ where: { id } });
await sendWelcomeEmail(user.email); // external call
await tx.user.update({ where: { id }, data: { emailSent: true } });
});
// GOOD: external calls outside the transaction
const user = await prisma.user.findUniqueOrThrow({ where: { id } });
await sendWelcomeEmail(user.email);
await prisma.user.update({ where: { id }, data: { emailSent: true } });
// Only raise timeout when bulk processing genuinely needs it
await prisma.$transaction(async (tx) => { ... }, { timeout: 30_000 });
migrate dev can reset the database
migrate dev detects schema drift and may prompt to reset the DB, dropping all data.
bash
# NEVER on shared dev, staging, or production
npx prisma migrate dev --name add_column
# Safe everywhere except local solo dev
npx prisma migrate deploy
# Check drift without applying
npx prisma migrate diff \
--from-migrations ./prisma/migrations \
--to-schema-datamodel ./prisma/schema.prisma \
--shadow-database-url "$SHADOW_DATABASE_URL"
Manually editing a migration file breaks future deploys
Prisma checksums every migration file. Editing after apply causes P3006 checksum mismatch on every environment where the original already ran. Create a new migration instead.
Adding NOT NULL to an existing column or renaming a column in one migration will lock the table or drop data. Use expand-and-contract:
bash
# Step 1: create migration locally, then deploy
npx prisma migrate dev --name add_new_column # local only
npx prisma migrate deploy # staging / production
ts
// Step 2: backfill data (run in a script or migration job, not in the shell)
await prisma.user.updateMany({ data: { newColumn: derivedValue } });
bash
# Step 3: create the NOT NULL constraint migration locally, then deploy
npx prisma migrate dev --name make_new_column_required # local only
npx prisma migrate deploy # staging / production
@updatedAt does not fire on updateMany
@updatedAt is set automatically only on update and upsert. Bulk writes leave it stale.
ts
// BAD: updatedAt stays at its old value
await prisma.post.updateMany({ where: { authorId }, data: { published: true } });
// GOOD
await prisma.post.updateMany({
where: { authorId },
data: { published: true, updatedAt: new Date() },
});
Soft delete + findUniqueOrThrow leaks deleted records
findUniqueOrThrow throws P2025 only when the row does not exist in the DB. Soft-deleted rows still exist and are returned without error.
findUniqueOrThrow requires a unique constraint field in where — adding deletedAt: null alongside id breaks the type because { id, deletedAt } is not a compound unique constraint. Use findFirstOrThrow instead.
ts
// BAD: returns soft-deleted user
const user = await prisma.user.findUniqueOrThrow({ where: { id } });
// BAD: Prisma type error — { id, deletedAt } is not a unique constraint
const user = await prisma.user.findUniqueOrThrow({ where: { id, deletedAt: null } });
// GOOD: findFirstOrThrow supports arbitrary where conditions
const user = await prisma.user.findFirstOrThrow({ where: { id, deletedAt: null } });
deleteMany without where deletes every row
ts
// BAD: silently wipes the table
await prisma.post.deleteMany();
// GOOD
await prisma.post.deleteMany({ where: { authorId: userId } });
Best Practices
Rule
Reason
migrate deploy in CI/CD, migrate dev only locally
migrate dev can reset the DB on drift
Map entities to response DTOs
Prevents leaking internal fields
Catch PrismaClientKnownRequestError at service boundary
Translate to domain errors
Prefer *OrThrow methods over manual null checks
Throws P2025 automatically; use findFirstOrThrow when filtering non-unique fields
connection_limit=1 + external pooler in serverless
Prevents connection exhaustion
Always provide where on deleteMany
Prevents accidental table wipe
Set updatedAt: new Date() manually in updateMany
@updatedAt skips bulk writes
Related Skills
nestjs-patterns — NestJS service layer that integrates Prisma
postgres-patterns — PostgreSQL-level indexing and connection tuning
database-migrations — multi-step migration planning for production
backend-patterns — general API and service layer design
We found 2 copies of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in affaan-m/ECC, which our catalogue first saw on October 7, 2026.
Prisma Patterns next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
Ingest, index, search, edit, and monitor video and audio with the VideoDB Python SDK — upload from files, URLs, or RTSP feeds, build spoken and scene indexes with timestamped search and playable…
Scans installed skills for principles that recur across them and proposes rule-file changes: append, revise, add a section, create a file or leave as covered.
Measures whether agents actually follow a skill, rule or agent definition by generating scenarios at three strictness levels and scoring tool-call traces.
Instinct-based learning system that observes sessions via hooks, creates atomic instincts with confidence scoring, and evolves them into skills/commands/agents.
Prisma ORM patterns for TypeScript backends — schema design, query optimization, transactions, pagination, and critical traps like updateMany returning count not records, $transaction timeouts…. Prisma Patterns is an agent skill from affaan-m/ECC. 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.
Run `npx skills add affaan-m/ECC --skill prisma-patterns -a claude-code`. Or copy the skill folder (skills/prisma-patterns in affaan-m/ECC) into .claude/skills/prisma-patterns in your project. Claude Code loads it when a task matches its description.
How do I install Prisma Patterns in Codex?
Run `npx skills add affaan-m/ECC --skill prisma-patterns -a codex`. Or copy the skill folder (skills/prisma-patterns in affaan-m/ECC) into .agents/skills/prisma-patterns in your project. Codex loads it when a task matches its description.
Can I use Prisma Patterns in Cursor, Gemini CLI or GitHub Copilot?
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add affaan-m/ECC --skill prisma-patterns -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/prisma-patterns, .gemini/skills/prisma-patterns, .github/skills/prisma-patterns and .opencode/skills/prisma-patterns in your project.
What does Prisma Patterns need to run?
Going by SKILL.md and its folder, Prisma Patterns needs the command-line tools its instructions call (npx). Our summary lists: Node.js.
Does Prisma Patterns access the network?
SKILL.md contains no URLs. Its commands use npx, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Is Prisma Patterns safe to install?
Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.
What licence does Prisma Patterns use?
Prisma Patterns is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
How many tokens does Prisma Patterns use?
About 3.8k tokens (SKILL.md is roughly 15k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
What are the alternatives to Prisma Patterns?
Skills that share tags, products or a category with Prisma Patterns: Drizzle Orm Expert (davila7/claude-code-templates, 32k stars), DB Sculptor (EliasOulkadi/shokunin, 114 stars), Prisma Expert (davila7/claude-code-templates, 32k stars) and Database Schema (alinaqi/maggy, 707 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
Who maintains Prisma Patterns?
affaan-m (a GitHub user) maintains it in affaan-m/ECC, which has 275,023 GitHub stars. The repository holds 645 skills in this directory. The repository was last updated on October 5, 2026.
Source: affaan-m/ECC on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.