npx skills add ...
npx skills add prisma/prisma-next --skill prisma-next-quickstart
npx skills add prisma/prisma-next --skill prisma-next-quickstart
Adopt Prisma Next into a new project, onto an existing database, or as the first move after a bootstrap tool dropped you into a scaffold. Use for "what can I do with Prisma Next", "what can I do next with Prisma", "where do I start", "what should I do first", "just ran createprisma", "createprisma", "npx createprisma", "npx create-prisma", "first steps", "first query", "I have a scaffolded Prisma Next project what now"; for `pnpm dlx prisma-next init` greenfield setup; and for `prisma-next contract infer` + `db sign` against an existing database. Also covers the connect-write-read first-arc orientation, the day-to-day commands (`contract emit`, `db init`, `db update`, `migration plan`, `migrate`, `db schema`, `db verify`), and routing to `prisma-next-contract` / `prisma-next-queries` / `prisma-next-runtime` for the next move. Flags: --target, --authoring, --schema-path, --probe-db, --output.
Edit your data contract. Prisma handles the rest.
This skill takes the user from zero (or near-zero) to a first working query against Prisma Next. Three paths — and they all converge on the same first arc: connect → write → read. Schema editing comes after the first arc, not before.
npx createprisma dropped them in, they cloned a teammate's repo, or they ran prisma-next init themselves and now want to make their first move) and they're asking "what can I do with Prisma Next?", "where do I start?", or "what's next?". The goal is to anchor them on the contract, get them connected to a database, round-trip one row, and let further commands surface organically.prisma-next init themselves. init seeds a starter contract with a sample model, so the path joins the first-touch orientation arc as soon as the database is initialised.contract infer, sign the marker with db sign, then write queries against one of the existing tables.This skill does not cover migrating from another ORM (Drizzle, Prisma 6/7, Sequelize, TypeORM, Kysely, Knex, raw drivers). Those are separately-installable skills.
createprisma (or equivalent scaffold tool) and is asking what to do next. First-touch orientation path.prisma-next-contract.@prisma-next/migrate-from-<orm>-skill (separate).db.ts in a project that already has a contract → prisma-next-runtime.prisma-next-build.contract.prisma (PSL, the canonical surface) or contract.ts (TypeScript builder). The framework reads it and emits two artefacts: contract.json (runtime IR) and contract.d.ts (types).postgres or mongodb. Picked at init time; baked into the @prisma-next/<target> façade the scaffold imports from.psl (Prisma Schema Language, default) or typescript (programmatic builder, optionally paired with the Vite plugin for auto-emit during vite dev — see prisma-next-build).@prisma-next/postgres (or @prisma-next/mongo). User code imports from façade subpaths (@prisma-next/postgres/config, @prisma-next/postgres/runtime, @prisma-next/postgres/contract-builder). The façade bakes in the family / target / adapter / driver wiring; never reach past it. See prisma-next-contract for the full list.db.ts: the runtime entry point. Lives next to the contract source at src/prisma/db.ts. Imports the contract artefacts and exports a db value the rest of the app uses.pn_meta_marker row in your database that records the contract hash. Lets PN detect drift between contract and live DB. Created by db init (greenfield / first-touch orientation) or db sign (brownfield).Every application that consumes Prisma Next uses the same shape:
Three things to internalise:
src/prisma/ is the home for the contract — source + emitted artefacts + db.ts all colocated. The rest of src/ imports from ./prisma/db (or ../prisma/db, depending on file depth).migrations/app/ — the app/ segment is the consuming application's space-id. Extensions you depend on get sibling directories under migrations/ (one per extension contract-space), but you don't write into those — only the app/ subtree is your migrations.prisma-next.config.ts lives at the repo root, not under src/. Every command resolves paths relative to the config's directory.Contributors building extension packages or aggregate-root monorepo packages use a different layout — src/contract.{prisma,ts} (no prisma/ subdir) + migrations/<timestamp>_<slug>/ (no app/ segment). That distinction is intentional; see prisma-next-contract for which path applies to you.
Heads up —
prisma-next initcurrently scaffolds the wrong layout. It writesprisma/contract.{prisma,ts}andprisma/db.tsat the repo root instead of undersrc/prisma/. Tracked as TML-2532. Until the fix lands, either pass--schema-path src/prisma/contract.prismatoinit, or move the scaffoldedprisma/directory intosrc/prisma/afterinitand update thecontractpath inprisma-next.config.tsto match. The canonical layout above is what the demo example uses and what the rest of the framework expects.
All three paths in this skill converge here. Once the project is scaffolded and the database is reachable, the first move is always the same: connect, write a row, read it back, against whatever model the contract already declares. Don't touch the contract source on this first move — extend it later, after the round-trip works.
Write the snippet in a fresh file directly under src/ (e.g. src/first-arc.ts) so the relative import resolves to one level deep:
If that prints [{ id: 1, email: 'alice@example.com' }], the project is wired end-to-end and the user has crossed from "I have a project" to "I'm building."
db.orm.<Model> is the default ORM lane — model-shaped, fully typed against the contract, lazily connects to the database on first use (it picks up DATABASE_URL from .env via the runtime's dotenv/config-loaded environment). The deeper prisma-next-queries skill covers the rest of the surface (filters, joins, transactions, the SQL builder, raw SQL, TypedSQL) when the user is ready.
Mongo target: the snippet above is SQL-target shape. On
@prisma-next/mongo,db.ormis keyed by the collection's storage name (@@map(...), or the lowercased model name if no@@map), so the same arc readsawait db.orm.users.create(...)/await db.orm.users.select('id', 'email').all()— notdb.orm.User. Full rule and rewrite recipe inprisma-next-queries§ MongoDB ORM addressing.
Prerequisites for the arc to work. All three paths leave these in place by the time you reach the arc:
prisma-next.config.ts exists at the repo root and declares the target + contract source (typically src/prisma/contract.prisma or src/prisma/contract.ts).src/prisma/contract.{prisma,ts} (a starter model from init, or the inferred contract from contract infer, or whatever the bootstrap tool generated).src/prisma/db.ts exists and instantiates the runtime with the emitted contract.DATABASE_URL is set in .env (or wherever the runtime's config tells it to look).db init) or marker-signed (db sign), so the marker row exists and the schema matches the contract.The three workflows below each describe how their path gets the user to that state. After that, the arc above is the same.
Triggers: "what can I do with Prisma Next?", "what can I do next with Prisma?", "where do I start?", "I just ran createprisma", "what's next?", or any close variant — paired with a PN project already on disk (scaffolded by createprisma, by prisma-next init, by a teammate, however).
The user's high-level intent is "I want to be running an application against my database, against this thing called Prisma Next." The job of this workflow is to anchor them on the contract, get one round-trip working, and let further commands surface organically as their next move requires them. It is orientation, not a tour, not a feature inventory, not a syllabus.
Prisma Next is contract-first. Everything the framework does — query types, migrations, runtime types, drift detection — flows from a single source of truth: the contract. The contract describes the user's application's data model. The framework reads it; the framework derives the rest. Lead with this.
The first response to "what can I do with Prisma Next?" names the contract path, frames its role in one sentence, and then steers toward getting the user's application running. Don't open with a feature inventory. Don't open with a list of commands. Open with: "Your contract is at <path>. It describes your application — your query types, migrations, and runtime types all flow from it. Let's get you connected to a database so your app can actually run against it."
The first arc — once oriented — is connect → write → read. Not edit-the-contract-first, not plan-a-migration-first. The user's win is I have application code running against my database.
Before saying anything specific to the user, read:
prisma-next.config.ts at the repo root — what target (postgres / mongodb) is wired, what contract: path it declares, what extensions are installed.src/prisma/contract.prisma or src/prisma/contract.ts; a project that pre-dates TML-2532 may have it at prisma/contract.{prisma,ts} instead — check the contract field of the config) — what starter models, if any, exist.src/prisma/db.ts (next to the contract) — the runtime entry point..env / .env.example — is DATABASE_URL set, or only the example?pnpm prisma-next db verify — does the live DB match the contract?Then say the contract path back to the user, with its role attached. Something like: "Your contract is at src/prisma/contract.prisma, and it currently declares a User model. The contract describes your app — every query type, migration, and runtime type the framework gives you flows from this file. Let's get your app connected to a database next." The exact wording is up to the agent; what matters is that the user leaves the first response knowing where the contract is and that it is the source of truth.
The motivation is "so your app can actually run against your database", not "so the prerequisite checklist passes". The mechanics depend on what's already in place from Step 1:
DATABASE_URL not set. Have the user set it in .env (not in prisma-next.config.ts — see Pitfall 5). Then pnpm prisma-next db init to apply the current contract to that database and write the marker row. Now the app can connect.db verify reports drift). Run pnpm prisma-next db init. (db update is the alternative for quick dev cycles — it's looser, doesn't write a migration history, and is what users reach for when they want to iterate on the schema fast. Mention it if the user asks how to make schema changes flow to the DB; don't pre-explain it.)User { id, email }), pnpm prisma-next contract emit, then pnpm prisma-next db init. Minimal — get the round-trip working, then extend.The user encounters db init (and optionally db update, contract emit) here because they're the commands their current move requires. They learn what those commands are by using them.
Run the snippet from Your first arc — connect, write, read above against whatever model the contract declares. When it prints the row back, the user has crossed from "I have a project" to "my app runs against my database". That's the win.
Now ask the user what they want to build. Route to the skill that owns that move:
prisma-next-queries.prisma-next-contract. They'll touch contract emit and db update (or migration plan + migrate) as part of that workflow.prisma-next-runtime.prisma-next-build.prisma-next.config.ts keys. The scaffold's defaults are correct; revisit when the user needs to change something.<path>, it's the source of truth" — anchors the user; without it, the rest of the workflow lands as disconnected ceremony.The concept: prisma-next init is one CLI command that scaffolds config, schema, runtime, dependencies, and the contract emit step. It operates on the current working directory — there is no positional project-name argument. Make the directory, cd in, then run init.
Telemetry is opt-out. The CLI collects anonymous usage data by default. Every command — including
init— prints a one-time notice to stderr on first use, then sends; there is no interactive consent prompt. Opt out anytime by runningprisma-next telemetry disable, withDO_NOT_TRACK=1orPRISMA_NEXT_DISABLE_TELEMETRY=1, or by setting"enableTelemetry": falsein your user config (prisma-nextconfig dir, notprisma-next.config.ts). Runprisma-next telemetry statusto see what's currently in effect. This is relevant for agent-driven runs — the CLI records that an agent invoked it. What's collected, the per-user config path, and how to fully reset are documented indocs/Telemetry.md.
The flags init accepts (run prisma-next init --help for the source of truth):
--target <db> — postgres or mongodb.--authoring <style> — psl or typescript.--schema-path <path> — defaults to prisma/contract.prisma (or prisma/contract.ts). Pass --schema-path src/prisma/contract.prisma (or .../contract.ts) to scaffold into the canonical src/prisma/ location directly — init's default is wrong today, see TML-2532.--force — overwrite an existing scaffold without prompting (re-running init in a scaffolded directory triggers the reinit flow — --force skips the confirmation).--write-env — also write .env (default writes only .env.example; .env stays under your control).--probe-db — connect to DATABASE_URL once and check the server version against the target's minimum.--strict-probe — fail init if the probe fails (no-op without --probe-db).--no-install — skip dependency install + initial contract emit.--no-skill — skip Prisma Next skills installation (air-gapped / restricted environments). The skill cluster is always installed at the project level — never globally — so its version stays locked to the project's Prisma Next version.init writes (when it runs cleanly):
prisma-next.config.ts at the project root.--schema-path — src/prisma/contract.prisma if you passed the canonical override, prisma/contract.prisma if you accepted the (currently-wrong) default.db.ts in the same directory as the contract source.prisma-next.md — a human quick-reference..env.example (and .env if --write-env).package.json (deps + scripts) and tsconfig.json (required compiler options).prisma-next contract emit once.If you took init's default and ended up with a top-level prisma/ directory (TML-2532), the cleanup is one move + one config edit:
Do this before running db init — once the marker row is written, restructuring is harder.
After init succeeds, the path converges on Your first arc — connect, write, read above. init has already seeded a starter contract with User and Post models (with a relation between them) and run contract emit once; the only remaining prerequisites are setting DATABASE_URL and initialising the database. Two commands:
DATABASE_URL in .env (copy from .env.example).pnpm prisma-next db init. Creates tables, indexes, constraints, and writes the marker row — using the starter contract init generated.Then run the snippet from Your first arc above against the User model. When the user is ready to extend the contract — add more models, change fields, add relations — chain to prisma-next-contract. For more queries, chain to prisma-next-queries.
Why this is queries-first, not schema-editing-first. init ships with User and Post on purpose: the user shouldn't have to design a schema to prove their setup works. Extending the contract is the next move after the first arc lands, not part of getting there. If the user asks you to skip straight to "add a Comment model" — sure, do that — but get one query green against User or Post first if there's any doubt the project is wired correctly.
The concept: against an existing database with no PN contract, contract infer walks the live schema (tables, columns, indexes, constraints) and writes a PSL contract that describes it. The result is a starting point, not the final contract — review and clean it up, then db sign to record the current contract hash as the marker (instead of letting db init try to recreate the schema from scratch).
Then, with DATABASE_URL set in .env:
(Note: the flag is --output, not --out. Run prisma-next contract infer --help for the full surface.)
The agent should pause here and read the inferred PSL. Symptoms a re-author pass is needed:
String where you want an extension type like pgvector.Vector(length: 1536)).@unique / @index hints PN couldn't see.Then re-emit and sign:
Then run the snippet from Your first arc — connect, write, read above, using one of your existing tables in place of the starter model. The arc is the same; only the path that got you there differs.
A reference table — not a script to recite at the user. Commands surface in the workflow above as the user's next move requires them; this table is here for the moment the user asks for a wider view (typically after the first round-trip), and as a one-glance summary anyone newly oriented to Prisma Next can scan. For flag-level detail, run <command> --help; the help output is the source of truth.
| What you want to do | Command | Deeper skill |
|---|---|---|
| Apply the current contract to the DB the first time | prisma-next db init | this skill |
Re-emit contract.json + contract.d.ts after editing the contract source | prisma-next contract emit | prisma-next-contract |
| Quick dev-only schema sync (no migration history kept) | prisma-next db update | prisma-next-migrations |
| Plan a migration from a contract diff | prisma-next migration plan --name <slug> | prisma-next-migrations |
| Apply pending migrations | prisma-next migrate | prisma-next-migrations |
| Inspect the live database | prisma-next db schema | prisma-next-debug |
| Confirm the DB matches the contract (drift check) | prisma-next db verify | prisma-next-debug |
| Bring an existing DB into a PN contract | prisma-next contract infer --db "$DATABASE_URL" | this skill (brownfield) |
| Decode a structured error envelope | (read the code / why / fix fields) | prisma-next-debug |
| Report a bug or request a feature | (file via the feedback skill) | prisma-next-feedback |
contract.prisma) — the default. Concise, declarative, familiar to anyone who has used Prisma. Recommended for most projects.contract.ts) — a programmatic builder. Use when the contract is genuinely computed (multi-tenant per-tenant variants), when you reuse contract fragments across files, or when an extension requires constructs PSL doesn't yet express (e.g. pgvector's parameterised storage-type registration). Pairs with the Vite plugin from prisma-next-build for auto-emit on save.Switch authoring later by re-running prisma-next init in the same directory. The init flow detects the existing scaffold and prompts to reinit (use --force to skip the prompt in non-interactive runs). Existing contract content is not automatically translated — you'll re-author by hand in the target language.
prisma-next init <project-name> with a positional argument. init operates on the current working directory; there is no positional project-name argument. mkdir foo && cd foo && pnpm dlx prisma-next init.init doesn't connect to your database. It only scaffolds files and installs dependencies (and runs the initial contract emit). You connect with db init / db update / migrate. If init succeeds and queries fail, the issue is DATABASE_URL, not init.contract infer produces a starting point. Don't db sign against a contract you haven't read.contract.json, contract.d.ts) are stale until you run contract emit. If the type-checker says a model "doesn't exist", you skipped emit.DATABASE_URL in prisma-next.config.ts instead of .env. The config reads .env automatically via dotenv/config. Hardcoding the URL leaks credentials and bypasses per-environment overrides. See prisma-next-runtime.contract.json or contract.d.ts. They're emitted artefacts; the next contract emit overwrites your changes. Edit the source instead.--out for contract infer. The flag is --output.@prisma-next/migrate-from-<orm>-skill if one exists for your source, or treat the source as a brownfield database and contract infer from it. If you need a guided migration flow built-in, file a feature request via the prisma-next-feedback skill.prisma db push-style production sync. db update is the quick development path; for production, use migrations (migration plan + migrate). PN deliberately does not offer a "push-to-prod-without-a-migration" surface — see prisma-next-migrations.prisma-next db schema for a CLI tree-style summary of the live DB. If you need an interactive UI, file a feature request via the prisma-next-feedback skill.This skill is intentionally body-only; prisma-next init --help, contract infer --help, and db sign --help are the authoritative surfaces for flag-level detail. When in doubt, run --help and read the actual command's description rather than guessing from this skill.
db.ts, DATABASE_URL, marker row) before writing application code.create + one select against the starter (or inferred) model — and got the round-trip working green.postgres / mongodb) and authoring mode (psl / typescript).prisma-next.config.ts, the contract source, db.ts, and .env before proposing anything — didn't assume what the scaffold tool / teammate left in place.prisma-next init from the project directory — no positional project-name argument.src/prisma/contract.{prisma,ts} + src/prisma/db.ts + migrations/app/ layout — including moving the scaffolded directory out of a top-level prisma/ if init produced one (TML-2532).contract infer --db "$DATABASE_URL" --output src/prisma/contract.prisma, reviewed the result, then contract emit + db sign.DATABASE_URL in .env and confirmed the value is reachable.db init greenfield / first-touch orientation) or signed the marker (db sign brownfield).contract.json or contract.d.ts.DATABASE_URL in prisma-next.config.ts.prisma-next-queries for more queries, then prisma-next-contract when they're ready to extend the schema).// src/first-arc.ts
import 'dotenv/config';
import { db } from './prisma/db';
// Write a row against the starter model. Adapt the field names to whatever
// model your contract source actually declares — read it first.
await db.orm.User.create({ email: 'alice@example.com' });
// Read it back.
const users = await db.orm.User.select('id', 'email').all();
console.log(users);mkdir my-app && cd my-app
pnpm init # if no package.json yet
pnpm dlx prisma-next init # interactive
# or non-interactive (CI / agent runs):
pnpm dlx prisma-next init --yes --target postgres --authoring pslmkdir -p src && mv prisma src/prisma
# Then update prisma-next.config.ts so `contract` reads
# 'src/prisma/contract.prisma' (or .ts) instead of 'prisma/contract.prisma'.
pnpm prisma-next contract emit # re-emits contract.json + contract.d.ts under src/prisma/mkdir my-app && cd my-app
pnpm init
pnpm dlx prisma-next init --yes --target postgres --authoring psl
# scaffold lands; you'll overwrite the starter schema belowpnpm prisma-next contract infer --db "$DATABASE_URL" --output src/prisma/contract.prismapnpm prisma-next contract emit
pnpm prisma-next db sign
pnpm prisma-next db verify # confirms the DB matches the contract; reports drift if not