# Configuration (/docs/cli/configuration) > For the complete Prisma documentation index, see [llms.txt](https://www.prisma.io/docs/llms.txt). A markdown version of any docs page is available by appending `.md` to its URL. Configure Prisma ORM CLI commands with prisma.config.ts and global flags. Location: CLI > Configuration Prisma ORM CLI commands read `prisma.config.ts`, starting in the directory you run them from. The file has one section per part of the CLI. The `orm` section holds your schema, database, and migration settings, which the `contract`, `db`, and `migration` commands read. The `skills` section holds the settings for the [agent skills commands](https://www.prisma.io/docs/cli/skills), which copy Prisma's instructions for AI coding agents into your project. The `composer` section holds [Prisma Composer](https://www.prisma.io/docs/composer)'s deploy config, the extensions and the deploy-state store that [`deploy`](https://www.prisma.io/docs/cli/deploy) and [`dev`](https://www.prisma.io/docs/cli/dev) read; [Composer getting started](https://www.prisma.io/docs/composer/getting-started) shows how to write it. ## Config file [#config-file] The outer `definePrismaConfig` comes from `prisma/config` and marks the file as a Prisma ORM 8 CLI config. A Prisma ORM 7 `prisma.config.ts` without that marker is rejected rather than misread. The import resolves from your project's `node_modules`, so `prisma` must be a local dependency. The `orm` section uses the config helper for your database. For PostgreSQL: ```typescript title="prisma.config.ts" import "dotenv/config"; import { definePrismaConfig } from "prisma/config"; import { defineConfig as ormConfig } from "@prisma/orm-postgres/config"; export default definePrismaConfig({ orm: ormConfig({ contract: "./prisma/contract.prisma", db: { connection: process.env["DATABASE_URL"]!, }, }), }); ``` For MongoDB projects, import the section helper from `@prisma/orm-mongo/config` instead. Both packages export this helper as `defineConfig`, and the examples on this page rename it to `ormConfig` when they import it. This paragraph is only for a config written for a Prisma ORM 8 release candidate before `8.0.0-rc.12`. Such a config may import `defineConfig` from `@prisma/cli-engine`. That import no longer exists, so the config fails to load. Replace it with `definePrismaConfig` from `prisma/config`, and rename the call to match: it is the same function under its new name. Leave the `defineConfig` import from `@prisma/orm-postgres/config` or `@prisma/orm-mongo/config` as it is. That one is the helper for the `orm` section, and its name has not changed. [`orm init`](https://www.prisma.io/docs/cli/orm-init) writes this file for you. Without `--config`, the CLI looks for `prisma.config.ts` in the directory you run the command from and in the directories above it, as [How the CLI finds the config](#how-the-cli-finds-the-config) explains. Pass `--config` to use a config file in another place, such as a subdirectory: #### bun ```bash bunx prisma contract emit --config ./config/prisma.config.ts ``` #### pnpm ```bash pnpm prisma contract emit --config ./config/prisma.config.ts ``` #### yarn ```bash yarn prisma contract emit --config ./config/prisma.config.ts ``` #### npm ```bash npx prisma contract emit --config ./config/prisma.config.ts ``` ## How the CLI finds the config [#how-the-cli-finds-the-config] The CLI starts with `prisma.config.ts` in the current directory, or with the file you pass to `--config`. It then also reads the `prisma.config.ts` in each parent directory that has one, up to the root of the repository, which is the first directory that has a `.git` entry. If neither the starting directory nor any directory above it has a `.git` entry, the CLI reads only the file it started with. The CLI combines the files it finds one section at a time. Inside a section such as `orm`, it takes each top-level key, such as `contract`, `db`, or `migrations`, from the nearest file that sets it, and it takes the whole value of that key from that one file. So if a config higher up sets `db.connection` and your project's config sets only `contract`, the CLI uses your `contract` and the other file's `db`. The `composer` section is not combined this way. The CLI takes it whole from the nearest file that declares a `composer` section and ignores the `composer` sections of files higher up. Extensions are the exception: if your project config has its own `orm` section, it never inherits `extensions` from a config higher up, even when it lists none. List the extensions your contract uses, as [Extension packs](#extension-packs) shows, in each project's own config. > [!WARNING] > More than one project in a repository > > If a `prisma.config.ts` higher up sets `db` or `migrations`, a project config that leaves them out uses that file's database and migrations folder. `db update`, `db migrate` and `db verify` then connect to the other project's database, and `migration plan` writes into the other project's migrations folder, without a warning. Set `db` and `migrations`, such as `migrations: { dir: "./migrations" }`, in every project's own config, or add `parent: false` to it. To stop a project's config from inheriting anything, add `parent: false` to it. The search then ends at that file: ```typescript title="prisma.config.ts" import { definePrismaConfig } from "prisma/config"; import { defineConfig as ormConfig } from "@prisma/orm-postgres/config"; export default definePrismaConfig({ parent: false, orm: ormConfig({ contract: "./prisma/contract.prisma", }), }); ``` `parent` can also be a path to another config file, which the CLI reads next in place of the one in the parent directory. The path is relative to the directory of the config file that sets it, and it may point outside the repository. After reading that file, the CLI goes on to search the directories above that file in the usual way, unless that file sets `parent` too: ```typescript title="prisma.config.ts" import { definePrismaConfig } from "prisma/config"; import { defineConfig as ormConfig } from "@prisma/orm-postgres/config"; export default definePrismaConfig({ parent: "../shared/prisma.config.ts", orm: ormConfig({ contract: "./prisma/contract.prisma", }), }); ``` A relative path in a config file, such as `contract`, `output`, or `migrations.dir`, resolves from the directory of the config file that sets it, not from the directory you run the command in. So `--config ./config/prisma.config.ts` with `contract: "./prisma/contract.prisma"` reads `./config/prisma/contract.prisma`. ## Split the schema across several files [#split-the-schema-across-several-files] `contract` accepts a glob, a path pattern where `*` matches any file name and `**` matches any number of folders, so one schema can span several `.prisma` files: ```typescript title="prisma.config.ts" import { definePrismaConfig } from "prisma/config"; import { defineConfig as ormConfig } from "@prisma/orm-postgres/config"; export default definePrismaConfig({ orm: ormConfig({ contract: "./prisma/**/*.prisma", }), }); ``` `contract emit` builds one contract from every matched file whose first line is `// use prisma-8`. The same rule applies when `contract` names a single file: that file must start with the line too. `contract emit` skips a matched file without that line and does not warn, so the line is what makes a file part of the schema. The Prisma editor extension uses the same rule, so the editor and `contract emit` agree on which files make up the schema. If the glob matches files but none of them starts with the line, `contract emit` fails with `CONTRACT.SOURCE_LOAD_FAILED`, and the error's details name the problem `PSL_NO_OPTED_IN_SCHEMA_FILES`. If the glob matches no file at all, for example because of a typo in the pattern, they name it `PSL_NO_SCHEMA_FILES_MATCHED` instead. [What `contract emit` creates](https://www.prisma.io/docs/cli/contract-emit#what-it-creates) says where these details appear in the output. A new file joins the schema the next time you run `contract emit`, with no change to the config. The emitted files go in the folder before the first wildcard, here `./prisma/contract.json` and `./prisma/contract.d.ts`. ## Use a Prisma ORM 7 schema [#use-a-prisma-orm-7-schema] On PostgreSQL, Prisma ORM 8 can read a Prisma ORM 7 `schema.prisma` directly as its contract source, so the two versions can run side by side on the database that Prisma ORM 7 migrates. Wrap the path in `prisma7Schema`: ```typescript title="prisma.config.ts" import "dotenv/config"; import { definePrismaConfig } from "prisma/config"; import { defineConfig as ormConfig, prisma7Schema } from "@prisma/orm-postgres/config"; export default definePrismaConfig({ orm: ormConfig({ contract: prisma7Schema("prisma/schema.prisma"), db: { connection: process.env["DATABASE_URL"]!, }, }), }); ``` `prisma7Schema` takes one schema file, or a directory of `.prisma` files as Prisma ORM 7 reads it. `prisma7Schema` reads every `.prisma` file it is given, so these files do not need the `// use prisma-8` first line. `contract emit` writes `contract.json` and `contract.d.ts` into the directory that holds the schema, here `prisma/`, unless you set `output`. Prisma ORM 7 keeps owning the database and its migrations, and you run its commands as `prisma7`, the Prisma ORM 7 CLI that [`orm init --from-prisma7-schema`](https://www.prisma.io/docs/cli/orm-init#on-a-prisma-orm-7-project) installs next to Prisma ORM 8. `orm init --from-prisma7-schema` also writes this config for you. Prisma ORM 7 gave your application date and time values as JavaScript `Date` objects. With `prisma7Schema`, Prisma ORM 8 gives them as strings instead. This applies to a `DateTime` field and to a field with `@db.Timestamp`, `@db.Timestamptz`, `@db.Date`, or `@db.Time`: each value is the text PostgreSQL prints, such as `"2026-09-14 10:00:00.123"`. A `DateTime` value is in UTC, as Prisma ORM 7 writes it. Prisma ORM 8 can also give these values as `Temporal` objects. `Temporal` is the newer JavaScript date and time API, and runtimes without it, such as Node.js 24, need the `temporal-polyfill` package. To get `Temporal` values, write a Prisma ORM 8 contract with `npx prisma contract print --output prisma/contract.prisma`, and in that file change `TimestampString(3)` to `Timestamp(3)`, `TimestamptzString(3)` to `Timestamptz(3)`, `DateString` to `Date`, and `TimeString(3)` to `Time(3)`. Then change `contract` in `prisma.config.ts` from `prisma7Schema("prisma/schema.prisma")` to `"./prisma/contract.prisma"`, so that `contract emit` reads the edited file. When your code creates or updates a row, Prisma ORM fills each `@updatedAt` field with the time from your application's clock, as text in the same form. This also works on a `@db.Date`, `@db.Time`, or `@db.Timetz` field. A field can have both `@updatedAt` and `@default(now())`, and `@default(now())` stays the column's default in the database. A list such as `String[]` reads as a list whose elements may be `null`, because the database that Prisma ORM 7 built does not stop a list from holding `null` elements. Once the config is in place, run `npx prisma contract emit` and then [`npx prisma db sign`](https://www.prisma.io/docs/cli/db-sign). `db sign` checks that the database matches the contract and then records that in the database, without changing your tables. Run both commands again after each Prisma ORM 7 migration, whether you ran `npx prisma7 migrate dev` or `npx prisma7 migrate deploy`, so that the record names the new contract. An `Unsupported("ltree")` field becomes a column of that database type with no field on the model, as in the Prisma ORM 7 client: migrations and `db verify` keep the column, and your code cannot read or write it. `contract print` cannot write such a column yet, so a schema with `Unsupported(...)` fields stays your contract source. `contract emit` fails on any part of the schema that Prisma ORM 8 cannot represent exactly, such as a `view` block or `relationMode = "prisma"`. The error names the file and the line and suggests an edit to the Prisma ORM 7 schema. When that edit would also change the database on the next Prisma ORM 7 migration, the error says so. Prisma ORM 8 has no views, so for a `view` block the error suggests removing the view or replacing it with a model over the table the view reads. `contract emit` also fails when a default function gets an argument it does not take, such as `uuid(5)` or `cuid(1)`. The error code is `PSL.PRISMA7_UNKNOWN_DEFAULT`, and the message names the values the function takes, for example `uuid: version must be 4 or 7, got 5`. The contract also keeps the columns and tables of `@ignore` fields and `@@ignore` models, as storage that no model maps, so adding or removing `@ignore` plans no migration. The ORM still leaves those fields and models out of its queries. Because they are in the contract, they have to meet the same rules as the rest of the schema: a `@db.*` type Prisma ORM 8 has no codec for is refused even on an ignored model. The contract keeps the constraint names Prisma ORM 7 gave the database. Where Prisma ORM 7's name for a primary key or foreign key differs from the name Prisma ORM 8 would derive, the contract states it: a `map` on `@id`, `@@id`, or `@relation`, the primary key of an implicit many-to-many table such as `_PostToTag_AB_pkey`, and a name Prisma ORM 7 cut to 63 bytes. A later migration that touches one of these constraints then targets the name the database has. A `map` longer than PostgreSQL keeps is refused, as Prisma ORM 7 refuses it. After Prisma ORM 8 takes over the migrations, you can give an existing integer column `@default(autoincrement())`. `migration plan` and `db update` create or reuse a sequence for it and start the sequence past the column's current maximum, so rows already in the table do not collide with new ones. ## Use a Prisma ORM 6 MongoDB schema [#use-a-prisma-orm-6-mongodb-schema] On MongoDB, Prisma ORM 8 can read a Prisma ORM 6 `schema.prisma` directly as its contract source. Wrap the path in `prisma6Schema`: ```typescript title="prisma.config.ts" import "dotenv/config"; import { definePrismaConfig } from "prisma/config"; import { defineConfig as ormConfig, prisma6Schema } from "@prisma/orm-mongo/config"; export default definePrismaConfig({ orm: ormConfig({ contract: prisma6Schema("prisma/schema.prisma"), db: { connection: process.env["DATABASE_URL"]!, }, }), }); ``` The schema file does not need the `// use prisma-8` first line. Run `npx prisma contract emit` and then [`npx prisma db sign`](https://www.prisma.io/docs/cli/db-sign), which checks that the database Prisma ORM 6 built matches the contract. `prisma6Schema` reads each field as the BSON type Prisma ORM 6 stores. A plain `Int` and an `Int @db.Long` are a `number` in your code, written as a BSON long, and a stored value with a fraction fails to read with `RUNTIME.DECODE_FAILED`. A `Bytes @db.ObjectId` field reads as a 24-digit hex string and takes a hex string or an `ObjectId`, not a `Buffer`. Every native type Prisma ORM 6 accepts on MongoDB is read, except `DateTime @db.Timestamp`. `contract emit` fails on any part of the schema that Prisma ORM 8 cannot represent exactly, with an error code that starts with `PSL.PRISMA6_MONGO_`. The [error reference](https://www.prisma.io/docs/orm/reference/error-reference) lists each code and what to change. ## Write your own contract source [#write-your-own-contract-source] A config that builds `contract.source` itself, as an object with a `load` function, must give the object a `format`: `"psl"` when its inputs are PSL text, and `"typescript"` when it builds the contract in TypeScript. Without it, every command that reads the config fails with `CONFIG.VALIDATION_FAILED`. A path, a glob, `prisma7Schema` and `prisma6Schema` set the format for you. ## Emit-only config [#emit-only-config] `contract emit` does not connect to a database, so the `orm` section can omit `db.connection`: ```typescript title="prisma.config.ts" import { definePrismaConfig } from "prisma/config"; import { defineConfig as ormConfig } from "@prisma/orm-postgres/config"; export default definePrismaConfig({ orm: ormConfig({ contract: "./prisma/contract.prisma", }), }); ``` Add `db.connection` before running commands such as `db verify`, `db sign`, `db init`, `db update`, `db schema`, `contract infer`, or `db migrate`. ## Extension packs [#extension-packs] Add extension control descriptors to the `orm` section when your contract uses extension-provided types: ```typescript title="prisma.config.ts" import { definePrismaConfig } from "prisma/config"; import { defineConfig as ormConfig } from "@prisma/orm-postgres/config"; import pgvector from "@prisma/orm-extension-pgvector/control"; export default definePrismaConfig({ orm: ormConfig({ contract: "./prisma/contract.prisma", extensions: [pgvector], db: { connection: process.env["DATABASE_URL"]!, }, }), }); ``` Re-run `contract emit` after changing extension packs, then update the matching runtime client. ## Agent skills [#agent-skills] The `skills` section controls the [agent skills commands](https://www.prisma.io/docs/cli/skills) and the staleness check: ```typescript title="prisma.config.ts" import { definePrismaConfig } from "prisma/config"; export default definePrismaConfig({ skills: { agents: ["claude", "cursor"], check: true, }, }); ``` | Field | What it does | | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `agents` | The agent harnesses `skills sync` writes and `skills list` reports: `claude`, `cursor`, `agents`, `devin`. An empty array records that no agent skills are wanted, and the next `skills sync` removes the copies already on disk. Default: all of them. | | `check` | Set `false` to stop commands reporting out-of-date skills, for everyone working in the project. Default: `true`. | [`init`](https://www.prisma.io/docs/cli/init) scaffolds this section for you. ## Database URLs [#database-urls] Database commands accept `--db `. If you omit it, Prisma ORM uses the database connection from `prisma.config.ts`. #### bun ```bash bunx prisma db verify --db "$DATABASE_URL" ``` #### pnpm ```bash pnpm prisma db verify --db "$DATABASE_URL" ``` #### yarn ```bash yarn prisma db verify --db "$DATABASE_URL" ``` #### npm ```bash npx prisma db verify --db "$DATABASE_URL" ``` ## Environment variables [#environment-variables] The variables the CLI reads, such as `PRISMA_DISABLE_TELEMETRY`, `PRISMA_SKILLS_CHECK`, and the `PRISMA_SERVICE_TOKEN` pair for CI, are listed on [Environment variables](https://www.prisma.io/docs/cli/environment-variables). `DATABASE_URL` is not one of them: your config file reads it, as in the example above. ## Output modes [#output-modes] Use the default text output when running commands locally. Use `--json` in CI or automation: #### bun ```bash bunx prisma db verify --db "$DATABASE_URL" --json ``` #### pnpm ```bash pnpm prisma db verify --db "$DATABASE_URL" --json ``` #### yarn ```bash yarn prisma db verify --db "$DATABASE_URL" --json ``` #### npm ```bash npx prisma db verify --db "$DATABASE_URL" --json ``` Piping a command does not switch it to JSON: without `--json`, standard output gets the command's plain data, such as one line per item of a list. See [Global flags](https://www.prisma.io/docs/cli/global-flags#output-formats). For an AI agent that reads the output as text rather than parsing JSON, use `--format markdown`; see [Global flags](https://www.prisma.io/docs/cli/global-flags#output-formats). Use `--no-interactive` for scripts that must never pause for user input. Use `--confirm ` to grant a consent prompt non-interactively. Commands that ask about data loss, such as [`db update`](https://www.prisma.io/docs/cli/db-update), take their answers as flags instead: `--delete`, `--rename`, and `--allow`. ## JSON output [#json-output] In `--json` mode, commands emit newline-delimited JSON events. Progress events have `kind: "step-finished"`. The final event has `kind: "result"` and carries the `envelope` object your script branches on: * `envelope.ok`: `true` or `false`. * `envelope.result`: the command's data, when `ok` is `true`. * `envelope.error.code`: a dotted `NAMESPACE.SUBCODE`, for example `PROJECT.NOT_FOUND` or `SERVICE.PROJECT_SETUP_REQUIRED`. * `envelope.error.summary` and `envelope.error.why`: what failed and why it was rejected. * `envelope.nextActions`: machine-readable follow-up commands, so agents can drive the CLI. Branch on `envelope.error.code`, not the message text: codes are a stable contract, while message wording can change between releases. ## Related pages - [`auth`](https://www.prisma.io/docs/cli/auth): Sign in to your Prisma account from the CLI, sign out, and manage workspace sessions. - [`branch`](https://www.prisma.io/docs/cli/branch): List platform branches for a project. - [`bucket`](https://www.prisma.io/docs/cli/bucket): Create and manage object-store buckets. - [`contract emit`](https://www.prisma.io/docs/cli/contract-emit): Emit Prisma ORM contract artifacts. - [`contract infer`](https://www.prisma.io/docs/cli/contract-infer): Infer a starter contract from an existing database.