Skip to content
Skillpedia
APIs & servers (backend)280k · #99

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

https://github.com/affaan-m/ECC/blob/main/pi/core/skills/prisma-patterns/SKILL.md

Ready-to-paste message

Use this skill to help me: https://github.com/affaan-m/ECC/blob/main/pi/core/skills/prisma-patterns/SKILL.md Read the SKILL.md file at that link and follow its instructions for my task.
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-patterns

Or download just the file:

curl -L https://raw.githubusercontent.com/affaan-m/ECC/main/pi/core/skills/prisma-patterns/SKILL.md -o SKILL.md
Technical 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 --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

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
// 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

Is this skill useful?

0

Sign in to vote.

Comments

  • …

More skills from this repository

Similar skills