PostgreSQL
Add Prisma Next to an existing PostgreSQL project.
This guide shows how to add Prisma Next to a project that already uses PostgreSQL. You will run prisma-next 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 24 or newer. If you want Prisma Next to create a new app for you, use the PostgreSQL quickstart.
Prisma Next is the next major version of Prisma ORM, available now in Early Access. It’s the cutting-edge version of Prisma ORM and will become the future of Prisma, so we’d love for you to try it, explore what’s new, and share your feedback in Discord.
If you want to stay on the current generally available version of Prisma ORM, you can continue with Prisma 7.
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 add --dev tsx typescriptLater, prisma-next init will also add the Node.js types it needs and make sure the generated Prisma Next files can run as ES modules. If your project already declares "type": "commonjs", Prisma Next leaves that choice alone and prints a warning so you can decide how to wire the generated helper into your app.
2. Initialize Prisma Next
From the root of your existing project, run:
bunx prisma-next init --target postgresThis is the existing-project path. It preselects PostgreSQL, adds Prisma Next files and package scripts to the app you already have, and does not scaffold a new framework project.
It also adds prisma-next.md and project-level Prisma Next skills for Cursor, Claude Code, Codex, and Windsurf so your agent can read the Prisma Next usage, upgrade, and extension-author guidance from the project.
When Prisma Next asks the remaining setup questions:
- choose
PSL - keep the default schema path,
prisma/contract.prisma
3. Set your database connection string
Update .env with the connection string for the database your app already uses:
DATABASE_URL="postgres://username:password@host:5432/database?sslmode=require"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:
bunx prisma-next contract infer --output ./prisma/contract.prismaThis reads the live PostgreSQL schema and writes a first draft of 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 Next to know about first, and make the file easier to read.
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:
bunx prisma-next contract emitThis refreshes prisma/contract.json and prisma/contract.d.ts so the runtime and query APIs are aligned with the contract you just reviewed.
6. Sign the database
Record that the live database matches the emitted contract:
bunx prisma-next db signThis step matters in two common cases:
- the database has never been signed by Prisma Next before
- the database was signed earlier, but under an older contract hash
7. Run a simple high-level query
With the database signed, you can test the higher-level API first and confirm Prisma Next is reading the existing schema correctly.
Create a script.ts file:
import "dotenv/config";
import { db } from "./prisma/db";
async function main() {
const runtime = await db.connect({ url: process.env.DATABASE_URL! });
const users = await db.orm.User
.select("id", "email", "name")
.take(2)
.all();
console.log(users);
await runtime.close();
}
main().catch((error) => {
console.error(error);
process.exit(1);
});Run it:
bunx tsx script.ts8. Run a simple low-level query
After the ORM example, this step shows the lower-level SQL builder against the same existing schema.
Replace script.ts with this version:
import "dotenv/config";
import { db } from "./prisma/db";
async function main() {
const runtime = await db.connect({ url: process.env.DATABASE_URL! });
const plan = db.sql.user
.select("id", "email", "name")
.limit(2)
.build();
const rows = await db.runtime().execute(plan);
console.log(rows);
await runtime.close();
}
main().catch((error) => {
console.error(error);
process.exit(1);
});Run it again:
bunx tsx script.ts9. Next steps
When you change prisma/contract.prisma, emit the contract again:
bunx prisma-next contract emitUse db update for a direct development update, or migration plan when you want a checked-in migration.