Skip to main content
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 by migration plan contains the following files:

Placeholder slots

When the planner inserts a placeholder(...) 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 [].
Applying a migration whose ops.json is [] due to unfilled placeholders will not advance the database to the intended destination hash. The runner’s destination-hash post-check will surface this as a state mismatch.
To resolve placeholder slots:
  1. Open migrations/<dir>/migration.ts and implement the body of each placeholder(...) lambda.
  2. Run node migrations/<dir>/migration.ts to re-emit ops.json and re-attest migration.json with the correct migrationHash.
  3. The script exits with PN-MIG-2001 if any slot is still unfilled.
See self-emit below for full details on the self-emit step.

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.
After creating branched migrations, use migration status --ref <name> to visualise which branch each environment is tracking, and migration apply --ref <name> to advance a specific branch.

Self-emitting ops.json

There is no dedicated CLI command for emitting a migration — migrations self-emit. After migration plan scaffolds the package (or after you fill in placeholder() slots), run the migration file directly with Node:
The scaffolded 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:
  1. Loads prisma-next.config.ts and assembles a ControlStack
  2. Instantiates the migration with the stack so dataTransform and adapter-aware helpers can materialise a real adapter
  3. Serialises operations to ops.json
  4. Writes the content-addressed migrationHash back into migration.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.

Examples

Output format

TTY (no placeholders):
TTY (pending placeholders):
JSON output: