Loading...
Loading...
Wire the Prisma Next runtime — `db.ts` setup using `postgres<Contract>(...)` from `@prisma-next/postgres/runtime`, middleware composition (telemetry from `@prisma-next/middleware-telemetry`; lints and budgets), `DATABASE_URL` config, per-environment branching, switching between Postgres and Mongo façades. Use for db.ts, postgres(), mongo(), middleware, telemetry, lints, budgets, DATABASE_URL, .env, connection pool, poolOptions, dev vs prod config, transactions, db.transaction, read replicas, multi-database, script won't exit, hangs, close connection, db.end, db.close, pool.end, [Symbol.asyncDispose], await using.
npx skill4agent add prisma/prisma-next prisma-next-runtimedb.tsEdit your data contract. Prisma handles the rest.
db.tsdb.tsdb.transaction(...)tsx my-script.tsdb.close()await usingprisma-next-queriesprisma-next-contractprisma-next-buildprisma-next-debugprisma-next-feedbackdb.ts@prisma-next/<target>@prisma-next/postgres/runtime@prisma-next/mongo/runtimecontract.jsonContractcontract.d.tsdbdb.tsimport postgres from '@prisma-next/postgres/runtime'postgres<Contract>(options)Contractcontract.d.tsdb.sqldb.ormawait db.connect({ url })db.tsmiddleware: [...]prisma-next.config.ts.envdefineConfig({ contract, db, extensions, migrations }).envDATABASE_URL.envdotenv/configDATABASE_URLvite devprisma-next-buildcontract.jsoncontract.d.tsdb.tsdb.tsContractinit--target postgres// src/prisma/db.ts
import postgres from '@prisma-next/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'],
});initprisma/db.tsprisma-next-quickstartsrc/prisma/db.tssrc/./prisma/db../prisma/db<Contract>Contract./contract.d.tswith { type: 'json' }urlDATABASE_URLdb.tsawait db.connect({ url })import mongo from '@prisma-next/mongo/runtime'dbpg.Poolawait db.close()await usingdbdb.ts// src/scripts/hello.ts
import { db } from '../prisma/db';
const created = await db.orm.User.create({ email: 'alice@example.com', name: 'Alice' });
const read = await db.orm.User.first();
console.log({ created, read });
await db.close();[Symbol.asyncDispose]close()// src/scripts/hello.ts — top-level await in a script module
import postgres from '@prisma-next/postgres/runtime';
import type { Contract } from '../prisma/contract.d';
import contractJson from '../prisma/contract.json' with { type: 'json' };
await using db = postgres<Contract>({ contractJson, url: process.env.DATABASE_URL! });
const user = await db.orm.User.first();
console.log(user);
// db.close() runs automatically when the script module exits.await usingawait using db = postgres(...)pg.Pool// DO NOT do this — closes the pool after every request.
app.get('/users', async (req, res) => {
await using db = postgres<Contract>({ contractJson, url: process.env.DATABASE_URL! });
const users = await db.orm.User.all();
res.json(users);
});db.ts// src/prisma/db.ts — constructed once, lives for the process
export const db = postgres<Contract>({ contractJson, url: process.env.DATABASE_URL });
// src/routes/users.ts
import { db } from '../prisma/db';
app.get('/users', async (req, res) => {
const users = await db.orm.User.all();
res.json(users);
});db.close()db.close()await usingtsx my-script.tsclose()close()dbdb.runtime()db.connect(...)db.transaction(...)db.prepare(...)Error('<target> client is closed')'Postgres client is closed''SQLite client is closed''Mongo client is closed'close()awaitclose()db.runtime().execute(plan)PreparedStatementclose()close()pg.Pool{ url }MongoClient{ url }{ uri, dbName }{ path }pg.Poolpg.Clientpg:mongodb.MongoClientmongoClient:bindingdb.close()db.end()node-postgrespool.end()pg.Poolpg.Poolawait db.close()import postgres from '@prisma-next/postgres/runtime';
import { createTelemetryMiddleware } from '@prisma-next/middleware-telemetry';
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'],
middleware: [
createTelemetryMiddleware({
onEvent: (event) => {
// forward to your collector, log, etc.
},
}),
],
});createTelemetryMiddleware@prisma-next/middleware-telemetry/middlewarepnpm ls @prisma-next/middleware-telemetryDELETEWHERESELECTLIMIT@prisma-next/sql-runtimeexamples/prisma-next-demo/src/prisma/db.tsimport postgres from '@prisma-next/postgres/runtime';
import { budgets, lints } from '@prisma-next/sql-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'],
middleware: [
lints({
severities: {
selectStar: 'warn',
noLimit: 'error',
deleteWithoutWhere: 'error',
updateWithoutWhere: 'error',
readOnlyMutation: 'error',
unindexedPredicate: 'warn',
},
}),
budgets({
maxRows: 10_000,
defaultTableRows: 10_000,
tableRows: { user: 10_000, post: 50_000 },
maxLatencyMs: 1_000,
severities: { rowCount: 'error', latency: 'warn' },
}),
],
});packages/2-sql/5-runtime/src/middleware/lints.ts.../budgets.tsseveritiesselectStarnoLimitdeleteWithoutWhereupdateWithoutWherereadOnlyMutationunindexedPredicaterowCountlatencymiddleware: [
createTelemetryMiddleware({ onEvent }), // outermost — sees all sub-failures as inner errors
lints({ severities: { noLimit: 'error' } }),
budgets({ maxLatencyMs: 5_000 }), // innermost — runs closest to the driver
],urlpgpg.Poolpg.ClientbindingpgurlpoolOptions.connectionTimeoutMillispoolOptions.idleTimeoutMillisdriverOptions// Default — URL string, factory constructs the pool.
postgres<Contract>({
contractJson,
url: process.env['DATABASE_URL'],
poolOptions: {
connectionTimeoutMillis: 20_000,
idleTimeoutMillis: 30_000,
},
});
// BYO pool — pass a pg.Pool you already created.
import { Pool } from 'pg';
const pool = new Pool({ connectionString: process.env['DATABASE_URL'] });
postgres<Contract>({ contractJson, pg: pool });urlpgDATABASE_URL.envprocess.envdb.tsDATABASE_URLdb.tsdb.tsprocess.env['NODE_ENV']const isProd = process.env['NODE_ENV'] === 'production';
export const db = postgres<Contract>({
contractJson,
url: process.env['DATABASE_URL'],
middleware: isProd
? [createTelemetryMiddleware({ onEvent })]
: [
createTelemetryMiddleware({ onEvent }),
lints({ severities: { noLimit: 'error', deleteWithoutWhere: 'error' } }),
],
});.env.envdb.transaction(fn)txsqlormdbtx.sqltx.ormdb.sqldb.ormawait db.transaction(async (tx) => {
const user = await tx.orm.User.create({ email: 'alice@example.com' });
await tx.orm.Post.create({ userId: user.id, title: 'hello' });
// If either call throws, both inserts roll back.
});txexecute(plan)db.ts@prisma-next/postgres@prisma-next/mongoprisma-next.config.tsdefineConfigprisma-next init--forceprisma-next.config.tsdb.ts// src/prisma/db.ts (Mongo)
import mongo from '@prisma-next/mongo/runtime';
import type { Contract } from './contract.d';
import contractJson from './contract.json' with { type: 'json' };
export const db = mongo<Contract>({ contractJson, url: process.env['DATABASE_URL'] });db.sqldb.ormJOINprisma-next contract emitprisma-next-build@prisma-next/vite-plugin-contract-emitprismaVitePlugin('prisma-next.config.ts')vite.config.tsprebuildprisma-next contract emitprisma-next-builddb.tscontract.jsoncontract.d.tsDATABASE_URLprisma-next.config.ts.env<Contract>postgres<Contract>(...)postgres<Contract, TypeMaps>with { type: 'json' }@prisma-next/postgres/middleware@prisma-next/middleware-telemetry@prisma-next/sql-runtimeseveritiesrequireWheremaxRowsWithoutLimitmaxLatencyMsmaxDurationMsmaxRowsdefaultTableRowstableRowspg.Poolawait db.close()await using db = postgres<Contract>(...)await using db = postgres(...)db.ts@prisma-next/postgres/middleware./runtime./config./contract-builder./control./family./target./serverlesslintsbudgets@prisma-next/sql-runtimecreateTelemetryMiddleware@prisma-next/middleware-telemetryTML-2526prisma-next-feedbackdb.tsprisma-next-feedbackpoolOptions.connectionTimeoutMillispoolOptions.idleTimeoutMillispg.PoolallowExitOnIdlepg.Poolpg:prisma-next-feedbackcreateTelemetryMiddlewareonEventprisma-next-feedbackprisma-next init --helpdefineConfigpackages/3-extensions/postgres/src/config/define-config.tspostgres()packages/3-extensions/postgres/src/runtime/postgres.tspackages/2-sql/5-runtime/src/middleware/{lints,budgets}.tsdb.ts@prisma-next/<target>/runtimeContract./contract.dwith { type: 'json' }<Contract>postgres<Contract>(...)DATABASE_URL.envprisma-next.config.tslintsbudgetsseveritiesmaxLatencyMsmaxRowstableRowsNODE_ENV@prisma-next/postgres/middleware@prisma-next/postgres-extension-auditpostgres<...>prisma-next-feedbackprisma-next-build