Prisma Next migrations are contract-driven: you change your contract, emit it, plan the migration offline, fill in any data transforms, then apply to the database. Every migration package is fully attested on disk — a content-addressedDocumentation 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.
migrationHash in migration.json means the runner can detect hand-edits or partial writes before applying anything.
The migration workflow
Bootstrap a new database with db init
For a fresh database, Use
db init plans and applies all additive operations needed to bring an empty database up to your current contract, then writes the contract marker:--dry-run to preview the plan without touching the database:db init is additive-only — it creates missing tables, columns, constraints, and indexes. It will not rename or drop anything. If your database already has a marker that does not match the current contract, db init will refuse and ask you to use the migration workflow instead.Update the contract after schema changes
After editing your schema, emit a fresh This does not connect to the database. It is a pure compilation step that produces deterministic artifacts from your schema definition.
contract.json and contract.d.ts:Plan a migration
migration plan diffs the latest on-disk migration state against the newly emitted contract and scaffolds a new migration package. No database connection is needed:migrations/<timestamp>-add-order-status/:| File | Contents |
|---|---|
migration.ts | Editable migration source with placeholder() slots |
migration.json | Attested metadata including migrationHash |
ops.json | Planned operations (or [] if placeholders are unfilled) |
start-contract.json / end-contract.json | Contract bookends for the migration edge |
--from <hash> to branch from a specific contract hash rather than the latest migration target:Fill in placeholder() slots if needed
When the planner cannot lower a data transform automatically (for example, backfilling a new non-nullable column), it inserts a After editing, re-emit This regenerates
placeholder() slot in migration.ts. Open the file and replace the placeholder with your implementation:ops.json and update the migrationHash by running the file directly with Node:ops.json with your transform included and reattests migration.json. If any placeholder() slot is still unfilled, the script exits with PN-MIG-2001.Apply migrations to the database
migration apply reads the migration graph from disk, determines which migrations are pending relative to the database marker, and executes them in order. Each migration runs in its own transaction:migration apply resumes from the last successful migration.Use --ref to target a named environment ref rather than the current contract hash:Inspect migration status
migration status shows the migration graph and how the database marker relates to it:◄ DB, ◄ Contract, and ◄ ref:<name> markers so you can see exactly where each environment sits in the graph.Create named refs for multi-environment workflows
Named refs map logical environment names (such as Refs are stored in
staging or production) to specific contract hashes. Use them to route migration apply and migration status to the right point in the graph for each environment:migrations/refs.json and written atomically to prevent corruption.Migration integrity: hash attestation
Every migration package on disk is fully attested.migration.json contains a migrationHash that is computed over (metadata, ops). When migration apply loads packages, it rehashes each one and confirms the result matches the stored hash. If a package has been hand-edited or partially written, the load fails with MIGRATION.HASH_MISMATCH and points at the offending directory:
db init vs db update
| Command | Use case | Allowed operations |
|---|---|---|
db init | Bootstrap a fresh database | Additive only |
db update | Bring any existing database to the current contract | Additive, widening, destructive |
db init is the safe default for new databases. db update is the escape hatch for databases that were not initialized through the migration workflow, or for quick local resets. For production, prefer migration plan → migration apply to keep a full audit trail in version control.