Officialprisma/prisma-next1 file

Prisma Next Contract

Edit the Prisma Next data contract — add models, fields, relations, indexes, enums, value objects (composite types), type aliases, namespaces (Postgres schemas), cross-contract foreign keys (cross-space FK), polymorphic types (`@@discriminator` / `@@base`), use extension namespaces (`pgvector.Vector(...)`, `cipherstash.EncryptedString(...)`), wire `prisma-next.config.ts` with `defineConfig` from the `@prisma-next/<target>/config` façade, and run `prisma-next contract emit`. Use for schema, models, fields, attributes, soft delete, paranoid, scopes, validations, callbacks, prisma schema, PSL, contract.prisma, contract.ts, contract.json, contract.d.ts, `@prisma-next/postgres/config`, `@prisma-next/postgres/contract-builder`, `@prisma-next/postgres/control`, `@prisma-next/mongo/config`, `@prisma-next/mongo/contract-builder`, `extensions:`, pgvector, cipherstash, postgis, paradedb, supabase, `@prisma-next/extension-supabase`, `@@control`, control policy, managed, tolerated, external, observed.

Specification
Skill ID
prisma/prisma-next/prisma-next-contract
Publisher
prisma
Repository
prisma-next
Installs
237
Files
1
Synced
Sep 24, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

prisma/prisma-next/prisma-next-contractInstalls these files
  • SKILL.md

What this skill tells the agent

Prisma Next — Contract Authoring

Edit your data contract. Prisma handles the rest.

The data contract is the single source of truth for your data layer. You edit a contract source — contract.prisma (PSL, the canonical surface) or contract.ts (TypeScript builder) — and the framework derives types, migrations, and runtime configuration from it. The three-step user model:

  1. You edit your data contract.
  2. The system plans the migrations for you. (prisma-next-migrations)
  3. If you need data migrations, you edit `migration.ts` and execute it. (prisma-next-migrations)

Behind step 1 the agent runs prisma-next contract emit after every contract edit (or installs the Vite plugin so the bundler runs it on save — see prisma-next-build). Emit reads the contract source through the provider the façade picks based on the file extension of contract: in prisma-next.config.ts, then writes two artefacts colocated with the source:

  • contract.json — the canonical, content-hashed Contract IR. Read by the planner, the runtime, and db verify.
  • contract.d.ts — the precise TypeScript types the runtime + lanes propagate when you import Contract from it.

Both files are emitted artefacts. Edit the source; never the JSON or .d.ts.

When to Use

  • User wants to add, change, or remove a model / field / relation.
  • User wants to add an index, unique constraint, enum, or value object (composite type).
  • User wants to add a namespace block (Postgres schema) or a cross-contract foreign key.
  • User wants to set @@control on a model or configure defaultControlPolicy.
  • User wants to use a custom type from an extension (pgvector.Vector(length: 1536), cipherstash.EncryptedString({...})).
  • User wants to install or configure an extension via extensions: [...] in prisma-next.config.ts, including @prisma-next/extension-supabase.
  • User is migrating between authoring sources (PSL ↔ TypeScript builder).
  • User received PN-CLI-4002, PN-CLI-4003, or PN-CLI-4011 from contract emit.
  • User mentions: schema, fields, models, attributes, prisma schema, PSL, contract.prisma, contract.ts, contract.json, contract.d.ts, contract emit, façade imports, `@prisma-next/postgres/config`, `@prisma-next/postgres/contract-builder`, extensions, pgvector, cipherstash, postgis, paradedb, supabase, namespaces, cross-space FK, `@@control`, enums, value objects, validations, callbacks, soft delete, paranoid, scopes. (The last cluster routes to What Prisma Next doesn't do yet below.)

When Not to Use

  • User wants to apply a contract change to the DB → prisma-next-migrations.
  • User wants to write a query against the contract → prisma-next-queries.
  • User wants to wire db.ts (runtime entry point, middleware, env config) → prisma-next-runtime.
  • User wants the Vite / bundler integration → prisma-next-build.
  • User wants to set up Prisma Next for the first time → prisma-next-quickstart.
  • User wants a deeper read of a single structured error envelope → prisma-next-debug.
  • User wants to file a missing-feature request → prisma-next-feedback.

Key Concepts

  • The `@prisma-next/<target>` façade is the only surface user-authored code imports from. For a Postgres app: @prisma-next/postgres/config, @prisma-next/postgres/contract-builder, @prisma-next/postgres/control, @prisma-next/postgres/runtime. Mongo has the same layout (@prisma-next/mongo/config, @prisma-next/mongo/contract-builder, @prisma-next/mongo/runtime). Each extension publishes its own façade — @prisma-next/extension-pgvector/control, @prisma-next/extension-postgis/control, @prisma-next/extension-paradedb/control. *Never reach into `@prisma-next/cli/, @prisma-next/family-`, `@prisma-next/target-, @prisma-next/adapter-`, `@prisma-next/driver-, or @prisma-next/sql-contract-` from user code. The façade bakes the family / target / adapter / driver wiring in. See Common Pitfalls* #4.
  • Contract source. A file the framework reads and lowers to the canonical Contract IR. Two flavours, both first-class:
  • `contract.prisma` (PSL) — schema-flavoured DSL. Canonical for typical apps and brownfield Prisma users. Wired by contract: './<path>/contract.prisma' — the defineConfig façade detects the .prisma extension and routes through the PSL provider.
  • `contract.ts` (TypeScript builder) — programmatic authoring with defineContract({...}, ({ field, model, rel, type }) => ({...})) from @prisma-next/postgres/contract-builder (or @prisma-next/mongo/contract-builder). Wired by contract: './<path>/contract.ts' — the façade detects the .ts extension and routes through the TS provider. Use when you need programmatic composition (per-tenant variants, generated fields) or constructs PSL doesn't yet express (e.g. registering a parameterised extension type — see pgvector's contract).
  • `prisma-next.config.ts`. Wires the contract source, the database connection, the migrations directory, and any installed extensions. Use defineConfig({...}) from @prisma-next/postgres/config (or @prisma-next/mongo/config). The four fields the façade accepts: contract (path string — .prisma or .ts), db ({ connection?: string }), extensions (array of control descriptors), migrations ({ dir?: string }). The output path for contract.json is auto-derived from contract (e.g. ./src/prisma/contract.prisma → ./src/prisma/contract.json).
  • Emit pipeline. prisma-next contract emit --config <path>? reads prisma-next.config.ts, calls the provider the façade picked, validates the resulting Contract, then atomically writes contract.json + contract.d.ts colocated with the source.
  • Extension namespaces. Extensions contribute namespaced constructors (pgvector.Vector(length: 1536), cipherstash.EncryptedString({equality: true})) and helper presets. Install them by adding the descriptor to two places — both fields are named extensions, but the two surfaces consume two different descriptor types and shapes:
  • In the config (façade and core): extensions: [pgvector] — array of control descriptors imported from @prisma-next/extension-<name>/control.
  • In the TS builder's `defineContract` (only when authoring `contract.ts`): extensions: { pgvector } — record of pack descriptors imported from @prisma-next/extension-<name>/pack.
  • Contract space. Every package that emits a contract owns its own contract space — a prisma-next.config.ts at package root, a contract source, the colocated emitted artefacts, and a migrations/ directory. There are two intentional on-disk layouts, picked by whether the contract space is the consuming application or a contract-space package (an extension, an internal aggregate-root package, etc.):
  • Application layout (what you use when building an app). prisma-next.config.ts at repo root; src/prisma/contract.{prisma,ts}; src/prisma/contract.{json,d.ts} colocated; src/prisma/db.ts colocated; migrations under migrations/app/<timestamp>_<slug>/. The app/ segment is the consuming application's space-id; extension space-ids land in sibling migrations/<extension-space-id>/ directories that the extension packages manage. This is what examples/prisma-next-demo uses. prisma-next init currently scaffolds something different (prisma/... at repo root) — that's a defect (TML-2532); the canonical layout is what every command actually expects to see.
  • Contract-space-package layout (what you use when publishing a contract-space package — extensions, internal monorepo packages). prisma-next.config.ts at package root; src/contract.{prisma,ts} directly (no prisma/ subdir); src/contract.{json,d.ts} colocated; migrations/<timestamp>_<slug>/ directly under migrations/ (no <space-id> segment — the package is a single space). Documented in .cursor/rules/contract-space-package-layout.mdc and ADR 212.

More from prisma

Use this skill in a project

Open any RiverX project, search the Skills panel for prisma/prisma-next/prisma-next-contract, and install it in one click.

Use this skill