Prisma patterns
Skill felixhennequin-gif/claude-code-config-template/.claude/skills/stacks/prisma-patterns
Prisma ORM conventions and patterns. Activates when working on the Prisma schema, migrations, queries, or services that call Prisma.From its SKILL.md
npx -y skills add felixhennequin-gif/claude-code-config-template --skill prisma-patternsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
3.6 KB, 889 tokens by cl100k_base, as published. Nobody here has run it
Prisma — Project conventions
Applies to Prisma 6.x and 7.x. Preview-only features are flagged inline.
Schema
- One model per domain entity. No technical tables surfaced in the schema (except sessions / tokens).
- Explicit relations via
@relation. Always name the relation when there's ambiguity. @updatedAton every model whose content can change.- String IDs: prefer
@default(uuid(7))(Prisma 5.18+) for new projects — UUIDv7 is time-ordered, which keeps B-tree indexes happy.@default(cuid())still works but cuid is in maintenance mode per the Prisma team — avoid it in new schemas. Do not use@default(ulid())— ULID is not a native Prisma generator; useuuid(7)or wire a manual@defaultviadbgeneratedif you truly need ULID. - Int IDs:
@default(autoincrement()). - Enums for fixed values (roles, statuses, visibility).
Queries
- Always use an explicit
selectorinclude. NeverfindMany()without a filter on a large table. omitfor sensitive fields (GA in Prisma 6.2+) — exclude fields likepasswordorsecretat the query level instead of manualselect:
Prefer this overconst user = await prisma.user.findUnique({ where: { id }, omit: { password: true }, });select-ing every field individually when you only want to hide one or two.- Avoid N+1: use
includewith the needed relations rather than loops callingfindUnique. - Cursor-based pagination for long lists (feed, search results). Pattern:
const items = await prisma.model.findMany({ take: limit + 1, cursor: cursor ? { id: cursor } : undefined, skip: cursor ? 1 : 0, orderBy: { createdAt: 'desc' }, }); const hasMore = items.length > limit; if (hasMore) items.pop(); typedSql⚠️ Preview feature since Prisma 5.19 — still preview as of last verified 2026-04-15. Re-check Prisma's preview-features list before adopting, because preview flags can break, rename, or get removed between minor releases. When you're comfortable pinning a Prisma version and revisiting on upgrades, enable withpreviewFeatures = ["typedSql"]in the generator block, put.sqlfiles underprisma/sql/, and call them viaprisma.$queryRawTyped()— this gives type-safe raw SQL without string interpolation. On a production codebase that can't absorb preview churn, stay on$queryRawwith careful review instead.- Transactions for multi-model operations that must be atomic.
Migrations
npx prisma migrate dev --name short-descriptionin dev.- Never
db pushin production. Alwaysmigrate deploy. - Review the generated migration before committing — Prisma may emit unexpected
DROPs.
Seed
prisma/seed.jsorprisma/seed.ts. Idempotent: preferupsertovercreate.- Realistic seed data — no
test123.
Anti-patterns
- ❌
prisma.$queryRawwith unchecked template literals — if thetypedSqlpreview flag is acceptable for your project, prefer$queryRawTyped+.sqlfiles. If you can't depend on preview flags, stay on$queryRawbut sanitize inputs yourself and review each call carefully. Either way, only use raw SQL when the query builder can't express the query. - ❌
deleteMany()without awhere— always spell out the filter - ❌ Deeply nested writes (> 2 levels) — split into sequential transactions
- ❌ Missing
@@indexon fields that are frequently filtered
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.