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 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 planmigration apply) for non-additive changes.

Options

query.--db
string
Database connection string. Optional when db.connection is set in your config file.
query.--config
string
Path to prisma-next.config.ts. Defaults to ./prisma-next.config.ts in the current working directory. The CLI does not search upward.
query.--dry-run
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.
query.--json
string
Output a JSON result envelope to stdout. Only object format is supported; --json ndjson is rejected with PN-CLI-4008.
query.-q
boolean
Quiet mode. Suppresses all output except errors.
query.-v
boolean
Verbose mode. Prints debug information and timing data.
query.-vv
boolean
Trace mode. Prints deep internals and full stack traces.
query.--color
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
import { defineConfig } from '@prisma-next/cli/config-types';
import { typescriptContract } from '@prisma-next/sql-contract-ts/config-types';
import postgresAdapter from '@prisma-next/adapter-postgres/control';
import postgresDriver from '@prisma-next/driver-postgres/control';
import postgres from '@prisma-next/target-postgres/control';
import sql from '@prisma-next/family-sql/control';
import { contract } from './prisma/contract';

export default defineConfig({
  family: sql,
  target: postgres,
  adapter: postgresAdapter,
  driver: postgresDriver,
  extensionPacks: [],
  contract: typescriptContract(contract, 'src/prisma/contract.json'),
  db: {
    connection: process.env.DATABASE_URL,
  },
});

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

prisma-next db init ➜ Bootstrap a database to match the current contract
  config:          prisma-next.config.ts
  contract:        src/prisma/contract.json
  mode:            plan (dry run)

✔ Planned 4 operation(s)

├─ Create table user [additive]
├─ Add unique constraint user_email_key on user [additive]
├─ Create index user_email_idx on user [additive]
└─ Add foreign key post_userId_fkey on post [additive]

Destination hash: sha256:abc123...

This is a dry run. No changes were applied.
Run without --dry-run to apply changes.

Error codes

CodeMeaning
PN-CLI-4004Contract file not found.
PN-CLI-4005Missing database connection. Provide --db <url> or set db.connection in config.
PN-CLI-4008Unsupported JSON format. --json ndjson is not valid for this command.
PN-CLI-4010Missing driver in config. Add a driver descriptor to your config.
PN-CLI-4020Migration planning failed due to conflicts. The plan contains non-additive operations.
PN-CLI-4021The target does not support migrations.
PN-RUN-3000Runtime error, including marker mismatch failures after apply.

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 init fails — even in --dry-run mode. This prevents accidental bootstrap of a database that is mid-migration. Use db update or your migration workflow to reconcile existing databases.
In CI pipelines, run db init once during environment provisioning. Use migration apply for ongoing schema updates.

Build docs developers (and LLMs) love