# PostgreSQL (/docs/prisma-orm/add-to-existing-project/postgresql) > 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. Add Prisma ORM to an existing PostgreSQL project. Location: Prisma ORM > Add to Existing Project > PostgreSQL To add Prisma ORM to a project that already uses PostgreSQL, you will run `orm init`, infer a contract from the live schema, sign the database, and run a couple of queries. Use this path when you already have an application and database. Make sure the app can already reach its PostgreSQL database and runs on Node.js 22.18 or newer (on the 24 line, 24.11 or newer; Node.js 24 is recommended). If you want Prisma ORM to create a new app for you, use the [PostgreSQL quickstart](https://www.prisma.io/docs/prisma-orm/quickstart/postgresql). > [!NOTE] > Using Prisma ORM 7? > > Prisma ORM 8 is the current release, as a release candidate. Prisma ORM 7 remains fully supported; its docs live at [/orm/v7](https://www.prisma.io/docs/orm/v7) and its setup paths at [/v7/getting-started](https://www.prisma.io/docs/v7/getting-started). > > For what release candidate means, when the final release is expected, and how to stay on version 7, see [Release status](https://www.prisma.io/docs/orm/release-status). For the Prisma ORM 8 name of every Prisma ORM 7 API, see [Coming from Prisma ORM 7](https://www.prisma.io/docs/orm/coming-from-prisma-orm-7). ## 1. Make sure you can run the example script [#1-make-sure-you-can-run-the-example-script] If your project already runs TypeScript scripts, you can skip this step. Otherwise, install the script tooling: #### bun ```bash bun add --dev tsx typescript ``` #### pnpm ```bash pnpm add --save-dev tsx typescript ``` #### yarn ```bash yarn add --dev tsx typescript ``` #### npm ```bash npm install --save-dev tsx typescript ``` ## 2. Initialize Prisma ORM [#2-initialize-prisma-orm] From the root of your existing project, run: #### bun ```bash bunx prisma@latest orm init --target postgres ``` #### pnpm ```bash pnpm dlx prisma@latest orm init --target postgres ``` #### yarn ```bash yarn dlx prisma@latest orm init --target postgres ``` #### npm ```bash npx prisma@latest orm init --target postgres ``` This command is for a project that already exists: it preselects PostgreSQL, adds Prisma ORM files and package scripts to the app you already have, and does not scaffold a new framework project. `orm init` also changes the `module` settings in `tsconfig.json`, and adds `"type": "module"` to `package.json` when the file has no `"type"` field. If your app is CommonJS, follow [In a CommonJS project](https://www.prisma.io/docs/cli/orm-init#in-a-commonjs-project) before you run the app again. The scripts in this guide run through `tsx`, which works in both kinds of project. It also adds `prisma-8.md`, a short project-level reference your coding agent can read. It does not install agent skills; the Prisma ORM skill ships inside the `@prisma/orm-postgres` package your project installs. If you later run `prisma init` or `prisma skills sync`, Prisma writes skill files for coding agents into your repo. To stop that, pass `--skills=none` to [`init`](https://www.prisma.io/docs/cli/init) or set the [`skills.agents`](https://www.prisma.io/docs/cli/configuration#agent-skills) config field to `[]`; the next [`skills sync`](https://www.prisma.io/docs/cli/skills) removes any copies already written. When Prisma ORM asks the remaining setup questions: * choose `PSL` * keep the default schema path, `src/prisma/contract.prisma`. Pass `--schema-path` if you want the contract somewhere else; the rest of this page assumes the default. * answer the last question, `Also write a .env file from .env.example? (gitignored)`, with Yes. It defaults to No, and `--write-env` skips the prompt and writes the file. ## 3. Set your database connection string [#3-set-your-database-connection-string] `orm init` always writes `.env.example`, and writes `.env` only if you asked it to. Put the connection string for the database your app already uses into `.env`: ```text title=".env" DATABASE_URL="postgres://username:password@host:5432/database?sslmode=require" ``` `orm init` also writes `src/prisma/db.ts`, the file your application imports. It builds the Prisma ORM client from the emitted contract and reads the connection string from the environment: ```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({ contractJson, url: process.env["DATABASE_URL"]!, }); ``` The first line is `import "dotenv/config"`, so any script that imports `db` loads `.env` for itself. You do not need to pass the URL again at the call site. ## 4. Infer a starter contract from the live database [#4-infer-a-starter-contract-from-the-live-database] This step gives you a starting contract by reading the schema that already exists in PostgreSQL. Run: #### bun ```bash bunx prisma contract infer --output ./src/prisma/contract.prisma ``` #### pnpm ```bash pnpm prisma contract infer --output ./src/prisma/contract.prisma ``` #### yarn ```bash yarn prisma contract infer --output ./src/prisma/contract.prisma ``` #### npm ```bash npx prisma contract infer --output ./src/prisma/contract.prisma ``` The command writes a first draft of `src/prisma/contract.prisma`. Open that file and review it before you go on. This is the moment to clean up model names, keep only the tables you want Prisma ORM to know about first, and make the file easier to read. A model's table is the model name exactly as written, so a table such as `User` gets a model with no `@@map`, and a table such as `user` or `user_profile` gets `@@map` with its name. Keep those `@@map` lines when you rename a model, so the table stays the same. > [!NOTE] > Temporal types on inferred date and time columns > > `contract infer` maps `timestamp` columns to `Timestamp` and `timestamptz` columns to `Timestamptz`. Both read and write their values through the global `Temporal` API. Node.js 26 ships it enabled by default (check with `node -p "typeof Temporal"`, which prints `object` when it is there); on Node.js 24 and earlier, reading such a column fails with `RUNTIME.TEMPORAL_UNAVAILABLE` unless you install [`temporal-polyfill`](https://www.npmjs.com/package/temporal-polyfill) and add `import "temporal-polyfill/full/global";` before the first query. If you would rather not add the polyfill, change the field's type in the contract to `TimestamptzString` and read and write PostgreSQL's own text instead. ## 5. Emit the generated artifacts [#5-emit-the-generated-artifacts] Once the contract looks right, this step turns it into the generated files the runtime and CLI use. After you are happy with the contract, run: #### bun ```bash bunx prisma contract emit ``` #### pnpm ```bash pnpm prisma contract emit ``` #### yarn ```bash yarn prisma contract emit ``` #### npm ```bash npx prisma contract emit ``` This refreshes `src/prisma/contract.json` and `src/prisma/contract.d.ts` so the runtime and query APIs match the contract you just reviewed. ## 6. Sign the database [#6-sign-the-database] Record that the live database matches the emitted contract: #### bun ```bash bunx prisma db sign ``` #### pnpm ```bash pnpm prisma db sign ``` #### yarn ```bash yarn prisma db sign ``` #### npm ```bash npx prisma db sign ``` **Expected result:** `Database signed`. The command also stores the contract snapshot under `migrations/snapshots/` and points the `db` ref at it, so a later [migration plan](https://www.prisma.io/docs/cli/migration-plan) starts from the schema you just adopted instead of from an empty database. This step matters in two common cases: * the database has never been signed by Prisma ORM before * the database was signed earlier, but under an older contract hash ## 7. Run a simple high-level query [#7-run-a-simple-high-level-query] With the database signed, you can test the higher-level API first and confirm Prisma ORM is reading the existing schema correctly. Create a `script.ts` file: ```typescript title="script.ts" import { db } from "./src/prisma/db"; async function main() { const users = await db.orm.public.User .select("id", "email", "name") .limit(2) .all(); console.log(users); await db.close(); } main().catch((error) => { console.error(error); process.exit(1); }); ``` Run it: #### bun ```bash bunx tsx script.ts ``` #### pnpm ```bash pnpm dlx tsx script.ts ``` #### yarn ```bash yarn dlx tsx script.ts ``` #### npm ```bash npx tsx script.ts ``` ## 8. Run a simple low-level query [#8-run-a-simple-low-level-query] After the ORM example, this step shows the lower-level SQL builder against the same existing schema. The SQL builder names the table, where the ORM API names the model. This example reads a table named `User`. If your model has `@@map("user")`, write `db.sql.public.user`. Replace `script.ts` with this version: ```typescript title="script.ts" import { db } from "./src/prisma/db"; async function main() { const plan = db.sql.public.User .select("id", "email", "name") .limit(2) .build(); const rows = await db.runtime().query(plan); console.log(rows); await db.close(); } main().catch((error) => { console.error(error); process.exit(1); }); ``` Run it again: #### bun ```bash bunx tsx script.ts ``` #### pnpm ```bash pnpm dlx tsx script.ts ``` #### yarn ```bash yarn dlx tsx script.ts ``` #### npm ```bash npx tsx script.ts ``` ## 9. Next steps [#9-next-steps] When you change `src/prisma/contract.prisma`, emit the contract again: #### bun ```bash bunx prisma contract emit ``` #### pnpm ```bash pnpm prisma contract emit ``` #### yarn ```bash yarn prisma contract emit ``` #### npm ```bash npx prisma contract emit ``` Use [db update](https://www.prisma.io/docs/cli/db-update) for a direct development update, or [migration plan](https://www.prisma.io/docs/cli/migration-plan) when you want a checked-in migration. Put together, adopting the database and making a first schema change is this sequence: #### bun ```bash bunx prisma contract infer --output ./src/prisma/contract.prisma bunx prisma contract emit bunx prisma db sign # edit src/prisma/contract.prisma bunx prisma contract emit bunx prisma migration plan --name ``` #### pnpm ```bash pnpm prisma contract infer --output ./src/prisma/contract.prisma pnpm prisma contract emit pnpm prisma db sign # edit src/prisma/contract.prisma pnpm prisma contract emit pnpm prisma migration plan --name ``` #### yarn ```bash yarn prisma contract infer --output ./src/prisma/contract.prisma yarn prisma contract emit yarn prisma db sign # edit src/prisma/contract.prisma yarn prisma contract emit yarn prisma migration plan --name ``` #### npm ```bash npx prisma contract infer --output ./src/prisma/contract.prisma npx prisma contract emit npx prisma db sign # edit src/prisma/contract.prisma npx prisma contract emit npx prisma migration plan --name ``` The plan starts from the contract `db sign` recorded, so it contains only your change. Because `migrations/app/` is still empty, that first plan also writes a baseline package recording the schema you adopted; see [the automatic baseline](https://www.prisma.io/docs/cli/migration-plan#the-automatic-baseline). ## Related pages - [`MongoDB`](https://www.prisma.io/docs/prisma-orm/add-to-existing-project/mongodb): Add Prisma ORM to an existing MongoDB project.