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 contract infer connects to a live database, introspects its schema, and writes an inferred Prisma Schema Language (PSL) contract file to disk. This is the recommended starting point for brownfield adoption: run contract infer once to generate a contract.prisma that reflects your existing schema, then refine it, run contract emit, and sign the database with db sign.

Synopsis

prisma-next contract infer [--db <url>] [--config <path>] [--output <path>] [--json] [-q] [-v] [-vv] [--color|--no-color]

Options

--db
string
Database connection string (e.g., postgresql://user:pass@localhost/db). Optional if db.connection is set in your config file.
--config
string
Path to prisma-next.config.ts. Accepts relative or absolute paths. Defaults to ./prisma-next.config.ts in the current working directory if the file is present. The CLI does not search upward.
--output
string
Write the inferred PSL contract to this path. When omitted, the output path is resolved automatically (see Default output path).
--json
boolean
Emit a JSON result envelope to stdout instead of the default human-readable TTY output. The envelope includes psl.path with the resolved output path.
-q, --quiet
boolean
Suppress all output except errors.
-v, --verbose
boolean
Print debug information and timing data.
-vv, --trace
boolean
Print deep internal trace output including stack traces. Intended for debugging the CLI itself.
--color / --no-color
boolean
Force-enable or force-disable ANSI color in output. By default, color is enabled when stdout is a TTY.

Config file requirements

contract infer requires a driver in your config to establish a database connection. A contract field is not required — infer works even before you have a contract.
prisma-next.config.ts
import { defineConfig } from '@prisma-next/cli/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';

export default defineConfig({
  family: sql,
  target: postgres,
  adapter: postgresAdapter,
  driver: postgresDriver,
  extensionPacks: [],
  db: {
    connection: process.env.DATABASE_URL, // Optional: can also use --db flag
  },
});
Either db.connection in the config or the --db flag must resolve to a connection string. If neither is present, the command exits with PN-CLI-4005.

Default output path

When --output is not provided, the output path is resolved in this order:
  1. --output <path>, if provided.
  2. contract.prisma placed next to config.contract.output (the configured contract.json path).
  3. contract.prisma in the current working directory.

Examples

prisma-next contract infer

Introspection process

1

Connect to database

Creates a driver instance by calling config.driver.create(url), using the URL from --db or config.db.connection.
2

Create family instance

Calls createControlStack() from @prisma-next/framework-components/control to assemble a ControlStack, then passes it to config.family.create(stack) to produce a ControlFamilyInstance.
3

Introspect

Calls familyInstance.introspect(), which queries the database catalog to discover tables, columns, constraints, indexes, and extensions. Returns a family-specific schema IR (e.g., SqlSchemaIR for the SQL family).
4

Transform to schema view

Calls familyInstance.toSchemaView() to project the family-specific schema IR into a CoreSchemaView used for display and PSL generation.
5

Write PSL contract

Formats the schema view as PSL and writes the result to the resolved output path.
Introspection output uses native database types (e.g., int4, text, timestamptz) rather than mapped codec IDs (e.g., pg/int4@1). These reflect the actual database state and may be enriched with type mappings after you edit the inferred contract.

Output format

TTY (default)

When stdout is a TTY, the command prints a human-readable summary:
sql schema (tables: 2)
├─ table user
│  ├─ id: int4 (not null)
│  ├─ email: text (not null)
│  └─ unique user_email_key
├─ table post
│  ├─ id: int4 (not null)
│  ├─ title: text (not null)
│  └─ userId: int4 (not null)
├─ extension plpgsql
└─ extension vector

✔ PSL contract written to prisma/contract.prisma

JSON (--json)

With --json, the command prints a single JSON object and exits. The psl.path field contains the resolved output path.
{
  "ok": true,
  "summary": "Schema introspected successfully",
  "psl": {
    "path": "/path/to/prisma/contract.prisma"
  },
  "schema": {
    "root": {
      "kind": "root",
      "id": "sql-schema",
      "label": "sql schema (tables: 2)",
      "children": [
        {
          "kind": "entity",
          "id": "table-user",
          "label": "table user",
          "children": [
            {
              "kind": "field",
              "id": "column-user-id",
              "label": "id: int4 (not null)",
              "meta": {
                "nativeType": "int4",
                "nullable": false
              }
            }
          ]
        }
      ]
    }
  },
  "meta": {
    "configPath": "/path/to/prisma-next.config.ts",
    "dbUrl": "postgresql://user:pass@localhost/db"
  },
  "timings": {
    "total": 42
  }
}

Error codes

CodeMeaningFix
PN-CLI-4005Missing database connectionProvide --db <url> or set db.connection in config
PN-CLI-4010Missing driver in configAdd a driver descriptor to prisma-next.config.ts

Next steps after inferring

After generating contract.prisma, the typical brownfield workflow is:
  1. Review and refine the inferred PSL contract.
  2. Run prisma-next contract emit to produce contract.json and contract.d.ts.
  3. Run prisma-next db sign --db <url> to write the contract marker to the database.
  4. Run prisma-next db verify to confirm the marker and schema match the contract.

Build docs developers (and LLMs) love