Skip to main content
The ORM client is the high-level query surface in Prisma Next. It gives you typed model collections with a fluent API for filtering, ordering, pagination, relations, and mutations — all verified against your emitted contract at compile time. You compose queries by chaining methods on a collection; the client builds and executes the required SQL plans for you.

Setting up the ORM client

For a long-lived Node process, the db.orm property is available directly on the postgres() facade. ORM collection accessors use the model name from your contract (capitalized, as declared in your schema):
For serverless runtimes, use createOrmClient(runtime) inside the request handler instead. See Deploying to serverless runtimes for the full pattern.

Defining collection classes

Collections are classes that extend the base Collection type and are registered on the orm() factory. Each collection maps to a model in your contract and can expose custom query methods:
Register collections on the orm() factory. Pass the runtime from db.runtime() (synchronous):

Filtering with .where()

You can pass a shorthand object filter or a typed expression callback. Both forms can be chained:

Sorting with .orderBy()

Pass a callback that selects a field and calls a direction method:

Pagination with .take() and .skip()

Including relations with .include()

Pass a relation name to eager-load it. You can pass a callback to further constrain the included collection — including nested includes:
Each nested .include() is a fully typed collection: you get the same .where(), .orderBy(), .take(), and .select() methods at every level.

Selecting fields with .select()

Use .select() to return only specific fields. TypeScript infers the return type from the selected columns:

Fetching results

.stream() returns an AsyncIterableResult. If execution fails, the iterable throws. Wrap streaming consumers in a try/catch or use a for await that propagates errors naturally.

Creating, updating, and deleting records

update() and delete() require a .where() clause. Calling them without filtering is a compile-time error — Prisma Next enforces this to prevent accidental bulk mutations.

Using withTransaction() for mutations

Wrap related mutations in a transaction to ensure atomicity. The withTransaction helper from @prisma-next/sql-runtime acquires a transaction on the runtime and runs your callback:
All statements inside the callback run on the same connection. If the callback throws, the transaction is rolled back automatically.

Using the ORM client in a serverless context

In per-request runtimes, construct the ORM client inside the request handler using the per-request runtime returned by db.connect():
Where createOrmClient is a factory that passes the per-request runtime to orm({...}):