prisma-next migration plan compares your emitted contract.json against the latest on-disk migration state and produces a new migration package containing all required operations. The command is fully offline — no database connection is needed. It reads the contracts, runs the target’s migration planner to diff the two states, and scaffolds a directory under migrations/ with every artifact pre-attested and ready for version control.
Options
string
Path to
prisma-next.config.ts. Defaults to ./prisma-next.config.ts in the current working directory.string
default:"migration"
Name slug used when creating the migration directory (e.g.,
--name add-user-email produces migrations/<timestamp>-add-user-email/).string
Explicit starting contract hash (
sha256:<hex>). Overrides automatic detection of the latest migration target and enables branched migration graphs.boolean
Emit a machine-readable JSON envelope instead of the default TTY output.
boolean
Quiet mode — suppresses all output except errors.
boolean
Verbose output — includes debug info and timings.
What it does
1
Load config and contract
Reads
prisma-next.config.ts (or the path given to --config) and loads contract.json from config.contract.output. This is the “to” contract — the destination state the migration must reach.2
Read existing migrations
Scans
config.migrations.dir (default: migrations/) and loads every attested migration package already on disk to reconstruct the current migration graph.3
Determine the starting point
If
--from <hash> is provided, that hash is used as the starting contract. Otherwise the command derives the starting point from the latest migration’s target contract hash.4
Diff using the target planner
Invokes the target’s migration planner to compare the starting contract against the new contract. The planner produces a list of operations (additive, widening, or destructive) required to advance the schema.
5
Scaffold the migration package
Writes a new directory under
migrations/ containing migration.ts, migration.json, ops.json, and contract bookend files. The package is fully attested on creation — there is no draft state on disk.Output files
Every migration package produced bymigration plan contains the following files:
Placeholder slots
When the planner inserts aplaceholder(...) lambda into migration.ts, it means a data transform is required that cannot be inferred automatically. The command returns successfully with a pendingPlaceholders envelope — this is a warning, not a failure — and ops.json is written as [].
To resolve placeholder slots:
- Open
migrations/<dir>/migration.tsand implement the body of eachplaceholder(...)lambda. - Run
node migrations/<dir>/migration.tsto re-emitops.jsonand re-attestmigration.jsonwith the correctmigrationHash. - The script exits with
PN-MIG-2001if any slot is still unfilled.
Branching with --from
By default, migration plan derives the starting contract from the latest migration in your graph. Use --from <hash> to explicitly choose a different ancestor, creating a migration edge from that contract hash instead. This enables branched migration graphs where multiple environments diverge from a common ancestor.
Self-emitting ops.json
There is no dedicated CLI command for emitting a migration — migrations self-emit. Aftermigration plan scaffolds the package (or after you fill in placeholder() slots), run the migration file directly with Node:
migration.ts calls MigrationCLI.run(import.meta.url, ...) from @prisma-next/cli/migration-cli (Postgres scaffolds re-export MigrationCLI through @prisma-next/target-postgres/migration). When invoked as the entrypoint, MigrationCLI.run:
- Loads
prisma-next.config.tsand assembles aControlStack - Instantiates the migration with the stack so
dataTransformand adapter-aware helpers can materialise a real adapter - Serialises operations to
ops.json - Writes the content-addressed
migrationHashback intomigration.json
MigrationCLI.run accepts an optional third argument { argv?, stdout?, stderr? } for in-process testability and returns the exit code as a Promise<number>.
Self-emit flags
boolean
Print the operations that would be written to
ops.json without writing any files.string
Path to
prisma-next.config.ts. Defaults to ./prisma-next.config.ts.Run the self-emit step any time you edit
migration.ts — for example, after filling in a placeholder() slot or adjusting a data transform — to keep ops.json and migrationHash in sync.