NestJS
This guide shows you how to use Prisma ORM in a NestJS API. You scaffold a project with a users controller backed by Prisma ORM, initialize the schema, query it over HTTP, and deploy the API to Prisma Compute.
Every command below was run end to end against a live Prisma Postgres database.
- Node.js 22.18 or newer (on the 24 line, 24.11 or newer; 24 recommended)
- A PostgreSQL connection string, or nothing at all:
npx create-db@latestcan create a Prisma Postgres database for you
To delegate this guide to your coding agent, copy the prompt below and hand it over:
Create a new NestJS API with Prisma ORM, seed it, and deploy it to Prisma Compute.
1. Scaffold: `npm create prisma@latest -- my-nest-api --template nest --provider postgres --yes`. Then run `npx prisma@latest init` in `my-nest-api` so the Prisma agent skills are installed and stay current, and use them. Get a database connection string: use the one I give you, or create a Prisma Postgres database with `npx create-db@latest` and show me the claim URL it prints. Export it as `DATABASE_URL` in the shell; the generated scripts read the environment variable, not `.env`.
2. In `my-nest-api`, run `npm run db:init` with `DATABASE_URL` exported. Sample users are seeded automatically on the app's first query; there is no separate seed script.
3. Start `npm run dev` in the background, wait until it reports ready, and verify `curl http://localhost:3000/users` returns the seeded users; stop the dev server once verified.
4. Deploy: check `npx prisma auth whoami`; if I am not signed in, stop and ask me to run `npx prisma auth login`. Then run `npm run build` followed by `npx prisma deploy module.ts` and verify the live URL's /users endpoint. The deployed app provisions and seeds its own Prisma Postgres database; do not pass the local DATABASE_URL. If the deploy fails with `HostedStateBootstrapError`, a project with the module's name exists in my workspace but its hosted state cannot be verified; re-run the deploy with `--name <a unique name>`.
Use the installed Prisma ORM skills.bun create prisma@latest my-nest-api --template nest --provider postgres --no-deploy
cd my-nest-apipnpm create prisma@latest my-nest-api --template nest --provider postgres --no-deploy
cd my-nest-apiyarn create prisma@latest my-nest-api --template nest --provider postgres --no-deploy
cd my-nest-apinpm create prisma@latest -- my-nest-api --template nest --provider postgres --no-deploy
cd my-nest-apiAnswer the prompts for contract authoring style, package manager, and agent skills. The scaffold generates the NestJS app with Prisma ORM wired in, installs dependencies, and emits the contract your queries are type-checked against.
Next, set the database connection for the local steps. Use your own PostgreSQL connection string, or create a Prisma Postgres database with npx create-db@latest; it prints a connection string and a claim URL you can open to keep the database. Export the variable in the shell you work in; the generated scripts read the environment variable, not .env:
export DATABASE_URL="<your connection string>"Answer the prompts for contract authoring style, package manager, and agent skills. The scaffold generates the NestJS app with Prisma ORM wired in, installs dependencies, and emits the contract your queries are type-checked against.
Next, set the database connection for the local steps. Use your own PostgreSQL connection string, or create a Prisma Postgres database with npx create-db@latest; it prints a connection string and a claim URL you can open to keep the database. Export the variable in the shell you work in; the generated scripts read the environment variable, not .env:
export DATABASE_URL="<your connection string>"bun run db:initpnpm run db:inityarn db:initnpm run db:init"summary": "Applied 5 operation(s) across 1 space(s), database signed"If db:init stops with Connection terminated unexpectedly, a database you just created is still starting; wait a few seconds and run it again. The command is safe to repeat and reports Applied 0 operation(s) when there is nothing left to do.
db:init applies your schema (src/prisma/contract.prisma) to the database and signs it. With TypeScript authoring (--authoring typescript) the schema is src/prisma/contract.ts and the emitted files land in src/prisma/generated/. Sample users are seeded automatically the first time the app queries the database.
"summary": "Applied 5 operation(s) across 1 space(s), database signed"If db:init stops with Connection terminated unexpectedly, a database you just created is still starting; wait a few seconds and run it again. The command is safe to repeat and reports Applied 0 operation(s) when there is nothing left to do.
db:init applies your schema (src/prisma/contract.prisma) to the database and signs it. With TypeScript authoring (--authoring typescript) the schema is src/prisma/contract.ts and the emitted files land in src/prisma/generated/. Sample users are seeded automatically the first time the app queries the database.
bun run devpnpm run devyarn devnpm run devThe server starts on port 3000 (set PORT to change it). Query the API:
curl http://localhost:3000/users[
{ "id": "1", "email": "alice@prisma.io", "username": "alice", "name": "Alice", "createdAt": "2026-07-24T10:55:54.156Z" },
{ "id": "2", "email": "bob@prisma.io", "username": "bob", "name": "Bob", "createdAt": "2026-07-24T10:55:54.192Z" },
{ "id": "3", "email": "carol@prisma.io", "username": "carol", "name": "Carol", "createdAt": "2026-07-24T10:55:54.228Z" }
]src/users.controller.ts: theGET /usersroutesrc/users.service.ts: the service the controller callssrc/prisma.service.ts: the injectable that exposes the Prisma ORM client and query helperssrc/prisma/users.ts: thelistUsersquery the service runssrc/prisma/db.ts: the Prisma ORM client itself
Model access is namespace-qualified on PostgreSQL: db.orm.public.User. The Prisma ORM overview covers the contract-first model behind it.
NestJS is supported on Prisma Compute. The scaffold declares the app for Prisma Composer in module.ts and service.ts, so deploying is building and handing that declaration to the CLI. Sign in once (it opens a browser):
bunx prisma auth loginpnpm prisma auth loginyarn prisma auth loginnpx prisma auth loginThen build and deploy from the project directory:
bun run build
bunx prisma deploy module.tspnpm run build
pnpm prisma deploy module.tsyarn build
yarn prisma deploy module.tsnpm run build
npx prisma deploy module.tsmy-nest-api
├─ database postgres-database db_abc123
└─ app compute-service cps_abc123
https://xyz.ewr.prisma.buildThe deploy creates a project named after your module in your workspace, and re-running the deploy reuses it: the CLI finds the hosted state it stored on the first run and converges the project to your module. If a project with that name exists but the CLI cannot identify or verify its stored state (one left behind by a different checkout, for example), the deploy stops with HostedStateBootstrapError; deploy under another name with --name <unique-name>, or rename the module in module.ts. The deploy also provisions its own Prisma Postgres database on the platform, declared in module.ts; the DATABASE_URL from your local steps is not involved, and the deployed database seeds on the app's first query. Verify the live endpoint returns the seeded users:
curl https://xyz.ewr.prisma.build/usersFor previews per Git branch and deploy on push, see Deploy on push.
my-nest-api
├─ database postgres-database db_abc123
└─ app compute-service cps_abc123
https://xyz.ewr.prisma.buildThe deploy creates a project named after your module in your workspace, and re-running the deploy reuses it: the CLI finds the hosted state it stored on the first run and converges the project to your module. If a project with that name exists but the CLI cannot identify or verify its stored state (one left behind by a different checkout, for example), the deploy stops with HostedStateBootstrapError; deploy under another name with --name <unique-name>, or rename the module in module.ts. The deploy also provisions its own Prisma Postgres database on the platform, declared in module.ts; the DATABASE_URL from your local steps is not involved, and the deployed database seeds on the app's first query. Verify the live endpoint returns the seeded users:
curl https://xyz.ewr.prisma.build/usersFor previews per Git branch and deploy on push, see Deploy on push.
Run npx prisma@latest init once to install the Prisma ORM skills for your coding agent and keep them matching your installed packages. Prompts that map to this guide:
-
"Using the prisma-8 skill, add GET /users/
to the users controller that returns one user or a 404."
-
"Expose GET /users/
/posts using the Post model that ships with the starter contract."
-
"Add a POST /users route that creates a user from the request body and returns it with a 201."
- Change the schema in
src/prisma/contract.prisma, then runnpm run contract:emitandnpm run db:update. - Learn the fundamentals: filtering, sorting, pagination, and writes.
- Read the Prisma ORM overview for the concepts behind contracts and typed queries.