Prisma Knowledge Patch
Use this skill to choose current Prisma ORM patterns, upgrade older projects, and avoid removed APIs. Read the reference file for every area touched by the task; several changes span configuration, generated code, and runtime construction.
Reference index
| Reference | Topics |
|---|---|
| client-generation-and-adapters.md | prisma-client, Query Compiler, driver adapters, runtime targets, generated types, caching, and adapter correctness |
| extensions-and-observability.md | Client Extensions, events, tracing, SQL comments, read replicas, metrics, and driver errors |
| prisma-postgres-and-products.md | Prisma Postgres, local development, direct connections, Console, Management API, MCP, Compute, and integrations |
| schema-migrations-and-queries.md | Schema features, indexes, views, migrations, transactions, filters, bulk queries, raw SQL, and introspection |
| studio-and-tooling.md | Studio, editor integrations, bootstrap/init workflows, CLI behavior, credentials, and large schemas |
| upgrading-and-configuration.md | Breaking upgrades, Prisma Config, datasource ownership, removed CLI inputs, environment loading, and destructive-command guards |
Start with the connection architecture
Treat generated client code and its database connection as separate choices:
- Generate application-owned code with
provider = "prisma-client"and an explicitoutput. - Put CLI datasource details in
prisma.config.ts. - Construct
PrismaClientwith a driver adapter, or withaccelerateUrlfor Prisma Accelerate. - Run generation and seeding explicitly in installation, migration, and deployment workflows.
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
}
// prisma.config.ts
import 'dotenv/config'
import { defineConfig, env } from 'prisma/config'
export default defineConfig({
schema: 'prisma/schema.prisma',
migrations: {
path: 'prisma/migrations',
seed: 'tsx prisma/seed.ts',
},
datasource: {
url: env('DATABASE_URL'),
shadowDatabaseUrl: env('SHADOW_DATABASE_URL'),
},
})
import { PrismaPg } from '@prisma/adapter-pg'
import { PrismaClient } from './src/generated/prisma/client'
const adapter = new PrismaPg(process.env.DATABASE_URL!)
const prisma = new PrismaClient({ adapter })
Do not rely on new PrismaClient() without a connection path, schema-level
datasource URLs, automatic .env loading by the CLI, postinstall generation,
or migration-triggered generation and seeding.
Apply the breaking-change checklist
Before upgrading an existing application:
- Keep MongoDB applications on a supported Prisma major instead of upgrading them blindly.
- Replace
prisma-client-jswithprisma-clientwhen practical and update imports to the configured generated output. - Normalize adapter export casing, including
PrismaBetterSqlite3,PrismaD1Http,PrismaLibSql, andPrismaNeonHttp. - Remove legacy engine selections, engine environment variables, Data Proxy controls, and removed generator flags.
- Move CLI datasource, schema, migration, and seed configuration into
prisma.config.ts. - Load environment variables explicitly before calling
env(). - Replace removed CLI options and deprecated
prisma introspectinvocations. - Add explicit
prisma generateandprisma db seedsteps where older workflows depended on side effects. - Verify Node.js and TypeScript satisfy the installed Prisma release before changing dependencies.
Read upgrading-and-configuration.md before changing package scripts, CI, migrations, or environment handling.
Configure generated output deliberately
Use generator options only when the deployment target needs them:
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
runtime = "nodejs"
moduleFormat = "esm"
generatedFileExtension = "ts"
importFileExtension = "ts"
compilerBuild = "small"
}
compilerBuild = "fast" is the speed-oriented default; small trades speed
for a smaller compiler. Runtime names are constrained and older aliases were
removed. Deno uses runtime = "deno"; Bun is detected by relevant CLI setup
commands.
Use the adapter matching the database. Read client-generation-and-adapters.md for supported adapters, protocol switches, statement caching, Entra ID, transaction cleanup, and correctness fixes.
Use migration and schema guardrails
- Request destructive resets explicitly; do not expect
migrate devto offer an interactive reset after drift or a failed migration. - Expect an additional confirmation guard when destructive commands run in supported automated coding environments.
- Manage PostgreSQL extensions in custom SQL migrations instead of
postgresqlExtensions. - Keep migrations beside the datasource schema file for multi-file schemas unless Prisma Config declares independent paths.
- Treat externally managed tables as queryable but migration-excluded through
tables.external. - Add uniqueness to a view only when its data truly guarantees it; client operations and relationships depend on that declaration.
- Remember that a partial unique index does not create a
findUniqueinput. - Use
CREATE INDEX CONCURRENTLYwhen a PostgreSQL index must be built without blocking writes. - Treat a rolled-back migration still present on disk as unapplied.
Read schema-migrations-and-queries.md before editing schema attributes or generated migrations.
Prefer current query capabilities
const changed = await prisma.user.updateManyAndReturn({
where: { status: 'pending' },
data: { status: 'active' },
})
await prisma.session.deleteMany({
where: { expired: true },
limit: 500,
})
- Use
omitper query or globally to exclude fields. - Use
mode: 'insensitive'with supported JSON string filters. - Use nested interactive transactions on SQL databases when savepoint semantics are available.
- Do not depend on rollback semantics from D1 savepoints; its adapter treats them as no-ops.
- Reject invalid
Dateinputs before raw queries and handle their validation errors. - Size
queryPlanCacheMaxSizefor query diversity and memory use, or set it to0to disable the cache. - Handle unmapped driver failures as catchable
P2039errors.
Mapped enum members use their schema names in generated code while @map
controls the database representation. Do not send the mapped database string
merely because it appears in the schema.
Compose extensions predictably
Register event listeners before extending a client:
const prisma = new PrismaClient({
adapter,
log: [{ emit: 'event', level: 'query' }],
})
.$on('query', (event) => console.log(event.query))
.$extends(extension)
For extension chains:
- Keep separately derived clients behaviorally isolated while recognizing that they share the base client's pool.
- Expect the last extension to win a same-name member conflict.
- Expect query extensions to begin in declaration order.
- Check whether a client-level method exists before calling it on an extended client.
- Do not attempt to intercept nested reads or writes with a
queryextension.
Read extensions-and-observability.md for tracing spans, instrumentation dependencies, SQL commenter plugins, and extension-version compatibility.
Choose product and tooling surfaces intentionally
- Use
prisma studiofor supported local or remote databases; Studio includes relationship navigation, SQL workflows, search, filtering, and multi-cell editing. - Use editor integrations for local and hosted database workflows when an interactive UI is appropriate.
- Use
prisma bootstrapfor state-aware Prisma Postgres setup andprisma postgres linkto link an existing project. - Use
prisma devfor local Prisma Postgres and manage persisted instances explicitly. - Use direct PostgreSQL URLs for standard PostgreSQL tools; add pooling only when the direct Prisma Postgres connection should use it.
- Treat Accelerate as the cache layer and Prisma Postgres as the pooled database layer.
- Configure shell completions according to whether Prisma is project-local or globally installed; the invocation differs.
Read prisma-postgres-and-products.md for provisioning, regions, backups, metrics, APIs, MCP, integrations, and Compute. Read studio-and-tooling.md for command and UI behavior.