prisma-next db init reads your emitted contract.json, introspects the live database, and plans a set of additive-only operations — create tables, add columns, add constraints, create indexes — until the database satisfies the contract. Once all operations succeed, it writes the contract marker so that db verify can confirm the database state in the future.
db init only performs additive operations. It never drops or renames anything. If the contract requires a change that is not purely additive (for example, a column type change), the command fails with a conflict list instead of touching the database. Use your migration workflow (migration plan → migration apply) for non-additive changes.
Options
string
Database connection string. Optional when
db.connection is set in your config file.string
Path to
prisma-next.config.ts. Defaults to ./prisma-next.config.ts in the current working directory. The CLI does not search upward.boolean
Print the migration plan without applying it. No database changes are made and the marker is not written. Exit code 0 when planning succeeds, non-zero on conflict or missing connection.
string
Output a JSON result envelope to stdout. Only
object format is supported; --json ndjson is rejected with PN-CLI-4008.boolean
Quiet mode. Suppresses all output except errors.
boolean
Verbose mode. Prints debug information and timing data.
boolean
Trace mode. Prints deep internals and full stack traces.
boolean
Force color output. Use
--no-color to disable color output entirely.Config requirements
db init requires a driver entry in your config to open a database connection. The contract entry must point to a valid emitted contract.json.
prisma-next.config.ts
Initialization process
1
Load contract
Reads
contract.json from the path specified by config.contract.output.2
Connect to database
Creates a driver instance using
config.driver.create(url).3
Create family instance
Builds a
ControlStack via createControlStack() and passes it to config.family.create(stack).4
Introspect current schema
Calls
familyInstance.introspect() to capture the current database state as a schema IR.5
Validate wiring
Confirms that
contract.targetFamily, contract.target, and any contract.extensionPacks are all satisfied by the descriptors in config. Exits with a structured error if wiring is inconsistent.6
Plan migration
Calls the target’s
createPlanner().plan() with the contract, schema IR, and an additive-only policy. Returns either a conflict list (fails) or a migration plan.7
Apply migration (unless --dry-run)
Calls
runner.execute() to apply all planned operations, verifies the resulting schema against the contract, then writes the contract marker and records a ledger entry.Output formats
Error codes
Difference from db update
db init is a bootstrap command. It only plans additive operations and refuses to proceed when it encounters any conflict. It is designed for fresh databases and CI environments where the database should be entirely empty or already match the contract.
db update is an incremental command. It allows widening and destructive operations in addition to additive ones. It also works on databases that have not been initialized with db init.
Idempotency and noop behavior
db init is safe to run multiple times:
- If the database marker already matches the destination contract hash, the command plans zero operations and exits with code 0.
- If the database marker exists but does not match the destination contract,
db initfails — even in--dry-runmode. This prevents accidental bootstrap of a database that is mid-migration. Usedb updateor your migration workflow to reconcile existing databases.