Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/prisma/prisma-next/llms.txt

Use this file to discover all available pages before exploring further.

Prisma Next is built around a single organizing principle: your schema should produce a verifiable artifact — a data contract — rather than executable client code. That contract is pure data: deterministic, hashable, diffable, and machine-readable. Every query, migration, and runtime check flows from it.

What is a data contract?

A data contract (contract.json) is a canonical JSON description of your application’s data model. It records the models and fields your code depends on, the physical storage layout (tables, columns, indexes, foreign keys), the capabilities your queries may use, and the hashes that tie everything together. It carries no executable logic — it is data that gates execution. Because the contract is pure JSON, any tool, agent, or human can read it without running application code. The emitter that produces it follows strict canonicalization rules (lexicographic key ordering, normalized scalars, stable array ordering), so the same schema always produces the same bytes — and the same hash.

What contract.json contains

Here is a minimal example from a real Prisma Next project:
{
  "schemaVersion": "1",
  "targetFamily": "sql",
  "target": "postgres",
  "profileHash": "sha256:1a8dbe044289f30a1de958fe800cc5a8378b285d2e126a8c44b58864bac2c18e",
  "roots": {
    "user": "User"
  },
  "models": {
    "User": {
      "fields": {
        "id":        { "nullable": false, "type": { "codecId": "pg/int4@1",      "kind": "scalar" } },
        "email":     { "nullable": false, "type": { "codecId": "pg/text@1",      "kind": "scalar" } },
        "createdAt": { "nullable": false, "type": { "codecId": "pg/timestamptz@1","kind": "scalar" } }
      },
      "relations": {},
      "storage": {
        "table": "user",
        "fields": {
          "id":        { "column": "id" },
          "email":     { "column": "email" },
          "createdAt": { "column": "createdAt" }
        }
      }
    }
  },
  "storage": {
    "storageHash": "sha256:e57551e3ede9609bcc4ead37f145f010642a05c4e9373c9b55b0f1705c940792",
    "tables": {
      "user": {
        "columns": {
          "id":        { "codecId": "pg/int4@1",       "nativeType": "int4",        "nullable": false },
          "email":     { "codecId": "pg/text@1",       "nativeType": "text",        "nullable": false },
          "createdAt": { "codecId": "pg/timestamptz@1","nativeType": "timestamptz", "nullable": false }
        },
        "primaryKey": { "columns": ["id"] },
        "foreignKeys": [],
        "indexes": [],
        "uniques": []
      }
    }
  },
  "capabilities": {
    "postgres": { "lateral": true, "jsonAgg": true, "returning": true }
  },
  "extensionPacks": {},
  "meta": {},
  "_generated": {
    "warning": "⚠️  GENERATED FILE - DO NOT EDIT",
    "message": "This file is automatically generated by \"prisma-next contract emit\".",
    "regenerate": "To regenerate, run: prisma-next contract emit"
  }
}
The top-level sections are:
SectionPurpose
rootsMaps ORM accessor names to model names (e.g. "user": "User")
modelsDomain-level description: fields, relations, and the storage bridge
storagePhysical layout: tables, columns, PK/FK/indexes, and the storageHash
capabilitiesFeature flags that queries are allowed to use when lowering to SQL
extensionPacksExtension-contributed types, codecs, and capability declarations

The three hashes

The contract carries three distinct hashes, each covering a different concern: storageHash — computed from the physical storage layout: tables, columns, types, constraints. When this hash changes, the database schema has changed. The runtime compares the storageHash embedded in each query plan against the hash stored in the database marker before executing. A mismatch means the database is out of sync with the contract. profileHash — computed from the capability profile declared by the contract: the capability keys and any explicit adapter pins. It does not change when you rename a column, but it does change when you enable a new capability such as pgvector.cosine. The migration runner writes this hash to the database marker after verifying that the live database satisfies all declared capabilities. executionHash (optional) — computed from the execution section when execution defaults (such as UUID generation or now() timestamps) are declared. Plans that depend on execution defaults embed this hash.

Schema drift detection at runtime

Every compiled query plan includes storageHash (and profileHash) in its meta block. Before executing any plan, the runtime reads the database marker — a small internal schema Prisma Next maintains — and checks that the plan’s hashes match what is recorded there. If the database has been migrated without updating the contract (or vice versa), execution fails immediately with a structured error rather than silently returning wrong data. This check happens at query time with no additional network round-trip on most adapters, because the marker is cached after the first connection.

Control Plane vs Execution Plane

Prisma Next is organized around two planes that both read the same contract.json: Control Plane (build time): responsible for authoring the contract (PSL or TypeScript), planning migrations as contract-to-contract edges, running preflight checks against shadow databases, and applying migrations idempotently. The Control Plane writes storageHash and profileHash to the database marker. Execution Plane (runtime): responsible for compiling queries into immutable plans, verifying marker hashes before execution, applying guardrail plugins (lints, budgets, telemetry), and streaming results through codec-aware adapters. The Execution Plane only reads the marker. Both planes are driven entirely by the contract. Neither evaluates application code at plan time.

Comparison with Prisma ORM codegen

FeaturePrisma ORMPrisma Next
Schema modelGenerates executable client codeGenerates contract IR + TypeScript types
Code generationHeavy, runtime-bound prisma generateMinimal: contract.json + contract.d.ts only
Query interfaceGenerated methods (prisma.user.findMany())Composable DSL (sql().from(...).select(...))
Machine readabilityOpaque generated codeStructured JSON artifact
Drift detectionNonestorageHash + runtime marker check
ExtensibilityMonolithic clientExtension packs, adapters, plugins
Artifact diffHard; code diffs are noisyEasy; JSON diffs are semantic
The contract is data, not code. Unlike Prisma ORM’s generated client — which is executable TypeScript tied to a specific runtime — contract.json carries no executable logic. Any tool, agent, or CI process can read, diff, and reason about it without running your application. This separation is what makes deterministic hashing, runtime drift detection, and agent-friendly workflows possible.

Build docs developers (and LLMs) love