# contract.json and contract.d.ts (/docs/orm/contract-authoring/the-contract-artifact)

> 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.

contract.json and contract.d.ts are the two files every other part of Prisma ORM reads. Here is what is inside them.

Location: ORM > Contract authoring > contract.json and contract.d.ts

Your contract is [a single file that describes your data and how it is stored](https://www.prisma.io/docs/orm/contract-authoring/the-data-contract). It replaces the `schema.prisma` of Prisma ORM 7 and is either `src/prisma/contract.prisma` in Prisma Schema Language (PSL) or `src/prisma/contract.ts` in TypeScript. [`npx prisma contract emit`](https://www.prisma.io/docs/cli/contract-emit) reads that file and writes two files beside it. In the table below, `db` is your client, the object you run queries on. [`npx prisma orm init`](https://www.prisma.io/docs/cli/orm-init) creates the contract source, `src/prisma/db.ts`, and `.env.example` for you. In Prisma ORM 7 you edited `schema.prisma` and the tooling read the same file, but now you edit the contract and the tooling reads the two files it produces.

| File            | Contents                                                                                                      | Read by                                                                 |
| --------------- | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `contract.json` | The machine-readable contract: models, how they are stored, which database features they need, and the hashes | `db`, `prisma db sign`, `prisma db verify`, and `prisma migration plan` |
| `contract.d.ts` | TypeScript declarations derived from the contract                                                             | The query APIs and your application code, for typed models and results  |

`prisma db sign` writes the current contract's hashes into the database, so later commands can tell which contract that database was built for. Both files are generated, so do not edit them: change the [PSL](https://www.prisma.io/docs/orm/contract-authoring/psl-syntax) or [TypeScript](https://www.prisma.io/docs/orm/contract-authoring/typescript-schema-builder) source and run `npx prisma contract emit` again. `contract.d.ts` starts with a comment saying it is generated and must not be edited, and `contract.json` carries the same notice in a `_generated` entry. To write the two files to another directory, see [`prisma contract emit`](https://www.prisma.io/docs/cli/contract-emit).

The everyday loop on a project:

1. Edit `contract.prisma` or `contract.ts`.
2. Run `npx prisma contract emit`.
3. Create the migration with [`npx prisma migration plan`](https://www.prisma.io/docs/cli/migration-plan), read it, then apply it with [`npx prisma db migrate`](https://www.prisma.io/docs/cli/db-migrate).
4. Check the database against the contract with [`npx prisma db verify`](https://www.prisma.io/docs/cli/db-verify) in CI or in your deploy step.

`npx prisma db verify` reports whether the database has a record and whether it matches. You almost never sign a database yourself:

* Applying a migration records the match for you, and so does [`npx prisma db init`](https://www.prisma.io/docs/cli/db-init) when it creates the structures in an empty database.
* Run [`npx prisma db sign`](https://www.prisma.io/docs/cli/db-sign) by hand only after [`npx prisma contract infer`](https://www.prisma.io/docs/cli/contract-infer) has written a starter contract from a database that already matches it.

## The same source always produces the same two files [#deterministic-emission]

Run `npx prisma contract emit` on the same source on any machine and you get the same two files, byte for byte. That holds only if your contract source does not read the environment, the clock, or random values, and the [TypeScript authoring page](https://www.prisma.io/docs/orm/contract-authoring/typescript-schema-builder#keep-the-contract-file-pure) lists the rules.

## The content hashes [#the-content-hashes]

`npx prisma contract emit` computes a hash over each part of the contract, and you never compute or compare them yourself. `storageHash` covers the storage layout: tables, columns, primary keys, uniques, indexes, foreign keys, and the allowed values of each enum. `profileHash` covers which database the contract targets. The hashes are how Prisma ORM connects the contract to a live database: `npx prisma db sign` checks that the database satisfies the contract, then records `storageHash` and `profileHash` in the database. `npx prisma db verify` compares the contract you hold against that record and against the live schema, and fails when they disagree. To fix a mismatch, apply the pending migration, or run `npx prisma db sign` when the database already matches the contract.

## Inside `contract.json` [#inside-contractjson]

The contract keeps your application's view of the data separate from the way the database stores it. The `domain` section describes models, fields, and relations, while the `storage` section describes tables, columns, keys, and indexes. On MongoDB it describes collections and indexes instead. Each model's own `storage` block maps each field to its column. Everything is grouped by namespace, and on PostgreSQL the namespace is the schema, which is `public` unless you put the models in a `namespace` block in your [PSL source](https://www.prisma.io/docs/orm/contract-authoring/psl-syntax).

An abridged `contract.json` for a `User` and `Post` schema:

```json title="src/prisma/contract.json (abridged)"
{
  "schemaVersion": "1",
  "targetFamily": "sql",
  "target": "postgres",
  "profileHash": "…",
  "roots": {
    "post": { "model": "Post", "namespace": "public" },
    "user": { "model": "User", "namespace": "public" }
  },
  "domain": {
    "namespaces": {
      "public": {
        "models": {
          "User": {
            "fields": {
              "email": { "nullable": false, "type": { "codecId": "pg/text@1", "kind": "scalar" } },
              "id": { "nullable": false, "type": { "codecId": "pg/uuid@1", "kind": "scalar" } }
            },
            "storage": {
              "fields": { "email": { "column": "email" }, "id": { "column": "id" } },
              "namespaceId": "public",
              "table": "user"
            }
          }
        }
      }
    }
  },
  "storage": {
    "namespaces": {
      "public": {
        "entries": {
          "table": {
            "user": {
              "columns": {
                "email": { "codecId": "pg/text@1", "nativeType": "text", "nullable": false },
                "id": { "codecId": "pg/uuid@1", "nativeType": "uuid", "nullable": false }
              },
              "primaryKey": { "columns": ["id"] }
            }
          }
        }
      }
    },
    "storageHash": "…"
  },
  "capabilities": { "postgres": { "returning": true } }
}
```

The sections, top to bottom:

* **`schemaVersion`, `targetFamily`, `target`**: the contract format version, whether the database is SQL or MongoDB, and which database this contract targets.
* **`roots`**: one entry per table that stores a model. The key is the name of that table, so for a model `User` mapped to a table `users` the key is `users`. The value names the model. The [ORM reference](https://www.prisma.io/docs/orm/reference) covers both ways of reaching it, `db.sql.public.user` by table name and `db.orm.public.User` by model name.
* **`domain` and `storage`**: your application's view, then the database's view. Each scalar field in `domain` records whether it is nullable and its `codecId`. `nativeType` is the column type in the database. `codecId` names how Prisma ORM reads and writes the value, the PostgreSQL type plus a version. `storage` holds the tables with their columns, keys, indexes, constraints, and enum values. `prisma db verify` compares it to the live database.
* **`capabilities`**: which database features this contract can use. `npx prisma contract emit` collects them from the adapter for your database and from the packages listed in `extensions: [...]` in `prisma.config.ts`, the config file `prisma orm init` writes. The query APIs check them before building a query that needs one. See [supported database features](https://www.prisma.io/docs/orm/contract-authoring/capabilities) and [extension types](https://www.prisma.io/docs/orm/contract-authoring/psl-syntax#extension-types).

## Inside `contract.d.ts` [#inside-contractdts]

The declarations file gives the type system the same information. It exports:

* `Contract`, the type the client is built from. `db.ts` imports it.
* One type per hash, such as `StorageHash` and `ProfileHash`. Each one carries the hash of that part of the contract.
* Input and output types for each [`type` block](https://www.prisma.io/docs/orm/contract-authoring/psl-syntax#value-objects) in your contract.

```typescript title="src/prisma/contract.d.ts (excerpt)"
export type StorageHash =
  StorageHashBase<'9f49f8f9e51a9cc016f1ec2098ebae9406521a3cc2cf00207adc795078333d8b'>;
```

You never write these types yourself. Both files come from the one `npx prisma contract emit` run, so they only drift when someone commits one and not the other. The CI check below catches that.

## How the application consumes the artifacts [#how-the-application-consumes-the-artifacts]

`db` is built from both files: `contract.json` as the value, `contract.d.ts` as the type. `prisma orm init` writes `src/prisma/db.ts` for you.

```typescript title="src/prisma/db.ts"
import "dotenv/config";
import postgres from "@prisma/orm-postgres/runtime";
import type { Contract } from "./contract.d";
import contractJson from "./contract.json" with { type: "json" };

export const db = postgres<Contract>({
  contractJson,
  url: process.env['DATABASE_URL']!,
});
```

The connection string comes from the `DATABASE_URL` environment variable: `prisma orm init` writes `.env.example`, and you put your `DATABASE_URL` in `.env`. Keep the `.d` in the import path, because if you delete it the import stops resolving. The `tsconfig.json` settings the JSON import needs are on the [transactions and runtime page](https://www.prisma.io/docs/orm/reference/transactions-and-runtime). Before its first query, `db` reads the record in the database of which contract it matches and compares it with the contract's hashes. If they do not match, it logs a warning whose `code` is `CONTRACT.MARKER_MISMATCH` and runs the query anyway. If there is no record at all, because nothing has signed the database yet, it logs a warning whose `code` is `CONTRACT.MARKER_MISSING` and again runs the query. On MongoDB the client is `mongo<Contract>(...)` from `@prisma/orm-mongo/runtime`, described under [`mongo(options)`](https://www.prisma.io/docs/orm/reference/transactions-and-runtime#mongooptions).

When `CONTRACT.MARKER_MISMATCH` shows up in production, apply the pending migration, or run `npx prisma db sign` when the database already matches the contract. The client warns by default, and you can set [`verifyMarker`](https://www.prisma.io/docs/orm/reference/transactions-and-runtime#postgresoptions) to `false` to skip the check. It cannot be made to fail, so run `prisma db verify` when you need a check that fails.

## Version control [#version-control]

Commit `contract.json` and `contract.d.ts` alongside the source: they hold structure only, no data and no credentials. Committing them lets teammates, CI, and deploys read the contract without running `npx prisma contract emit` first. Run `npx prisma contract emit` after every source change so the two files never trail the source. A CI job can check this in two lines:

```bash
npx prisma contract emit
git diff --exit-code src/prisma
```

## Prompt your coding agent [#prompt-your-coding-agent]

Projects created with `npm create prisma@latest` include the [Prisma ORM skills](https://www.prisma.io/docs/ai/tools/skills#available-skills-for-prisma-8) for your coding agent. In an existing project, run `npx prisma skills sync` to add them. The `prisma-8` skill covers the contract, so ask your agent to:

* "Explain the difference between contract.json and contract.d.ts in this project."
* "Run prisma contract emit and show me what changed in contract.json."

## Next steps [#next-steps]

* Learn [which database features](https://www.prisma.io/docs/orm/contract-authoring/capabilities) the contract needs, and how Prisma ORM checks that your database has them.
* Apply the contract to a fresh database with [`prisma db init`](https://www.prisma.io/docs/cli/db-init).
* Check a live database against the contract with [`prisma db verify`](https://www.prisma.io/docs/cli/db-verify).
* Plan schema changes between contract versions with [`prisma migration plan`](https://www.prisma.io/docs/cli/migration-plan).

## Related pages

- [`Author in PSL`](https://www.prisma.io/docs/orm/contract-authoring/psl-syntax): Write the Prisma ORM contract in the Prisma schema language you already know, plus the Prisma ORM 8 additions.
- [`Author in TypeScript`](https://www.prisma.io/docs/orm/contract-authoring/typescript-schema-builder): Define the Prisma ORM contract with a typed builder in TypeScript instead of a schema file. Same models, same `contract.json` and `contract.d.ts`, no separate language.
- [`Editor support`](https://www.prisma.io/docs/orm/contract-authoring/editor-support): What the Prisma VS Code extension does for a Prisma ORM contract, and what to do when it stops accepting the file.
- [`Supported database features`](https://www.prisma.io/docs/orm/contract-authoring/capabilities): The contract records which database features your packages support, so Prisma ORM can reject an unsupported one early with a clear error.
- [`The data contract`](https://www.prisma.io/docs/orm/contract-authoring/the-data-contract): The data contract is the one description of your data model and how it is stored. Prisma ORM types your queries, plans your migrations, and checks your database against it.