diff --git a/apps/docs/content/docs/(index)/next/add-to-existing-project/mongodb.mdx b/apps/docs/content/docs/(index)/next/add-to-existing-project/mongodb.mdx index 15dd0684c0..0816552399 100644 --- a/apps/docs/content/docs/(index)/next/add-to-existing-project/mongodb.mdx +++ b/apps/docs/content/docs/(index)/next/add-to-existing-project/mongodb.mdx @@ -6,7 +6,9 @@ metaTitle: Add Prisma Next to an existing MongoDB project metaDescription: Add Prisma Next to an existing MongoDB project. --- -This guide shows how to add Prisma Next to a project that already uses MongoDB. You will initialize Prisma Next, describe the collections you want to work with, emit the generated artifacts, and run a couple of queries. +This guide shows how to add Prisma Next to a project that already uses MongoDB. You will run `prisma-next init`, describe the collections you want to work with, emit the generated artifacts, 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 MongoDB deployment and runs on Node.js 24 or newer. If you want Prisma Next to create a new app for you, use the [MongoDB quickstart](/next/quickstart/mongodb). :::warning[Prisma Next is still in development] @@ -14,14 +16,6 @@ Prisma Next is not ready for production yet. Prisma ORM 7 is still the recommend ::: -## Prerequisites - -Before you start, make sure you can already reach the MongoDB deployment this project uses today. - -- Node.js 24 or newer -- npm -- An existing MongoDB 6.0 or newer deployment - For local development, use a replica set. MongoDB Atlas already gives you that. ## 1. Make sure you can run the example script @@ -41,12 +35,15 @@ Later, `prisma-next init` will also add the Node.js types it needs and make sure From the root of your existing project, run: ```npm -npx prisma-next init --write-env +npx prisma-next init --target mongodb ``` -When Prisma Next asks a few setup questions: +This is the existing-project path. It preselects MongoDB, 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 `MongoDB` - choose `PSL` - keep the default schema path, `prisma/contract.prisma` @@ -55,7 +52,7 @@ When Prisma Next asks a few setup questions: Update `.env` with the connection string for the MongoDB deployment your app already uses: ```text title=".env" -DATABASE_URL="mongodb://127.0.0.1:27017/my-app?replicaSet=rs0" +DATABASE_URL="mongodb://127.0.0.1:27017/app?replicaSet=rs0" ``` ## 4. Describe the collections you want Prisma Next to know about @@ -166,21 +163,12 @@ Run it again: npx tsx script.ts ``` -## 8. Commands you will use next +## 8. Next steps -Once Prisma Next is in the project, these are the MongoDB commands to remember: +When you change `prisma/contract.prisma`, emit the contract again: ```npm npx prisma-next contract emit ``` -Run this after you change `prisma/contract.prisma`. - -```npm -npx prisma-next migration plan --name add-user-bio -npx prisma-next migration apply -``` - -Use these when you want Prisma Next to manage a schema change for the collections in your contract. - -You do not need to create a migration just to start reading collections that already exist. Create a migration when you are ready for Prisma Next to own a change. +You do not need a migration just to read collections that already exist. Use [migration plan](/cli/next/migration-plan) when you want Prisma Next to own a schema change. diff --git a/apps/docs/content/docs/(index)/next/add-to-existing-project/postgresql.mdx b/apps/docs/content/docs/(index)/next/add-to-existing-project/postgresql.mdx index 6db183be5e..6b1211264b 100644 --- a/apps/docs/content/docs/(index)/next/add-to-existing-project/postgresql.mdx +++ b/apps/docs/content/docs/(index)/next/add-to-existing-project/postgresql.mdx @@ -1,12 +1,14 @@ --- -title: Postgres +title: PostgreSQL description: Add Prisma Next to an existing PostgreSQL project. url: /next/add-to-existing-project/postgresql -metaTitle: Add Prisma Next to an existing Postgres project +metaTitle: Add Prisma Next to an existing PostgreSQL project metaDescription: 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 initialize Prisma Next, infer a contract from the live schema, sign the database, and run a couple of queries. +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](/next/quickstart/postgresql). :::warning[Prisma Next is still in development] @@ -14,14 +16,6 @@ Prisma Next is not ready for production yet. Prisma ORM 7 is still the recommend ::: -## Prerequisites - -Before you start, make sure you can already reach the PostgreSQL database this project uses today. - -- Node.js 24 or newer -- npm -- An existing PostgreSQL database - ## 1. Make sure you can run the example script If your project already runs TypeScript scripts, you can skip this step. @@ -39,12 +33,15 @@ Later, `prisma-next init` will also add the Node.js types it needs and make sure From the root of your existing project, run: ```npm -npx prisma-next init --write-env +npx prisma-next init --target postgres ``` -When Prisma Next asks a few setup questions: +This 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 `PostgreSQL` - choose `PSL` - keep the default schema path, `prisma/contract.prisma` @@ -166,25 +163,12 @@ Run it again: npx tsx script.ts ``` -## 9. Commands you will use next +## 9. Next steps -Once Prisma Next is in the project, these are the PostgreSQL commands to remember: +When you change `prisma/contract.prisma`, emit the contract again: ```npm npx prisma-next contract emit ``` -Run this after you change `prisma/contract.prisma`. - -```npm -npx prisma-next db update -``` - -Use this when you want Prisma Next to update the live database directly so it matches the latest contract. - -```npm -npx prisma-next migration plan --name add-user-bio -npx prisma-next migration apply -``` - -Use these when you want checked-in migration packages instead of a direct database update. +Use [db update](/cli/next/db-update) for a direct development update, or [migration plan](/cli/next/migration-plan) when you want a checked-in migration. diff --git a/apps/docs/content/docs/(index)/next/create-prisma.mdx b/apps/docs/content/docs/(index)/next/create-prisma.mdx deleted file mode 100644 index 903e92d836..0000000000 --- a/apps/docs/content/docs/(index)/next/create-prisma.mdx +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: create-prisma@next -description: Scaffold a new Prisma Next app with create-prisma@next. -url: /next/create-prisma -metaTitle: Scaffold a Prisma Next app with create-prisma@next -metaDescription: Use create-prisma@next to create a new Prisma Next app with templates, database scripts, and runtime helpers. ---- - -`create-prisma@next` creates a new Prisma Next project from an app template. It installs the Prisma Next packages and adds the files and scripts needed to start developing. - -:::warning[Prisma Next is still in development] - -Prisma Next is not ready for production yet. Prisma ORM 7 is still the recommended choice for production applications today. - -::: - -Use this when you want to start from a working app template. If you already have an app, use [Add Prisma Next to an existing PostgreSQL project](/next/add-to-existing-project/postgresql) or [Add Prisma Next to an existing MongoDB project](/next/add-to-existing-project/mongodb). - -## Create a project - -Run: - -```npm -npx create-prisma@next -``` - -Then choose a project name, app template, database provider, contract authoring style, and package manager. - -Generated Node.js projects expect Node.js 24 LTS or newer. - -## Skip the prompts - -Pass flags when you already know the project shape: - -```npm -npx create-prisma@next --name my-app --template next --provider postgres -``` - -Use `--name .` to create the project in the current directory. - -Useful flags: - -| Flag | What it does | -| --- | --- | -| `--template ` | Chooses the app template. | -| `--provider postgres\|mongodb` | Chooses the database provider. | -| `--authoring psl\|typescript` | Chooses the contract authoring style. | -| `--package-manager ` | Chooses `npm`, `pnpm`, `yarn`, `bun`, or `deno`. | -| `--database-url ` | Writes `DATABASE_URL` during setup. | -| `--no-install` | Scaffolds files without installing dependencies. | -| `--no-emit` | Skips `prisma-next contract emit`. | -| `--force` | Allows scaffolding into a non-empty directory. | - -## What gets created - -The generated project includes Prisma Next dependencies, a contract file, Prisma Next configuration, environment files, and package scripts for local development. - -Supported templates include Hono, Elysia, NestJS, Next.js, SvelteKit, Astro, Nuxt, TanStack Start, and Turborepo. - -## Start the app - -Review `DATABASE_URL` in `.env`, then initialize the database. - -For PostgreSQL: - -```npm -npm run db:init -npm run dev -``` - -For MongoDB: - -```npm -npm run db:up -npm run migration:plan -- --name init -npm run migration:apply -npm run dev -``` - -To add Prisma Next to an app you already have, use the [PostgreSQL existing-project guide](/next/add-to-existing-project/postgresql) or [MongoDB existing-project guide](/next/add-to-existing-project/mongodb). diff --git a/apps/docs/content/docs/(index)/next/getting-started.mdx b/apps/docs/content/docs/(index)/next/getting-started.mdx new file mode 100644 index 0000000000..fba2d1f94a --- /dev/null +++ b/apps/docs/content/docs/(index)/next/getting-started.mdx @@ -0,0 +1,62 @@ +--- +title: Choose a setup path +description: Choose the fastest path to try Prisma Next in a new or existing project. +url: /next/getting-started +metaTitle: Prisma Next getting started +metaDescription: Choose a Prisma Next quickstart for a new project or add Prisma Next to an existing app. +badge: early-access +--- + +Start with a quickstart if you want Prisma Next to create the app. Use the existing-project path if you already have an app and database. + +## Start a new project + +```npm +npx create-prisma@next +``` + + + }> + Create the app, choose PostgreSQL, initialize the database, seed data, and run the first query. + + }> + Create the app, choose MongoDB, start or connect to MongoDB, seed data, and run the first query. + + + +## Use Prisma Postgres + +```npm +npx create-prisma@next +``` + + + }> + Create a Prisma Next app and let setup provision Prisma Postgres for the first run. + + }> + Start from the command line when you want the Prisma Postgres path without browsing Console first. + + + +## Add to an existing project + +```npm +npx prisma-next init +``` + + + }> + Add Prisma Next to an existing PostgreSQL app and infer a starter contract from the live schema. + + }> + Add Prisma Next to an existing MongoDB app and model the collections you want to query first. + + + +## After setup + +- Use the generated app scripts for the first run. +- Open `prisma-next.md` or the installed Prisma Next skills when you want agent-ready guidance inside the project. +- Change the starter contract when you are ready to model your own data. +- Open the [Prisma Next overview](/orm/next) when you want the concepts behind the setup. diff --git a/apps/docs/content/docs/(index)/next/index.mdx b/apps/docs/content/docs/(index)/next/index.mdx index 54e4e477d5..c947211459 100644 --- a/apps/docs/content/docs/(index)/next/index.mdx +++ b/apps/docs/content/docs/(index)/next/index.mdx @@ -1,13 +1,13 @@ --- -title: Get started with Prisma Next -description: Start a new Prisma Next app or add Prisma Next to an existing project. +title: Introduction to Prisma Next +description: Prisma Next is the next foundation for Prisma ORM. url: /next -metaTitle: Get started with Prisma Next -metaDescription: Start a Prisma Next project with create-prisma@next or add Prisma Next to an existing project. +metaTitle: Introduction to Prisma Next +metaDescription: Prisma Next is the next foundation for Prisma ORM. badge: early-access --- -Prisma Next is the next foundation for Prisma ORM. Start here if you want to try the Prisma Next workflow. +Prisma Next is the next foundation for Prisma ORM. It is an early access version of the ORM runtime, query APIs, migration flow, and project setup. :::warning[Prisma Next is still in development] @@ -15,15 +15,44 @@ Prisma Next is not ready for production yet. Prisma ORM 7 is still the recommend ::: -## Start a new project - -- [Scaffold a Prisma Next app with create-prisma@next](/next/create-prisma) - -## Add Prisma Next to an existing project - -- [Add Prisma Next to an existing PostgreSQL project](/next/add-to-existing-project/postgresql) -- [Add Prisma Next to an existing MongoDB project](/next/add-to-existing-project/mongodb) - -## Learn the ORM workflow - -Read the [Prisma Next overview](/orm/next) to learn about contracts, emitted artifacts, runtime clients, query styles, and database change commands. +Use Prisma Next when you want to try the new developer experience before it becomes the default Prisma ORM path. + +```npm +npx create-prisma@next +``` + +Start with the setup page when you want a guided first run. + + + }> + Pick a new-project quickstart or add Prisma Next to an existing app. + + + +## What you can try + + + }> + Create a Prisma Next app, initialize the database, seed data, and run the first query. + + }> + Create a Prisma Next app with a local MongoDB replica set or your own MongoDB deployment. + + }> + Add Prisma Next to an existing PostgreSQL app with `prisma-next init`. + + }> + Add Prisma Next to an existing MongoDB app and model the collections you want to query first. + + }> + Create a Prisma Next app backed by Prisma Postgres. + + + +## Learn the concepts + + + }> + Learn the core ideas behind contracts, emitted artifacts, runtime clients, query styles, and migrations. + + diff --git a/apps/docs/content/docs/(index)/next/meta.json b/apps/docs/content/docs/(index)/next/meta.json index 022d2ebb44..852e032cf4 100644 --- a/apps/docs/content/docs/(index)/next/meta.json +++ b/apps/docs/content/docs/(index)/next/meta.json @@ -1,11 +1,15 @@ { - "title": "Next", + "title": "Prisma Next", "defaultOpen": true, "root": true, "pages": [ "---Getting Started---", "index", - "create-prisma", - "add-to-existing-project" + "getting-started", + "---Prisma ORM---", + "quickstart", + "add-to-existing-project", + "---Prisma Postgres---", + "...prisma-postgres" ] } diff --git a/apps/docs/content/docs/(index)/next/prisma-postgres/from-the-cli.mdx b/apps/docs/content/docs/(index)/next/prisma-postgres/from-the-cli.mdx new file mode 100644 index 0000000000..3a2239a805 --- /dev/null +++ b/apps/docs/content/docs/(index)/next/prisma-postgres/from-the-cli.mdx @@ -0,0 +1,55 @@ +--- +title: From the CLI +description: Start a Prisma Next app with Prisma Postgres from the command line. +url: /next/prisma-postgres/from-the-cli +metaTitle: Prisma Next with Prisma Postgres from the CLI +metaDescription: Start a Prisma Next app with Prisma Postgres from the command line. +badge: early-access +--- + +Use the CLI when you want Prisma Next and Prisma Postgres set up without leaving the terminal. + +## Start a new app + +```npm +npx create-prisma@next +``` + +Choose PostgreSQL and Prisma Postgres when prompted. + +Setup provisions Prisma Postgres, writes `DATABASE_URL`, adds `prisma-next.md`, installs project-level Prisma Next skills for your coding agent, and writes the generated scripts used below. + +## Initialize the database + +From the generated project directory, run: + +```npm +npm run db:init +``` + +## Seed data + +```npm +npm run db:seed +``` + +## Run the app + +```npm +npm run dev +``` + +## Add Prisma Next to an existing app + +If the app already exists, run Prisma Next from the project root: + +```npm +npx prisma-next init +``` + +Choose PostgreSQL, set `DATABASE_URL` to your Prisma Postgres connection string, and let init add `prisma-next.md`, package scripts, and the Prisma Next skills for your coding agent. Then follow the [PostgreSQL existing-project guide](/next/add-to-existing-project/postgresql). + +## Import an existing database + +- Use [Import from PostgreSQL](/next/prisma-postgres/import-from-existing-database-postgresql) when your source database is PostgreSQL. +- Use [Import from MySQL](/next/prisma-postgres/import-from-existing-database-mysql) when your source database is MySQL. diff --git a/apps/docs/content/docs/(index)/next/prisma-postgres/import-from-existing-database-mysql.mdx b/apps/docs/content/docs/(index)/next/prisma-postgres/import-from-existing-database-mysql.mdx new file mode 100644 index 0000000000..f98417e5c6 --- /dev/null +++ b/apps/docs/content/docs/(index)/next/prisma-postgres/import-from-existing-database-mysql.mdx @@ -0,0 +1,71 @@ +--- +title: Import from MySQL +description: Import an existing MySQL database into Prisma Postgres, then use it with Prisma Next. +url: /next/prisma-postgres/import-from-existing-database-mysql +metaTitle: Import from MySQL into Prisma Postgres for Prisma Next +metaDescription: Import MySQL data into Prisma Postgres, then connect Prisma Next to the imported database. +badge: early-access +--- + +Move an existing MySQL database into Prisma Postgres, then connect Prisma Next to it. + +## Prerequisites + +You need: + +- the connection URL for the MySQL database you are importing from +- a Prisma Data Platform account +- `pgloader` +- Node.js 24 or newer + +## 1. Create a Prisma Postgres database + +Create a Prisma Postgres database from Console or with the CLI. Copy the direct connection string; you will use it for the import and for `DATABASE_URL`. + +## 2. Create a pgloader config + +Create `config.load`: + +```text title="config.load" +LOAD DATABASE + FROM mysql://USER:PASSWORD@HOST:PORT/DATABASE + INTO postgres://USER:PASSWORD@db.prisma.io:5432/?sslmode=require + +WITH quote identifiers, + include drop, + create tables, + create indexes, + reset sequences + +ALTER SCHEMA 'DATABASE' RENAME TO 'public'; +``` + +## 3. Import into Prisma Postgres + +Run pgloader: + +```shell +pgloader config.load +``` + +## 4. Add Prisma Next + +From your app root, initialize Prisma Next: + +```npm +npx prisma-next init +``` + +Choose PostgreSQL, set `DATABASE_URL` to the Prisma Postgres connection string, then infer and emit the contract: + +```npm +npx prisma-next contract infer --output ./prisma/contract.prisma +npx prisma-next contract emit +npx prisma-next db sign +``` + +## Next steps + +- Review table and column names in the inferred contract. +- Use the [PostgreSQL existing-project guide](/next/add-to-existing-project/postgresql) for the first Prisma Next query. +- Use the [full Prisma Postgres MySQL import guide](/prisma-postgres/import-from-existing-database-mysql) for deeper migration details. diff --git a/apps/docs/content/docs/(index)/next/prisma-postgres/import-from-existing-database-postgresql.mdx b/apps/docs/content/docs/(index)/next/prisma-postgres/import-from-existing-database-postgresql.mdx new file mode 100644 index 0000000000..dea8eb60fa --- /dev/null +++ b/apps/docs/content/docs/(index)/next/prisma-postgres/import-from-existing-database-postgresql.mdx @@ -0,0 +1,61 @@ +--- +title: Import from PostgreSQL +description: Import an existing PostgreSQL database into Prisma Postgres, then use it with Prisma Next. +url: /next/prisma-postgres/import-from-existing-database-postgresql +metaTitle: Import from PostgreSQL into Prisma Postgres for Prisma Next +metaDescription: Import PostgreSQL data into Prisma Postgres, then connect Prisma Next to the imported database. +badge: early-access +--- + +Move an existing PostgreSQL database into Prisma Postgres, then connect Prisma Next to it. + +## Prerequisites + +You need: + +- the connection URL for the PostgreSQL database you are importing from +- a Prisma Data Platform account +- PostgreSQL 17 CLI tools, including `pg_dump` and `pg_restore` +- Node.js 24 or newer + +## 1. Create a Prisma Postgres database + +Create a Prisma Postgres database from Console or with the CLI. Copy the direct connection string; you will use it for the restore and for `DATABASE_URL`. + +## 2. Export from PostgreSQL + +Run `pg_dump` against the source database: + +```shell +pg_dump -Fc -v -d "postgresql://USER:PASSWORD@HOST:PORT/DATABASE" -n public -f db_dump.bak +``` + +## 3. Restore into Prisma Postgres + +Restore the dump with the direct Prisma Postgres connection string: + +```shell +pg_restore -d "postgres://USER:PASSWORD@db.prisma.io:5432/postgres?sslmode=require" -v ./db_dump.bak +``` + +## 4. Add Prisma Next + +From your app root, initialize Prisma Next: + +```npm +npx prisma-next init +``` + +Choose PostgreSQL, set `DATABASE_URL` to the Prisma Postgres connection string, then infer and emit the contract: + +```npm +npx prisma-next contract infer --output ./prisma/contract.prisma +npx prisma-next contract emit +npx prisma-next db sign +``` + +## Next steps + +- Review the inferred contract before you rely on it in application code. +- Use the [PostgreSQL existing-project guide](/next/add-to-existing-project/postgresql) for the first Prisma Next query. +- Use the [full Prisma Postgres import guide](/prisma-postgres/import-from-existing-database-postgresql) for deeper migration details. diff --git a/apps/docs/content/docs/(index)/next/prisma-postgres/meta.json b/apps/docs/content/docs/(index)/next/prisma-postgres/meta.json new file mode 100644 index 0000000000..5201852397 --- /dev/null +++ b/apps/docs/content/docs/(index)/next/prisma-postgres/meta.json @@ -0,0 +1,9 @@ +{ + "title": "Prisma Postgres", + "pages": [ + "quickstart", + "import-from-existing-database-postgresql", + "import-from-existing-database-mysql", + "from-the-cli" + ] +} diff --git a/apps/docs/content/docs/(index)/next/prisma-postgres/quickstart/meta.json b/apps/docs/content/docs/(index)/next/prisma-postgres/quickstart/meta.json new file mode 100644 index 0000000000..1ac4f6124b --- /dev/null +++ b/apps/docs/content/docs/(index)/next/prisma-postgres/quickstart/meta.json @@ -0,0 +1,4 @@ +{ + "title": "Quickstart", + "pages": ["prisma-next"] +} diff --git a/apps/docs/content/docs/(index)/next/prisma-postgres/quickstart/prisma-next.mdx b/apps/docs/content/docs/(index)/next/prisma-postgres/quickstart/prisma-next.mdx new file mode 100644 index 0000000000..885240bcbe --- /dev/null +++ b/apps/docs/content/docs/(index)/next/prisma-postgres/quickstart/prisma-next.mdx @@ -0,0 +1,56 @@ +--- +title: Prisma Next +description: Create a Prisma Next app with Prisma Postgres. +url: /next/prisma-postgres/quickstart/prisma-next +metaTitle: 'Quickstart: Prisma Next with Prisma Postgres' +metaDescription: Create a Prisma Next app, provision Prisma Postgres, seed data, and run your first query. +badge: early-access +--- + +Create a Prisma Next app backed by Prisma Postgres. + +## Quick start + +```npm +npx create-prisma@next +``` + +Run this from a Node.js 24 or newer environment. When prompted, choose PostgreSQL and Prisma Postgres. + +Setup provisions the database, writes `DATABASE_URL`, adds a starter contract, creates `prisma-next.md`, installs project-level Prisma Next skills for your coding agent, and adds package scripts for the database steps below. + +## 1. Create the app + +Run `create-prisma@next` and choose the minimal template if you want the fastest first run. Choose a framework template when you want the first query wired into an app route or page. + +## 2. Initialize the database + +From the generated project directory, run `db:init` to apply the starter schema to Prisma Postgres and sign the database. + +```npm +npm run db:init +``` + +## 3. Seed data + +`db:seed` inserts sample data so the first query returns something immediately. + +```npm +npm run db:seed +``` + +## 4. Run the app + +Start the app and confirm the sample query runs successfully. + +```npm +npm run dev +``` + +Use the URL or terminal output shown by your template to confirm the sample query runs successfully. + +## Next steps + +- Open the generated contract and change the starter model. +- Use [Import from PostgreSQL](/next/prisma-postgres/import-from-existing-database-postgresql) or [Import from MySQL](/next/prisma-postgres/import-from-existing-database-mysql) when you want to move an existing database to Prisma Postgres. +- Use the [PostgreSQL existing-project guide](/next/add-to-existing-project/postgresql) when your app already has a Prisma Postgres database. diff --git a/apps/docs/content/docs/(index)/next/quickstart/meta.json b/apps/docs/content/docs/(index)/next/quickstart/meta.json new file mode 100644 index 0000000000..3a7edc76ec --- /dev/null +++ b/apps/docs/content/docs/(index)/next/quickstart/meta.json @@ -0,0 +1,4 @@ +{ + "title": "Quickstart", + "pages": ["postgresql", "mongodb"] +} diff --git a/apps/docs/content/docs/(index)/next/quickstart/mongodb.mdx b/apps/docs/content/docs/(index)/next/quickstart/mongodb.mdx new file mode 100644 index 0000000000..3bac46d344 --- /dev/null +++ b/apps/docs/content/docs/(index)/next/quickstart/mongodb.mdx @@ -0,0 +1,87 @@ +--- +title: MongoDB +description: Create a new Prisma Next project with MongoDB using create-prisma@next. +url: /next/quickstart/mongodb +metaTitle: 'Quickstart: Prisma Next with MongoDB' +metaDescription: Scaffold a Prisma Next project with MongoDB, apply the starter migration, seed data, and run your first query. +--- + +Create a Prisma Next app with MongoDB, seed it, and run your first query. + +:::warning[Prisma Next is still in development] + +Prisma Next is not ready for production yet. Prisma ORM 7 is still the recommended choice for production applications today. + +::: + +## Quick start + +```npm +npx create-prisma@next --provider mongodb +``` + +Run this from a Node.js 24 or newer environment. The command preselects MongoDB. The generated local setup gives you a MongoDB replica set through `db:up`; if you use MongoDB Atlas or another existing deployment, set `DATABASE_URL` and skip `db:up`. + +Setup gives you the app template, a starter contract, `prisma-next.md`, project-level Prisma Next skills for your coding agent, and package scripts for the database steps below. + +For local development, use a replica set. MongoDB Atlas already provides one, and the generated `db:up` script starts one for you. + +## 1. Check the database connection + +Open `.env` and confirm that `DATABASE_URL` points to the MongoDB deployment you want Prisma Next to use. + +```text title=".env" +DATABASE_URL="mongodb://127.0.0.1:27017/app?replicaSet=rs0" +``` + +If you use MongoDB Atlas, replace this with the connection string from your Atlas cluster. + +## 2. Start MongoDB + +From the generated project directory, run `db:up` to start the local replica set. + +```npm +npm run db:up +``` + +Skip this command when you use MongoDB Atlas or another existing deployment. + +## 3. Create the migration plan + +Create the first migration plan from the starter contract. + +```npm +npm run migration:plan -- --name init +``` + +## 4. Apply the migration + +Apply the planned migration to MongoDB. + +```npm +npm run migrate +``` + +## 5. Seed data + +`db:seed` inserts sample users so the first query has data to show. + +```npm +npm run db:seed +``` + +## 6. Run the app + +Start the app and confirm the sample query runs successfully. + +```npm +npm run dev +``` + +Use the URL or terminal output shown by your template. You should see the seeded users returned from MongoDB. + +## Next steps + +- Open `src/prisma/contract.prisma` or `src/prisma/contract.ts` and change the starter model. +- Use the [MongoDB existing-project guide](/next/add-to-existing-project/mongodb) if you already have an app and database. +- Read the [Prisma Next overview](/orm/next) when you want the concepts behind contracts, query APIs, and migrations. diff --git a/apps/docs/content/docs/(index)/next/quickstart/postgresql.mdx b/apps/docs/content/docs/(index)/next/quickstart/postgresql.mdx new file mode 100644 index 0000000000..d9f0ec18f3 --- /dev/null +++ b/apps/docs/content/docs/(index)/next/quickstart/postgresql.mdx @@ -0,0 +1,69 @@ +--- +title: PostgreSQL +description: Create a new Prisma Next project with PostgreSQL using create-prisma@next. +url: /next/quickstart/postgresql +metaTitle: 'Quickstart: Prisma Next with PostgreSQL' +metaDescription: Scaffold a Prisma Next project with PostgreSQL, initialize the database, seed data, and run your first query. +--- + +Create a Prisma Next app with PostgreSQL, seed it, and run your first query. + +:::warning[Prisma Next is still in development] + +Prisma Next is not ready for production yet. Prisma ORM 7 is still the recommended choice for production applications today. + +::: + +## Quick start + +```npm +npx create-prisma@next --provider postgres +``` + +Run this from a Node.js 24 or newer environment. The command preselects PostgreSQL, so you can focus on the template and database URL prompts. Pick Prisma Postgres if you want setup to create the database for you, or paste your own `DATABASE_URL`. + +Setup gives you the app template, a starter contract, `prisma-next.md`, project-level Prisma Next skills for your coding agent, and package scripts for the database steps below. + +If you use your own database, keep the connection string ready before you start. + +## 1. Check the database connection + +Open `.env` and confirm that `DATABASE_URL` points to the PostgreSQL database you want Prisma Next to use. + +```text title=".env" +DATABASE_URL="postgresql://username:password@host:5432/database?sslmode=require" +``` + +If you chose Prisma Postgres during setup, this value is already written for you. If you pasted your own connection string, keep it in `.env` and do not hardcode it in application code. + +## 2. Initialize the database + +From the generated project directory, run `db:init` to apply the starter schema to PostgreSQL and sign the database. + +```npm +npm run db:init +``` + +## 3. Seed data + +`db:seed` inserts sample users so the first query has data to show. + +```npm +npm run db:seed +``` + +## 4. Run the app + +Start the app and confirm the sample query runs successfully. + +```npm +npm run dev +``` + +Use the URL or terminal output shown by your template. You should see the seeded users returned from PostgreSQL. + +## Next steps + +- Open `src/prisma/contract.prisma` or `src/prisma/contract.ts` and change the starter model. +- Use the [PostgreSQL existing-project guide](/next/add-to-existing-project/postgresql) if you already have an app and database. +- Read the [Prisma Next overview](/orm/next) when you want the concepts behind contracts, query APIs, and migrations. diff --git a/apps/docs/content/docs/cli/next/index.mdx b/apps/docs/content/docs/cli/next/index.mdx index bcd24d33db..4e3b23dc33 100644 --- a/apps/docs/content/docs/cli/next/index.mdx +++ b/apps/docs/content/docs/cli/next/index.mdx @@ -28,7 +28,7 @@ npx prisma-next help npx prisma-next contract emit ``` -For a full app scaffold, use [`create-prisma@next`](/next/create-prisma). That path creates the project files and package scripts for you. This CLI reference is for the lower-level commands those scripts call. +For a full app scaffold, use a [Prisma Next quickstart](/next/quickstart/postgresql). That path creates the project files and package scripts for you. This CLI reference is for the lower-level commands those scripts call. ## Common workflows diff --git a/apps/docs/content/docs/cli/next/init.mdx b/apps/docs/content/docs/cli/next/init.mdx index 07f76eb742..66db8e2de1 100644 --- a/apps/docs/content/docs/cli/next/init.mdx +++ b/apps/docs/content/docs/cli/next/init.mdx @@ -8,7 +8,7 @@ metaDescription: Learn how to initialize Prisma Next files in an existing projec `prisma-next init` scaffolds the Prisma Next config, contract source, and runtime files inside an existing project. -Use [`create-prisma@next`](/next/create-prisma) when you want a complete new application template. Use `prisma-next init` when you already have a project and want to add the lower-level Prisma Next files. +Use a [Prisma Next quickstart](/next/quickstart/postgresql) when you want a complete new application template. Use `prisma-next init` when you already have a project and want to add the lower-level Prisma Next files. ## Usage diff --git a/apps/docs/content/docs/orm/index.mdx b/apps/docs/content/docs/orm/index.mdx index 893e6c8c62..37710f64fe 100644 --- a/apps/docs/content/docs/orm/index.mdx +++ b/apps/docs/content/docs/orm/index.mdx @@ -14,6 +14,12 @@ Prisma ORM is [open-source](https://github.com/prisma/prisma) and consists of: Prisma Client works with any Node.js or TypeScript backend, whether you're deploying to traditional servers, serverless functions, or microservices. +:::tip[Try Prisma Next] + +Prisma Next is available in early access and is the path toward the next major version of Prisma ORM. Start with the [Prisma Next getting started guide](/next) and share feedback in [Discord](https://pris.ly/discord?utm_source=docs&utm_medium=inline_text). + +::: + ## Why Prisma ORM Traditional database tools force a tradeoff between **productivity** and **control**. Raw SQL gives full control but is error-prone and lacks type safety. Traditional ORMs improve productivity but abstract too much, leading to the [object-relational impedance mismatch](https://en.wikipedia.org/wiki/Object-relational_impedance_mismatch) and performance pitfalls like the n+1 problem. diff --git a/apps/docs/content/docs/orm/next/concepts/contract-first-design.mdx b/apps/docs/content/docs/orm/next/concepts/contract-first-design.mdx deleted file mode 100644 index 979a57c959..0000000000 --- a/apps/docs/content/docs/orm/next/concepts/contract-first-design.mdx +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: Contract-first design in Prisma Next -description: Understand how Prisma Next uses a contract as the source of truth for runtime queries and database changes. -url: /orm/next/concepts/contract-first-design -metaTitle: Contract-first design in Prisma Next -metaDescription: Understand how Prisma Next uses a contract as the source of truth for runtime queries and database changes. ---- - -Prisma Next is contract-first. The contract describes the data shape your application expects, and Prisma Next uses that contract to drive generated types, runtime clients, verification, and database changes. - -The contract-first model answers the important questions from one source of truth: - -- What models, fields, relations, enums, and custom types can application code use? -- Which generated TypeScript types should query code receive? -- Which extension capabilities are required by this application? -- What database shape must exist before this code runs? -- Has the live database drifted away from the contract? - -## What the contract contains - -The emitted `contract.json` is the canonical machine-readable artifact. It is generated from your PSL or TypeScript contract source and then consumed by Prisma Next tooling and runtime clients. - -At a high level, the contract includes: - -| Area | Examples | -| --- | --- | -| Target information | Database family, target database, and extension pack requirements. | -| Application shape | Models, fields, enums, relations, mapped table names, and custom types. | -| Storage mapping | Column types, database names, constraints, indexes, and defaults. | -| Generated metadata | Hashes and metadata used by verification and migration tooling. | - -`contract.d.ts` sits next to `contract.json` and gives TypeScript a typed view of the same contract. - -## Contract lifecycle - -A typical Prisma Next workflow starts by emitting the contract: - -```bash -prisma-next contract emit -``` - -Then run the database workflow that fits the environment: - -| Workflow | Use it when | -| --- | --- | -| `db init` | You are creating missing database structures from the current contract. | -| `db update` | You want Prisma Next to reconcile an existing database directly. | -| `migration plan` and `migration apply` | You want reviewable migration packages in version control. | -| `db verify` | You want to check a live database against the emitted contract. | - -## Drift detection - -Prisma Next verification compares the database marker and live schema with the emitted contract: - -```bash -prisma-next db verify --db "$DATABASE_URL" -``` - -Use verification before deploying code that depends on a changed contract. In CI, prefer JSON output so failures can be parsed reliably: - -```bash -prisma-next db verify --db "$DATABASE_URL" --json -``` - -## Control plane and runtime plane - -Prisma Next separates the tools that understand and change the database from the runtime client that executes application queries. - -| Plane | Where it is used | What it does | -| --- | --- | --- | -| Control plane | `prisma-next.config.ts` and CLI commands | Emits contracts, introspects schemas, plans migrations, verifies drift, and applies changes. | -| Runtime plane | Application code | Loads `contract.json`, exposes query APIs, encodes values, decodes rows, and runs queries. | - -Extension packs usually have both planes. For example, `@prisma-next/extension-pgvector/control` teaches the CLI about vector columns and migration requirements, while `@prisma-next/extension-pgvector/runtime` teaches runtime queries how to encode vectors and expose vector operations. - -## Contracts are not just documentation - -The contract is an executable boundary between your app and the database. If the contract changes, emit it again. If the database changes, verify it again. That is the heart of Prisma Next's design. diff --git a/apps/docs/content/docs/orm/next/concepts/extension-packs.mdx b/apps/docs/content/docs/orm/next/concepts/extension-packs.mdx deleted file mode 100644 index 4e44a4b56c..0000000000 --- a/apps/docs/content/docs/orm/next/concepts/extension-packs.mdx +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: 'Extension packs: adding capabilities' -description: Add database-specific types, operations, and migrations to Prisma Next with extension packs. -url: /orm/next/concepts/extension-packs -metaTitle: Prisma Next extension packs -metaDescription: Add database-specific types, operations, and migrations to Prisma Next with extension packs. ---- - -Extension packs add capabilities that are not part of the base database target. They can contribute column types, query operations, runtime codecs, and migration artifacts. - -Examples include: - -- [pgvector](/orm/next/extensions/pgvector) for vector similarity search -- [PostGIS](/orm/next/extensions/postgis) for geospatial data -- [CipherStash](/orm/next/extensions/cipherstash) for searchable encrypted columns - -## What an extension pack can provide - -| Capability | Example | -| --- | --- | -| Column types | `pgvector.Vector(1536)`, `postgis.Geometry(4326)`, `cipherstash.EncryptedString()`. | -| Query operations | `cosineDistance`, `distanceSphere`, `within`, `cipherstashEq`. | -| Runtime codecs | Encode JavaScript values before sending them to the database and decode returned values. | -| Database setup | Baseline migrations such as `CREATE EXTENSION IF NOT EXISTS vector` or `CREATE EXTENSION IF NOT EXISTS postgis`. | -| Capability gates | Signals that a contract depends on a feature such as `pgvector.cosine` or `postgis.geometry`. | - -## Control and runtime descriptors - -Most extension packs have two sides: - -| Side | Where it is used | Purpose | -| --- | --- | --- | -| Control descriptor | `prisma-next.config.ts` | Lets contract emission and database tooling understand the extension. | -| Runtime descriptor | `prisma/db.ts` or similar | Lets query execution encode, decode, and expose extension operations. | - -Register the control descriptor in config: - -```typescript title="prisma-next.config.ts" -import { defineConfig } from "@prisma-next/postgres/config"; -import pgvector from "@prisma-next/extension-pgvector/control"; - -export default defineConfig({ - contract: "./prisma/contract.prisma", - extensions: [pgvector], -}); -``` - -Register the matching runtime descriptor in your database client: - -```typescript title="prisma/db.ts" -import pgvector from "@prisma-next/extension-pgvector/runtime"; -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({ - contractJson, - extensions: [pgvector], -}); -``` - -The contract and runtime must agree. If the emitted contract requires an extension pack, the runtime must register the matching runtime descriptor. - -## Add an extension to a project - -1. Install the extension package. -2. Add the control descriptor to `prisma-next.config.ts`. -3. Use the extension's types in your contract. -4. Run `prisma-next contract emit`. -5. Add the runtime descriptor to your Prisma Next client. -6. Run `prisma-next db init`, `db update`, or your migration workflow so database-side requirements are applied. - -## Available packs in these docs - -| Pack | Package | Adds | -| --- | --- | --- | -| pgvector | `@prisma-next/extension-pgvector` | Vector columns and cosine distance or similarity operations. | -| PostGIS | `@prisma-next/extension-postgis` | Geometry columns and geospatial operations. | -| CipherStash | `@prisma-next/extension-cipherstash` | Searchable encrypted columns, encryption middleware, and encrypted query operators. | - -Use only the extension packs your contract needs. Keeping the extension list small makes database setup and runtime wiring easier to reason about. diff --git a/apps/docs/content/docs/orm/next/concepts/meta.json b/apps/docs/content/docs/orm/next/concepts/meta.json deleted file mode 100644 index 9a22bab442..0000000000 --- a/apps/docs/content/docs/orm/next/concepts/meta.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "title": "Core Concepts", - "pages": [ - "contract-first-design", - "schema-definition-and-contract-emission", - "query-apis", - "extension-packs" - ] -} diff --git a/apps/docs/content/docs/orm/next/concepts/query-apis.mdx b/apps/docs/content/docs/orm/next/concepts/query-apis.mdx deleted file mode 100644 index a241807498..0000000000 --- a/apps/docs/content/docs/orm/next/concepts/query-apis.mdx +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: 'Query APIs: SQL DSL and ORM client' -description: Choose between Prisma Next model-oriented and lower-level query APIs. -url: /orm/next/concepts/query-apis -metaTitle: Prisma Next query APIs -metaDescription: Learn when to use db.orm, db.sql, and db.query in Prisma Next. ---- - -Prisma Next gives you more than one query surface because different queries need different levels of control. - -| API | Use it for | -| --- | --- | -| `db.orm` | Model-oriented CRUD and readable application queries. | -| `db.sql` | PostgreSQL queries where you want an explicit SQL-shaped plan. | -| `db.query` | MongoDB queries where you want an explicit document query plan. | - -All of these APIs are contract-aware. They use the emitted contract to type fields, validate model names, and expose extension-provided operations. - -## ORM client - -Use the ORM client when you want model-oriented code: - -```typescript -const user = await db.orm.User - .where((user) => user.email.eq("alice@example.com")) - .first(); -``` - -The ORM client is the default place for normal application reads and writes: - -```typescript -const newestUsers = await db.orm.User - .orderBy((user) => user.createdAt.desc()) - .take(10) - .all(); -``` - -## SQL DSL - -Use `db.sql` when you want a lower-level PostgreSQL plan: - -```typescript -const plan = db.sql.user - .select("id", "email", "createdAt") - .where((field, fns) => fns.eq(field.email, "alice@example.com")) - .limit(1) - .build(); - -const rows = await db.runtime().execute(plan); -``` - -The SQL DSL is useful for explicit projections, computed columns, extension operations, and query shapes where reviewing the plan matters. - -## Same query, two surfaces - -Use the ORM surface for the everyday version: - -```typescript -const posts = await db.orm.Post - .where((post) => post.title.ilike("%prisma%")) - .orderBy((post) => post.createdAt.desc()) - .take(10) - .all(); -``` - -Use the SQL DSL when you want the plan object: - -```typescript -const plan = db.sql.post - .select("id", "title", "createdAt") - .where((field, fns) => fns.ilike(field.title, "%prisma%")) - .orderBy((field) => field.createdAt, { direction: "desc" }) - .limit(10) - .build(); - -const posts = await db.runtime().execute(plan); -``` - -## Transactions - -The Postgres runtime facade exposes transaction scopes: - -```typescript -await db.transaction(async (tx) => { - await tx.orm.User.create({ - id: crypto.randomUUID(), - email: "alice@example.com", - }); - - await tx.execute( - tx.sql.post - .insert({ - id: crypto.randomUUID(), - title: "Welcome", - userId: "user-id", - createdAt: new Date(), - }) - .build(), - ); -}); -``` - -Use the transaction context when related reads and writes must commit or roll back together. - -## MongoDB query builder - -MongoDB uses `db.query` for lower-level document queries: - -```typescript -const plan = db.query - .from("products") - .sort({ _id: 1 }) - .skip(20) - .limit(10) - .build(); -``` - -Use it when the query is naturally expressed as a document query plan instead of a model-oriented operation. diff --git a/apps/docs/content/docs/orm/next/concepts/schema-definition-and-contract-emission.mdx b/apps/docs/content/docs/orm/next/concepts/schema-definition-and-contract-emission.mdx deleted file mode 100644 index 3ea9009f1b..0000000000 --- a/apps/docs/content/docs/orm/next/concepts/schema-definition-and-contract-emission.mdx +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: Schema definition and contract emission -description: Define a Prisma Next contract in PSL or TypeScript and emit generated artifacts. -url: /orm/next/concepts/schema-definition-and-contract-emission -metaTitle: Schema definition and contract emission in Prisma Next -metaDescription: Define a Prisma Next contract in PSL or TypeScript and emit contract.json and contract.d.ts. ---- - -Prisma Next lets you author a contract in PSL or TypeScript. Both paths emit the same kind of generated artifacts for runtime clients, database verification, and migration planning. - -## PSL authoring - -PSL keeps the contract close to the Prisma schema syntax many users already know: - -```prisma title="prisma/contract.prisma" -// use prisma-next - -model User { - id String @id @default(uuid()) - email String @unique - createdAt DateTime @default(now()) -} -``` - -The config points Prisma Next at that contract source: - -```typescript title="prisma-next.config.ts" -import "dotenv/config"; -import { defineConfig } from "@prisma-next/postgres/config"; - -export default defineConfig({ - contract: "./prisma/contract.prisma", - db: { - connection: process.env["DATABASE_URL"]!, - }, -}); -``` - -MongoDB projects use the same shape with `@prisma-next/mongo/config`. - -## TypeScript authoring - -TypeScript authoring uses builder APIs instead of a `.prisma` file. It is useful when you want a programmable schema surface or want to compose shared schema pieces in code. - -Choose TypeScript authoring when you scaffold: - -```bash -npx create-prisma@next --authoring typescript -``` - -Or when you initialize the lower-level CLI workflow: - -```bash -prisma-next init --authoring typescript -``` - -## Emit the contract - -Run `contract emit` after changing the contract source: - -```bash -prisma-next contract emit -``` - -The command is offline. It reads `prisma-next.config.ts`, validates the contract source, and writes the generated artifacts. - -| Artifact | Purpose | -| --- | --- | -| `contract.json` | The canonical contract used by runtimes, verification, and migration tooling. | -| `contract.d.ts` | Generated TypeScript declarations used by query code. | - -Do not edit these generated files by hand. Re-run `prisma-next contract emit` when the contract source changes. - -## Load the emitted contract at runtime - -Your runtime client imports the emitted JSON contract and its generated type: - -```typescript title="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({ - contractJson, - url: process.env["DATABASE_URL"]!, -}); -``` - -For serverless runtimes, use the serverless facade instead: - -```typescript title="prisma/db.ts" -import postgresServerless from "@prisma-next/postgres/serverless"; -import type { Contract } from "./contract.d"; -import contractJson from "./contract.json" with { type: "json" }; - -export const db = postgresServerless({ - contractJson, -}); -``` - -## No-emit authoring - -Some development workflows can pass a TypeScript-authored contract directly to the runtime client instead of loading `contract.json`. This is useful for local experimentation, but emitted artifacts are still the clearest boundary for CI, deployments, and database verification. - -Use emitted contracts when you need repeatable builds or any CLI command that checks or changes a database. diff --git a/apps/docs/content/docs/orm/next/extensions/cipherstash.mdx b/apps/docs/content/docs/orm/next/extensions/cipherstash.mdx deleted file mode 100644 index be3a6f8169..0000000000 --- a/apps/docs/content/docs/orm/next/extensions/cipherstash.mdx +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: CipherStash extension -description: Add searchable encrypted columns to Prisma Next with CipherStash. -url: /orm/next/extensions/cipherstash -metaTitle: CipherStash extension in Prisma Next -metaDescription: Learn how to configure CipherStash encryption and searchable encrypted queries in Prisma Next. ---- - -The `@prisma-next/extension-cipherstash` pack adds searchable encrypted column support for PostgreSQL. - -Use it when values should be encrypted at rest but still queried through CipherStash-supported operations such as equality, text search, range search, and JSON search. - -## Install the package - -```bash -npm install @prisma-next/extension-cipherstash -``` - -You also need a CipherStash workspace, credentials for your app, and the database-side EQL bundle required by your encryption setup. - -## Configure the extension - -Register the control descriptor: - -```typescript title="prisma-next.config.ts" -import { defineConfig } from "@prisma-next/postgres/config"; -import cipherstash from "@prisma-next/extension-cipherstash/control"; - -export default defineConfig({ - contract: "./prisma/contract.prisma", - extensions: [cipherstash], -}); -``` - -Register the runtime descriptor and middleware: - -```typescript title="src/db.ts" -import { bulkEncryptMiddleware } from "@prisma-next/extension-cipherstash/middleware"; -import { createCipherstashRuntimeDescriptor } from "@prisma-next/extension-cipherstash/runtime"; -import postgres from "@prisma-next/postgres/runtime"; -import type { Contract } from "./prisma/contract.d"; -import contractJson from "./prisma/contract.json" with { type: "json" }; -import { createCipherstashSdk } from "./sdk"; - -const sdk = createCipherstashSdk(); - -export const db = postgres({ - contractJson, - extensions: [createCipherstashRuntimeDescriptor({ sdk })], - middleware: [bulkEncryptMiddleware(sdk)], -}); -``` - -## Define encrypted fields - -CipherStash provides six encrypted column types: - -| PSL constructor | Plain JavaScript value | Search modes | -| --- | --- | --- | -| `cipherstash.EncryptedString()` | `string` | Equality, text search, order and range. | -| `cipherstash.EncryptedDouble()` | `number` | Equality, order and range. | -| `cipherstash.EncryptedBigInt()` | `bigint` | Equality, order and range. | -| `cipherstash.EncryptedDate()` | `Date` | Equality, order and range. | -| `cipherstash.EncryptedBoolean()` | `boolean` | Equality. | -| `cipherstash.EncryptedJson()` | JSON value | Searchable JSON. | - -```prisma title="prisma/contract.prisma" -// use prisma-next - -model User { - id String @id - email cipherstash.EncryptedString() - salary cipherstash.EncryptedDouble() - accountId cipherstash.EncryptedBigInt() @map("accountid") - birthday cipherstash.EncryptedDate() - emailVerified cipherstash.EncryptedBoolean() @map("emailverified") - preferences cipherstash.EncryptedJson() - - @@map("users") -} -``` - -Search flags default to enabled for the modes supported by each encrypted type. Disable modes explicitly when a column should be storage-only or should expose fewer query operators. - -## Insert encrypted values - -Wrap plaintext values with the encrypted runtime classes: - -```typescript -import { - EncryptedBoolean, - EncryptedDate, - EncryptedDouble, - EncryptedJson, - EncryptedString, -} from "@prisma-next/extension-cipherstash/runtime"; - -await db.orm.User.create({ - id: "user-1", - email: EncryptedString.from("alice@example.com"), - salary: EncryptedDouble.from(95_000), - birthday: EncryptedDate.from(new Date("1990-04-12")), - emailVerified: EncryptedBoolean.from(true), - preferences: EncryptedJson.from({ theme: "dark" }), -}); -``` - -The middleware groups encryption work before the query reaches the database. - -## Query encrypted values - -CipherStash operators are exposed only on compatible encrypted columns: - -```typescript -const users = await db.orm.User - .where((user) => user.email.cipherstashIlike("%@example.com")) - .all(); -``` - -Range operators are available on encrypted string, number, bigint, and date fields: - -```typescript -const users = await db.orm.User - .where((user) => user.salary.cipherstashGt(100_000)) - .all(); -``` - -Equality-style lookups can use array operators: - -```typescript -const users = await db.orm.User - .where((user) => user.emailVerified.cipherstashInArray([true])) - .all(); -``` - -## Decrypt returned rows - -Use `decryptAll` to batch-decrypt envelopes from a result set: - -```typescript -import { decryptAll } from "@prisma-next/extension-cipherstash/runtime"; - -const rows = await db.orm.User - .where((user) => user.email.cipherstashEq("alice@example.com")) - .all(); - -await decryptAll(rows); - -console.log(await rows[0]?.email.decrypt()); -``` - -## Operator reference - -| Operator | Applies to | -| --- | --- | -| `cipherstashEq(value)` | All encrypted types with equality enabled. | -| `cipherstashNe(value)` | All encrypted types with equality enabled. | -| `cipherstashInArray(values)` | All encrypted types with equality enabled. | -| `cipherstashNotInArray(values)` | All encrypted types with equality enabled. | -| `cipherstashIlike(pattern)` | `EncryptedString` with text search enabled. | -| `cipherstashNotIlike(pattern)` | `EncryptedString` with text search enabled. | -| `cipherstashGt(value)`, `cipherstashGte(value)` | String, number, bigint, and date fields with order and range enabled. | -| `cipherstashLt(value)`, `cipherstashLte(value)` | String, number, bigint, and date fields with order and range enabled. | -| `cipherstashBetween(min, max)` | String, number, bigint, and date fields with order and range enabled. | -| `cipherstashNotBetween(min, max)` | String, number, bigint, and date fields with order and range enabled. | -| `cipherstashJsonbPathExists(path)` | `EncryptedJson` with searchable JSON enabled. | - -The runtime package also exports helpers such as `cipherstashAsc`, `cipherstashDesc`, `cipherstashJsonbPathQueryFirst`, and `cipherstashJsonbGet` for sort and projection use cases. - -## Security notes - -Searchable encryption intentionally exposes limited search behavior through configured indexes. Enable only the search modes your application needs, protect CipherStash credentials like production secrets, and keep encryption setup in a controlled deployment workflow. diff --git a/apps/docs/content/docs/orm/next/extensions/meta.json b/apps/docs/content/docs/orm/next/extensions/meta.json deleted file mode 100644 index 0a31731836..0000000000 --- a/apps/docs/content/docs/orm/next/extensions/meta.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "title": "Extensions", - "pages": [ - "pgvector", - "postgis", - "cipherstash" - ] -} diff --git a/apps/docs/content/docs/orm/next/extensions/pgvector.mdx b/apps/docs/content/docs/orm/next/extensions/pgvector.mdx deleted file mode 100644 index d16f0efd43..0000000000 --- a/apps/docs/content/docs/orm/next/extensions/pgvector.mdx +++ /dev/null @@ -1,141 +0,0 @@ ---- -title: pgvector extension -description: Add vector similarity search to Prisma Next with pgvector. -url: /orm/next/extensions/pgvector -metaTitle: pgvector extension in Prisma Next -metaDescription: Learn how to configure pgvector and run vector similarity queries in Prisma Next. ---- - -The `@prisma-next/extension-pgvector` pack adds pgvector columns and vector similarity operations for PostgreSQL. - -Use it when your app stores embeddings and needs nearest-neighbor style queries, such as semantic search, recommendations, or similarity ranking. - -## Install the package - -```bash -npm install @prisma-next/extension-pgvector -``` - -## Configure the extension - -Register the control descriptor in `prisma-next.config.ts`: - -```typescript title="prisma-next.config.ts" -import { defineConfig } from "@prisma-next/postgres/config"; -import pgvector from "@prisma-next/extension-pgvector/control"; - -export default defineConfig({ - contract: "./prisma/contract.prisma", - extensions: [pgvector], -}); -``` - -Register the runtime descriptor in your database client: - -```typescript title="prisma/db.ts" -import pgvector from "@prisma-next/extension-pgvector/runtime"; -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({ - contractJson, - extensions: [pgvector], -}); -``` - -## Define vector fields - -Every vector column must declare a dimension: - -```prisma title="prisma/contract.prisma" -// use prisma-next - -types { - Embedding1536 = pgvector.Vector(1536) -} - -model Post { - id String @id @default(uuid()) - title String - embedding Embedding1536? -} -``` - -The emitted `contract.d.ts` uses a dimensioned `Vector<1536>` type so query results preserve the vector size in TypeScript. - -## Emit and apply database setup - -After adding the extension and vector field, emit the contract: - -```bash -prisma-next contract emit -``` - -Then run your database workflow: - -```bash -prisma-next db init --db "$DATABASE_URL" -``` - -The extension pack contributes a baseline migration that installs pgvector with: - -```sql -CREATE EXTENSION IF NOT EXISTS vector; -``` - -If your database is managed, make sure the provider allows the pgvector extension. - -## Query by similarity with the ORM - -Use vector operations on vector fields: - -```typescript -const similarPosts = await db.orm.Post - .where((post) => post.embedding.cosineDistance(queryVector).lt(0.3)) - .orderBy((post) => post.embedding.cosineDistance(queryVector).asc()) - .take(10) - .all(); -``` - -Use the ORM surface when you want model rows ordered by similarity. - -## Query by similarity with the SQL DSL - -Use the SQL DSL when you also want to project the computed distance: - -```typescript -const plan = db.sql.post - .select("id", "title") - .select("distance", (field, fns) => fns.cosineDistance(field.embedding, queryVector)) - .orderBy((field, fns) => fns.cosineDistance(field.embedding, queryVector), { - direction: "asc", - }) - .limit(10) - .build(); - -const rows = await db.runtime().execute(plan); -``` - -## Operations - -| Operation | Returns | Use it for | -| --- | --- | --- | -| `cosineDistance(rhs)` | `number` | Ranking nearest vectors first. Lower values are closer. | -| `cosineSimilarity(rhs)` | `number` | Ranking by similarity score. Higher values are more similar. | - -Both operations are available only on vector fields from the pgvector extension. - -## Type exports - -Use the codec types when a helper needs to reference vector values directly: - -```typescript -import type { Vector } from "@prisma-next/extension-pgvector/codec-types"; - -function normalizeEmbedding(value: Vector<1536>) { - return value; -} -``` - -For TypeScript-authored contracts, the package also exports `vector` from `@prisma-next/extension-pgvector/column-types` and a pure pack descriptor from `@prisma-next/extension-pgvector/pack`. diff --git a/apps/docs/content/docs/orm/next/extensions/postgis.mdx b/apps/docs/content/docs/orm/next/extensions/postgis.mdx deleted file mode 100644 index 0ddd88e490..0000000000 --- a/apps/docs/content/docs/orm/next/extensions/postgis.mdx +++ /dev/null @@ -1,180 +0,0 @@ ---- -title: PostGIS extension -description: Add geospatial types and queries to Prisma Next with PostGIS. -url: /orm/next/extensions/postgis -metaTitle: PostGIS extension in Prisma Next -metaDescription: Learn how to configure PostGIS and write geospatial queries in Prisma Next. ---- - -The `@prisma-next/extension-postgis` pack adds geospatial column types and PostGIS-backed query operations for PostgreSQL. - -Use it when your app stores points, routes, neighborhoods, service areas, or any other location-aware data. - -## Install the package - -```bash -npm install @prisma-next/extension-postgis -``` - -Your PostgreSQL server must allow the PostGIS extension. For local development, a PostGIS-enabled PostgreSQL image is usually the easiest path. - -## Configure the extension - -Register the control descriptor: - -```typescript title="prisma-next.config.ts" -import { defineConfig } from "@prisma-next/postgres/config"; -import postgis from "@prisma-next/extension-postgis/control"; - -export default defineConfig({ - contract: "./prisma/contract.prisma", - extensions: [postgis], -}); -``` - -Register the runtime descriptor: - -```typescript title="prisma/db.ts" -import postgis from "@prisma-next/extension-postgis/runtime"; -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({ - contractJson, - extensions: [postgis], -}); -``` - -## Define geospatial fields - -Declare a `Geometry` type in PSL. SRID `4326` is the common WGS84 longitude and latitude coordinate system: - -```prisma title="prisma/contract.prisma" -// use prisma-next - -types { - WgsGeometry = postgis.Geometry(4326) -} - -model Cafe { - id String @id @default(uuid()) - name String - location WgsGeometry -} - -model Neighborhood { - id String @id @default(uuid()) - name String - boundary WgsGeometry -} -``` - -`postgis.Geometry()` without an SRID is also valid when your schema needs to store mixed coordinate systems. - -## Create geometry values - -Use the helpers from `@prisma-next/extension-postgis/geojson`: - -```typescript -import { bboxPolygon, point, polygon } from "@prisma-next/extension-postgis/geojson"; - -const ferryBuilding = point(-122.3937, 37.7955, 4326); - -const downtown = bboxPolygon([-122.425, 37.775, -122.4, 37.8], 4326); - -const boundary = polygon( - [ - [-122.418, 37.77], - [-122.4, 37.77], - [-122.4, 37.785], - [-122.418, 37.785], - [-122.418, 37.77], - ], - 4326, -); -``` - -Coordinates are longitude first, then latitude. - -## Query geospatial data with the ORM - -Use geospatial operations on geometry fields: - -```typescript -const cafes = await db.orm.Cafe - .where((cafe) => cafe.location.within(boundary)) - .all(); -``` - -Find rows within a radius and order nearest first: - -```typescript -const nearby = await db.orm.Cafe - .where((cafe) => cafe.location.distanceSphere(ferryBuilding).lte(2_000)) - .orderBy((cafe) => cafe.location.distanceSphere(ferryBuilding).asc()) - .take(10) - .all(); -``` - -Use `intersectsBbox` for map viewport queries: - -```typescript -const visible = await db.orm.Cafe - .where((cafe) => cafe.location.intersectsBbox(downtown)) - .all(); -``` - -## Query geospatial data with the SQL DSL - -Use the SQL DSL when you want an explicit PostGIS projection or sort: - -```typescript -const plan = db.sql.cafe - .select("id", "name") - .select("meters", (field, fns) => fns.distanceSphere(field.location, ferryBuilding)) - .orderBy((field, fns) => fns.distanceSphere(field.location, ferryBuilding), { - direction: "asc", - }) - .limit(5) - .build(); - -const rows = await db.runtime().execute(plan); -``` - -## Operations - -| Operation | Use it for | -| --- | --- | -| `distance(other)` | Cartesian distance in the geometry's native units. | -| `distanceSphere(other)` | Approximate metres between longitude and latitude geometries. | -| `dwithin(other, distance)` | Index-friendly "within this distance" checks. | -| `contains(other)` | Polygon or geometry containment. | -| `within(other)` | The inverse of `contains`. | -| `intersects(other)` | Any overlap between geometries. | -| `intersectsBbox(other)` | Fast 2D bounding-box overlap for viewport filtering. | - -## SRID and units - -Declare an SRID at the column level when you know the coordinate system. Values created with `point`, `polygon`, and `bboxPolygon` should use the same SRID. - -For SRID 4326 data, `distance` returns degrees. Use `distanceSphere` when the product needs metres. - -## Wire format and types - -Runtime values are GeoJSON-shaped objects with optional SRID metadata. The codec handles the PostGIS wire format for you. - -```typescript -import type { Geometry } from "@prisma-next/extension-postgis/codec-types"; - -const route: Geometry = { - type: "LineString", - coordinates: [ - [-122.4194, 37.7749], - [-122.4106, 37.7765], - ], - srid: 4326, -}; -``` - -The extension declares the `postgis.geometry` capability, which gates the geometry type and the operations above. diff --git a/apps/docs/content/docs/orm/next/guides/building-queries-with-sql-dsl.mdx b/apps/docs/content/docs/orm/next/guides/building-queries-with-sql-dsl.mdx deleted file mode 100644 index f429cfcf0b..0000000000 --- a/apps/docs/content/docs/orm/next/guides/building-queries-with-sql-dsl.mdx +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: Building queries with the SQL DSL -description: Build explicit PostgreSQL query plans with Prisma Next db.sql. -url: /orm/next/guides/building-queries-with-sql-dsl -metaTitle: Building queries with Prisma Next SQL DSL -metaDescription: Learn how to build explicit PostgreSQL query plans with Prisma Next db.sql. ---- - -Use `db.sql` when you want an explicit PostgreSQL query plan while keeping contract-aware fields, result types, and extension operations. - -`db.sql` builds a plan. The runtime executes the plan: - -```typescript -const plan = db.sql.user - .select("id", "email", "createdAt") - .limit(10) - .build(); - -const rows = await db.runtime().execute(plan); -``` - -## Select fields - -```typescript -const plan = db.sql.user - .select("id", "email", "createdAt") - .limit(10) - .build(); -``` - -Select only the fields your caller needs. The result type follows the projection. - -## Add filters - -Use the `fns` helper in `where` callbacks for SQL predicates: - -```typescript -const plan = db.sql.user - .select("id", "email") - .where((field, fns) => fns.eq(field.email, "alice@example.com")) - .build(); -``` - -Chain `where` calls to add more conditions: - -```typescript -const plan = db.sql.post - .select("id", "title", "createdAt") - .where((field, fns) => fns.ilike(field.title, "%prisma%")) - .where((field, fns) => fns.gte(field.createdAt, new Date("2026-01-01"))) - .build(); -``` - -## Order and limit - -```typescript -const plan = db.sql.post - .select("id", "title", "createdAt") - .orderBy((field) => field.createdAt, { direction: "desc" }) - .orderBy((field) => field.id, { direction: "asc" }) - .limit(20) - .build(); -``` - -Use a stable tie-breaker such as `id` when a query powers pagination or a feed. - -## Add computed projections - -Extension packs can add query operations to the SQL DSL. For example, pgvector exposes cosine distance: - -```typescript -const plan = db.sql.post - .select("id", "title") - .select("distance", (field, fns) => fns.cosineDistance(field.embedding, queryVector)) - .orderBy((field, fns) => fns.cosineDistance(field.embedding, queryVector), { - direction: "asc", - }) - .limit(10) - .build(); -``` - -This is the kind of query where the SQL DSL is a better fit than the ORM surface: the result includes a computed column that is not part of the model. - -## Insert, update, and delete - -The SQL DSL also builds mutation plans: - -```typescript -const insertPlan = db.sql.user - .insert({ - id: crypto.randomUUID(), - email: "alice@example.com", - createdAt: new Date(), - }) - .returning("id", "email") - .build(); - -const inserted = await db.runtime().execute(insertPlan); -``` - -```typescript -const updatePlan = db.sql.user - .update({ email: "alice@prisma.io" }) - .where((field, fns) => fns.eq(field.id, userId)) - .returning("id", "email") - .build(); - -const updated = await db.runtime().execute(updatePlan); -``` - -```typescript -const deletePlan = db.sql.user - .delete() - .where((field, fns) => fns.eq(field.id, userId)) - .returning("id") - .build(); - -const deleted = await db.runtime().execute(deletePlan); -``` - -## Build first, execute later - -Because `db.sql` returns plans, you can pass plans through your own helpers before execution: - -```typescript -function usersByDomain(domain: string) { - return db.sql.user - .select("id", "email") - .where((field, fns) => fns.ilike(field.email, `%@${domain}`)) - .build(); -} - -const rows = await db.runtime().execute(usersByDomain("example.com")); -``` - -User input is passed as parameters by the query builder. Do not build SQL by concatenating strings. diff --git a/apps/docs/content/docs/orm/next/guides/deploying-to-serverless-runtimes.mdx b/apps/docs/content/docs/orm/next/guides/deploying-to-serverless-runtimes.mdx deleted file mode 100644 index ef36ef3580..0000000000 --- a/apps/docs/content/docs/orm/next/guides/deploying-to-serverless-runtimes.mdx +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: Deploying Prisma Next to serverless runtimes -description: Use Prisma Next in serverless and edge-like runtimes with request-scoped database connections. -url: /orm/next/guides/deploying-to-serverless-runtimes -metaTitle: Deploying Prisma Next to serverless runtimes -metaDescription: Learn the Prisma Next runtime pattern for serverless deployments. ---- - -Serverless runtimes work best when static query surfaces are created once and database connections are acquired per request. - -For PostgreSQL serverless environments, use `@prisma-next/postgres/serverless`: - -```typescript title="prisma/db.ts" -import postgresServerless from "@prisma-next/postgres/serverless"; -import type { Contract } from "./contract.d"; -import contractJson from "./contract.json" with { type: "json" }; - -export const db = postgresServerless({ - contractJson, -}); -``` - -Then connect inside the request handler: - -```typescript -interface Env { - HYPERDRIVE: { connectionString: string }; -} - -export default { - async fetch(request: Request, env: Env) { - await using runtime = await db.connect({ - url: env.HYPERDRIVE.connectionString, - }); - - const rows = await runtime.execute( - db.sql.user.select("id", "email").limit(10).build(), - ); - - return Response.json(rows); - }, -}; -``` - -## Node runtime versus serverless runtime - -| Runtime | Import | Connection model | -| --- | --- | --- | -| Node or long-lived process | `@prisma-next/postgres/runtime` | Configure a URL or pool once and call `db.runtime()` or `db.connect()`. | -| Serverless or edge-like handler | `@prisma-next/postgres/serverless` | Keep the query surface at module scope and call `db.connect({ url })` inside each request. | - -The serverless facade intentionally exposes `db.sql`, `db.context`, and `db.connect`. It does not keep a process-wide `db.orm` or `db.runtime()` because those can accidentally retain stale request connections. - -## ORM queries in serverless handlers - -When a serverless route needs the ORM surface, build it from the request runtime and the shared context: - -```typescript -import { orm } from "@prisma-next/sql-orm-client"; - -export default { - async fetch(request: Request, env: Env) { - await using runtime = await db.connect({ - url: env.HYPERDRIVE.connectionString, - }); - - const client = orm({ - runtime, - context: db.context, - }); - - const users = await client.User - .orderBy((user) => user.createdAt.desc()) - .take(10) - .all(); - - return Response.json(users); - }, -}; -``` - -## Deployment checklist - -- Emit `contract.json` and `contract.d.ts` before building the deployment bundle. -- Keep the `db` object at module scope. -- Open database connections inside the request, job, or handler. -- Dispose request-scoped runtimes when the handler finishes. -- Run `prisma-next db verify` in CI or before deployment. -- Run migrations from a Node environment or controlled deployment job, not from every request. - -If your platform provides a database proxy such as Hyperdrive, use the connection string from that binding instead of a process-wide static URL. diff --git a/apps/docs/content/docs/orm/next/guides/error-handling-patterns.mdx b/apps/docs/content/docs/orm/next/guides/error-handling-patterns.mdx deleted file mode 100644 index f6212f32c1..0000000000 --- a/apps/docs/content/docs/orm/next/guides/error-handling-patterns.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Error handling patterns in Prisma Next -description: Handle Prisma Next CLI and runtime errors in local development, CI, and application code. -url: /orm/next/guides/error-handling-patterns -metaTitle: Error handling patterns in Prisma Next -metaDescription: Learn practical error handling patterns for Prisma Next CLI commands and runtime code. ---- - -Prisma Next is early-access, so error handling should make failures easy to inspect and safe to automate. - -## Common failure categories - -| Category | Where it appears | Typical fix | -| --- | --- | --- | -| Config errors | CLI startup | Check `prisma-next.config.ts`, `--config`, and database target wiring. | -| Missing database URL | Database and migration commands | Pass `--db` or set `db.connection` in the config. | -| Contract drift | `db verify`, runtime verification | Emit the contract again, apply the required database changes, then verify. | -| Extension mismatch | CLI database commands or runtime startup | Register the same extension packs in config and runtime. | -| Query/runtime errors | Application code | Catch errors at request or job boundaries and return an application-level error. | - -## Use JSON output in automation - -Use `--json` for scripts and CI: - -```bash -prisma-next db verify --db "$DATABASE_URL" --json -``` - -JSON output is easier to parse than terminal text and avoids brittle log matching. - -## Keep verification separate from deployment - -Run verification before code that depends on a new contract is deployed: - -```bash -prisma-next contract emit -prisma-next db verify --db "$DATABASE_URL" --strict -``` - -Use `--strict` when extra database schema elements should fail the check. - -## Add trace output only when debugging - -Use trace output when a command fails in a way you need to report or debug: - -```bash -prisma-next db verify --db "$DATABASE_URL" --trace -``` - -Keep trace output out of normal CI logs unless you need it. - -## Handle runtime failures at boundaries - -Create and close runtimes at request or job boundaries. Keep query code focused on the application operation, and translate Prisma Next failures into errors your API can return consistently. - -```typescript -export async function loadUsers() { - try { - return await db.orm.User - .select("id", "email") - .take(50) - .all(); - } catch (error) { - console.error(error); - throw new Error("Could not load users"); - } -} -``` - -For serverless handlers, dispose the runtime even when a query fails: - -```typescript -try { - await using runtime = await db.connect({ url: env.HYPERDRIVE.connectionString }); - return Response.json( - await runtime.execute(db.sql.user.select("id", "email").build()), - ); -} catch (error) { - console.error(error); - return Response.json({ error: "Could not load users" }, { status: 500 }); -} -``` - -## Handle migration errors conservatively - -Migration failures should stop deployment. Prefer this order: - -1. Run `prisma-next migration status --db "$DATABASE_URL"` before applying. -2. Run `prisma-next migration apply --db "$DATABASE_URL"` from a controlled job. -3. Run `prisma-next db verify --db "$DATABASE_URL"` after applying. -4. Deploy application code only after verification succeeds. - -If a migration fails partway through, inspect the database state and migration history before retrying. Do not blindly re-run destructive changes in production. diff --git a/apps/docs/content/docs/orm/next/guides/managing-database-migrations.mdx b/apps/docs/content/docs/orm/next/guides/managing-database-migrations.mdx deleted file mode 100644 index e765228e05..0000000000 --- a/apps/docs/content/docs/orm/next/guides/managing-database-migrations.mdx +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: Managing database migrations -description: Choose between direct database reconciliation and checked-in migrations in Prisma Next. -url: /orm/next/guides/managing-database-migrations -metaTitle: Managing database migrations in Prisma Next -metaDescription: Learn how Prisma Next handles database initialization, updates, verification, and migration packages. ---- - -Prisma Next database changes start from the emitted contract. After you change the contract, emit artifacts first: - -```bash -prisma-next contract emit -``` - -Then choose either the direct database workflow or the checked-in migration workflow. - -## Direct database workflow - -Use direct commands when you want Prisma Next to bring a database in line with the current contract: - -```bash -prisma-next db init --db "$DATABASE_URL" -prisma-next db update --db "$DATABASE_URL" -prisma-next db verify --db "$DATABASE_URL" -``` - -| Command | Use it when | -| --- | --- | -| `db init` | Creating missing structures for the first time. It is intended for additive bootstrap work. | -| `db update` | Reconciling an existing database with a changed contract. | -| `db verify` | Checking that a live database still matches the emitted contract. | - -Use `--dry-run` with `db init` or `db update` before touching a shared database: - -```bash -prisma-next db update --db "$DATABASE_URL" --dry-run -``` - -## Checked-in migration workflow - -Use migration packages when you want database changes reviewed in version control: - -```bash -prisma-next migration plan --name add-users-table -prisma-next migration status --db "$DATABASE_URL" -prisma-next migration apply --db "$DATABASE_URL" -``` - -`migration plan` is offline. It creates a migration package from contract changes. `migration apply` runs pending packages against the database. - -## Suggested development loop - -1. Edit the PSL or TypeScript contract source. -2. Run `prisma-next contract emit`. -3. Run `prisma-next migration plan --name `. -4. Review the generated migration package. -5. Run `prisma-next migration status --db "$DATABASE_URL"`. -6. Run `prisma-next migration apply --db "$DATABASE_URL"`. -7. Run `prisma-next db verify --db "$DATABASE_URL"`. - -For a small local prototype, `db update --dry-run` followed by `db update` can be faster. For team development, checked-in migrations are easier to review and reproduce. - -## Existing databases - -For an existing database, start by inferring a contract: - -```bash -prisma-next contract infer --db "$DATABASE_URL" --output ./prisma/contract.prisma -``` - -Review and edit the inferred contract, then emit and sign: - -```bash -prisma-next contract emit -prisma-next db sign --db "$DATABASE_URL" -prisma-next db verify --db "$DATABASE_URL" -``` - -`db sign` records that the current database matches the current contract. After signing, use `db verify` in CI to detect drift. - -## Extension pack migrations - -Some extension packs contribute their own database setup. For example, pgvector and PostGIS need database extensions enabled. When those packs are registered in your config, Prisma Next can include the required extension-space migrations alongside your application schema workflow. - -Always re-emit the contract after adding or removing an extension pack, then run your database workflow again. diff --git a/apps/docs/content/docs/orm/next/guides/meta.json b/apps/docs/content/docs/orm/next/guides/meta.json deleted file mode 100644 index e4558789bf..0000000000 --- a/apps/docs/content/docs/orm/next/guides/meta.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "title": "Guides", - "pages": [ - "using-the-orm-client", - "building-queries-with-sql-dsl", - "managing-database-migrations", - "deploying-to-serverless-runtimes", - "error-handling-patterns" - ] -} diff --git a/apps/docs/content/docs/orm/next/guides/using-the-orm-client.mdx b/apps/docs/content/docs/orm/next/guides/using-the-orm-client.mdx deleted file mode 100644 index ff6a504033..0000000000 --- a/apps/docs/content/docs/orm/next/guides/using-the-orm-client.mdx +++ /dev/null @@ -1,147 +0,0 @@ ---- -title: Using the ORM client with Prisma Next -description: Use db.orm for model-oriented Prisma Next queries. -url: /orm/next/guides/using-the-orm-client -metaTitle: Using the Prisma Next ORM client -metaDescription: Learn how to use db.orm for model-oriented Prisma Next queries. ---- - -Use `db.orm` for model-oriented reads and writes. It is the highest-level Prisma Next query API and the best default for application code. - -## Create records - -```typescript -await db.orm.User.create({ - id: crypto.randomUUID(), - email: "alice@example.com", - createdAt: new Date(), -}); -``` - -Use the values your contract requires. Prisma Next checks model and field names from the emitted contract. - -## Filter records - -```typescript -const user = await db.orm.User - .where((user) => user.email.eq("alice@example.com")) - .first(); -``` - -Use `.all()` when you expect multiple rows: - -```typescript -const users = await db.orm.User - .where((user) => user.createdAt.gte(new Date("2026-01-01"))) - .all(); -``` - -You can chain filters: - -```typescript -const posts = await db.orm.Post - .where((post) => post.title.ilike("%prisma%")) - .where((post) => post.createdAt.gte(new Date("2026-01-01"))) - .all(); -``` - -## Order, skip, and limit records - -```typescript -const newestUsers = await db.orm.User - .orderBy((user) => user.createdAt.desc()) - .take(10) - .all(); -``` - -Use an array when you need stable ordering by more than one field: - -```typescript -const feed = await db.orm.Post - .orderBy([(post) => post.createdAt.desc(), (post) => post.id.asc()]) - .skip(20) - .take(20) - .all(); -``` - -## Select fields - -Use `select` to return only the fields a view needs: - -```typescript -const users = await db.orm.User - .select("id", "email", "createdAt") - .take(20) - .all(); -``` - -## Include relations - -Use `include` to load relations from the same model query: - -```typescript -const users = await db.orm.User - .include("posts", (posts) => - posts - .select("id", "title", "createdAt") - .orderBy((post) => post.createdAt.desc()) - .take(5), - ) - .take(10) - .all(); -``` - -`include` works best for user-facing views that need a parent row and a small, bounded set of related rows. - -## Update records - -Filter before updating: - -```typescript -await db.orm.User - .where((user) => user.email.eq("alice@example.com")) - .update({ email: "alice@prisma.io" }); -``` - -For MongoDB collections, update helpers can also express operations such as pushing or pulling array values. - -## Delete records - -Filter before deleting: - -```typescript -await db.orm.User - .where((user) => user.email.eq("alice@prisma.io")) - .delete(); -``` - -Avoid unbounded mutations in application code. Keep destructive actions behind explicit filters and reviewable workflows. - -## Run ORM queries in transactions - -The Postgres runtime facade exposes a transaction helper: - -```typescript -await db.transaction(async (tx) => { - const id = crypto.randomUUID(); - - await tx.orm.User.create({ - id, - email: "alice@example.com", - createdAt: new Date(), - }); - - await tx.orm.Post.create({ - id: crypto.randomUUID(), - userId: id, - title: "Hello Prisma Next", - createdAt: new Date(), - }); -}); -``` - -The transaction commits when the callback resolves and rolls back when the callback throws. - -## When to switch to a lower-level API - -Stay with `db.orm` for normal model work. Switch to [`db.sql`](/orm/next/guides/building-queries-with-sql-dsl) when you need explicit PostgreSQL projections, computed columns, extension functions, or a query plan you want to review directly. diff --git a/apps/docs/content/docs/orm/next/index.mdx b/apps/docs/content/docs/orm/next/index.mdx index c4846f5b6c..93ffa61a93 100644 --- a/apps/docs/content/docs/orm/next/index.mdx +++ b/apps/docs/content/docs/orm/next/index.mdx @@ -1,68 +1,12 @@ --- title: What is Prisma Next? -description: Learn the Prisma Next ORM model, from contracts to query APIs, migrations, and extensions. +description: A look at Prisma Next, a ground-up rethink of Prisma that improves queries, extensibility, migrations, and AI-friendly workflows while keeping Prisma’s schema-first approach. url: /orm/next metaTitle: What is Prisma Next? -metaDescription: Learn the Prisma Next ORM model, from contracts to query APIs, migrations, and extensions. +metaDescription: A look at Prisma Next, a ground-up rethink of Prisma that improves queries, extensibility, migrations, and AI-friendly workflows while keeping Prisma’s schema-first approach. badge: early-access --- -Prisma Next is the next foundation for Prisma ORM. It keeps the familiar idea of modeling application data in one place, then makes that model more explicit: you emit a contract, load that contract at runtime, verify databases against it, and use it from more than one query API. +A look at Prisma Next, a ground-up rethink of Prisma that improves queries, extensibility, migrations, and AI-friendly workflows while keeping Prisma’s schema-first approach. -:::warning[Prisma Next is still in development] - -Prisma Next is not ready for production yet. Prisma ORM 7 is still the recommended choice for production applications today. - -::: - -## Why Prisma Next exists - -Prisma Next is built around a contract that can be checked by both tooling and runtime code. That gives you a clearer path for early-access workflows that need: - -- contract artifacts that can be generated, committed, and inspected -- database verification before code that depends on a contract is deployed -- model-oriented ORM queries and lower-level SQL plans in the same project -- extension packs for capabilities such as vector search, geospatial queries, and searchable encrypted columns - -## How Prisma Next fits together - -The ORM workflow has four main pieces: - -| Piece | What it does | -| --- | --- | -| Contract | The schema your application expects. You can author it in PSL or TypeScript. | -| Emitted artifacts | `contract.json` and `contract.d.ts`, generated with `prisma-next contract emit`. | -| Runtime client | The database-specific client that loads the emitted contract. | -| Query APIs | `db.orm` for model queries, `db.sql` for PostgreSQL plans, and `db.query` for MongoDB plans. | - -Database changes build on the same contract. You can initialize or reconcile a database directly with `db init` and `db update`, or create checked-in migration packages with `migration plan` and `migration apply`. - -## How it differs from Prisma ORM 7 - -| Prisma ORM 7 | Prisma Next | -| --- | --- | -| Generates a client from `schema.prisma`. | Emits an explicit contract used by tooling and runtime clients. | -| Uses Prisma Client as the main query API. | Provides `db.orm` plus lower-level query builders such as `db.sql`. | -| Migration workflows are centered on Prisma Migrate. | Migration and verification commands operate from the emitted contract. | -| Preview database capabilities are usually part of the main ORM surface. | Optional capabilities can be composed through extension packs. | - -## Typical workflow - -1. Define a contract in PSL or TypeScript. -2. Run `prisma-next contract emit`. -3. Use `db init`, `db update`, or `migration plan` to align the database. -4. Query through `db.orm`, `db.sql`, or `db.query`. -5. Run `db verify` in CI or before deployment to catch drift. - -## Start with the right section - -Use [Getting Started](/next) when you want setup instructions, including [`create-prisma@next`](/next/create-prisma). `create-prisma@next` scaffolds a complete application template and adds package scripts for contract emission, database initialization, verification, and migrations. - -Stay in this ORM section when you want to understand the Prisma Next model: - -- [Contract-first design](/orm/next/concepts/contract-first-design) -- [Schema definition and contract emission](/orm/next/concepts/schema-definition-and-contract-emission) -- [Query APIs](/orm/next/concepts/query-apis) -- [Extension packs](/orm/next/concepts/extension-packs) - -Use the [Prisma Next CLI reference](/cli/next) when you need exact command flags. +Read [The Next Evolution of Prisma ORM](https://www.prisma.io/blog/the-next-evolution-of-prisma-orm) for the full story. diff --git a/apps/docs/content/docs/orm/next/meta.json b/apps/docs/content/docs/orm/next/meta.json index 4ea134414c..3dc6aa8226 100644 --- a/apps/docs/content/docs/orm/next/meta.json +++ b/apps/docs/content/docs/orm/next/meta.json @@ -2,17 +2,5 @@ "title": "Next", "defaultOpen": true, "root": true, - "pages": [ - "---Introduction---", - "index", - - "---Core Concepts---", - "...concepts", - - "---Guides---", - "...guides", - - "---Extensions---", - "...extensions" - ] + "pages": ["index"] } diff --git a/apps/docs/next.config.mjs b/apps/docs/next.config.mjs index f89ccb2b99..82e2d4f01f 100644 --- a/apps/docs/next.config.mjs +++ b/apps/docs/next.config.mjs @@ -260,22 +260,27 @@ const config = { }, { source: "/orm/next/create-prisma", - destination: "/next/create-prisma", + destination: "/next/getting-started", + permanent: false, + }, + { + source: "/next/create-prisma", + destination: "/next/getting-started", permanent: false, }, { source: "/next/quickstart", - destination: "/next/create-prisma", + destination: "/next/quickstart/postgresql", permanent: false, }, { - source: "/next/quickstart/:path*", - destination: "/next/create-prisma", + source: "/next/prisma-postgres/quickstart", + destination: "/next/prisma-postgres/quickstart/prisma-next", permanent: false, }, { source: "/orm/next/quickstart/:path*", - destination: "/next/create-prisma", + destination: "/next/quickstart/:path*", permanent: false, }, { diff --git a/apps/docs/src/app/global.css b/apps/docs/src/app/global.css index 41692a91ba..59639b90e3 100644 --- a/apps/docs/src/app/global.css +++ b/apps/docs/src/app/global.css @@ -29,6 +29,162 @@ header &[data-search-full] { visibility: hidden !important; } +#prisma-next-docs.prisma-next-banner { + isolation: isolate; + overflow: hidden; + color: #f8fffd; + border-bottom: 1px solid color-mix(in oklab, #00ccb4 45%, #6385ff); + background: + linear-gradient(100deg, rgba(0, 204, 180, 0.32), transparent 28%), + linear-gradient(260deg, rgba(255, 188, 63, 0.28), transparent 30%), + linear-gradient(90deg, #061615 0%, #101936 36%, #25152d 68%, #081816 100%), + repeating-linear-gradient( + 115deg, + rgba(255, 255, 255, 0.14) 0, + rgba(255, 255, 255, 0.14) 1px, + transparent 1px, + transparent 18px + ); + background-position: + 0% 50%, + 100% 50%, + 0% 50%, + 0 0; + background-size: + 150% 100%, + 150% 100%, + 220% 100%, + 48px 48px; + box-shadow: + 0 8px 32px rgba(0, 204, 180, 0.16), + inset 0 1px 0 rgba(255, 255, 255, 0.12), + inset 0 -1px 0 rgba(0, 0, 0, 0.32); + animation: prisma-next-banner-flow 16s ease-in-out infinite alternate; +} + +#prisma-next-docs.prisma-next-banner::before, +#prisma-next-docs.prisma-next-banner::after { + content: ""; + position: absolute; + inset: 0; + pointer-events: none; +} + +#prisma-next-docs.prisma-next-banner::before { + background: + linear-gradient( + 90deg, + transparent 0%, + rgba(0, 204, 180, 0.28) 18%, + rgba(99, 133, 255, 0.44) 38%, + rgba(255, 188, 63, 0.4) 56%, + rgba(255, 111, 145, 0.28) 74%, + transparent 100% + ), + linear-gradient(90deg, #00ccb4, #6385ff 34%, #ffbc3f 68%, #ff6f91); + background-position: + -42rem 0, + 0 0; + background-repeat: no-repeat; + background-size: + 42rem 100%, + 100% 2px; + animation: prisma-next-banner-sweep 8s ease-in-out infinite; +} + +#prisma-next-docs.prisma-next-banner::after { + opacity: 0.48; + background: + linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.18), transparent), + repeating-linear-gradient( + 135deg, + transparent 0, + transparent 16px, + rgba(255, 255, 255, 0.16) 16px, + rgba(255, 255, 255, 0.16) 17px + ); + background-position: + -30% 0, + 0 0; + background-size: + 24rem 100%, + 32px 32px; + mix-blend-mode: screen; + animation: prisma-next-banner-grid 20s linear infinite; +} + +#prisma-next-docs .prisma-next-banner-content { + position: relative; + z-index: 1; +} + +#prisma-next-docs .prisma-next-banner-cta { + display: inline-flex; + align-items: center; + gap: 4px; + border-color: color-mix(in oklab, #00ccb4 48%, #ffffff); + color: #f8fffd; + background: linear-gradient(135deg, #05201d, #172036 60%, #2a2030); + box-shadow: + 0 4px 18px rgba(0, 204, 180, 0.22), + inset 0 1px 0 rgba(255, 255, 255, 0.18); +} + +#prisma-next-docs .prisma-next-banner-cta:hover { + color: #ffffff; + background: linear-gradient(135deg, #06302b, #1d2b52 58%, #3b243c); +} + +@keyframes prisma-next-banner-flow { + from { + background-position: + 0% 50%, + 100% 50%, + 0% 50%, + 0 0; + } + + to { + background-position: + 30% 50%, + 70% 50%, + 100% 50%, + 48px 0; + } +} + +@keyframes prisma-next-banner-sweep { + 0%, + 24% { + background-position: + -42rem 0, + 0 0; + } + + 68%, + 100% { + background-position: + calc(100% + 42rem) 0, + 0 0; + } +} + +@keyframes prisma-next-banner-grid { + to { + background-position: + 130% 0, + 32px 32px; + } +} + +@media (prefers-reduced-motion: reduce) { + #prisma-next-docs.prisma-next-banner, + #prisma-next-docs.prisma-next-banner::before, + #prisma-next-docs.prisma-next-banner::after { + animation: none; + } +} + @layer utilities { .glitch { position: relative; diff --git a/apps/docs/src/app/layout.tsx b/apps/docs/src/app/layout.tsx index 973197038b..8aae50af60 100644 --- a/apps/docs/src/app/layout.tsx +++ b/apps/docs/src/app/layout.tsx @@ -10,6 +10,7 @@ import Link from "next/link"; import Script from "next/script"; import { FontAwesomeScript as EclipseFA } from "@prisma/eclipse"; import { Banner } from "fumadocs-ui/components/banner"; +import { ArrowRightIcon } from "lucide-react"; const inter = Inter({ subsets: ["latin"], @@ -89,9 +90,9 @@ export default function Layout({ children }: { children: ReactNode }) { -
+
Prisma Next is in early access. Explore the next Prisma ORM workflow. @@ -100,10 +101,11 @@ export default function Layout({ children }: { children: ReactNode }) { href="/next" className={cn( buttonVariants({ variant: "secondary", size: "sm" }), - "h-7 shrink-0 whitespace-nowrap px-2 py-1 text-xs", + "prisma-next-banner-cta h-7 shrink-0 whitespace-nowrap px-2 py-1 text-xs", )} > Read the docs +
diff --git a/apps/docs/src/components/sidebar-badge-provider.tsx b/apps/docs/src/components/sidebar-badge-provider.tsx index 832dd2c50c..8e49943615 100644 --- a/apps/docs/src/components/sidebar-badge-provider.tsx +++ b/apps/docs/src/components/sidebar-badge-provider.tsx @@ -30,18 +30,36 @@ const BADGE_COLOR: Record = { deprecated: "warning", }; +function shouldHideSidebarBadge(url: string, badge: BadgeType | undefined) { + if (badge !== "early-access") { + return false; + } + + const docsPathname = url.replace(/^\/docs(?=\/|$)/, "") || "/"; + + return ( + docsPathname === "/next" || + docsPathname.startsWith("/next/") || + docsPathname === "/orm/next" || + docsPathname.startsWith("/orm/next/") || + docsPathname === "/cli/next" || + docsPathname.startsWith("/cli/next/") + ); +} + export const SidebarBadgeItem: FC<{ item: PageTree.Item }> = ({ item }) => { const badges = use(BadgeContext); const badge = badges[item.url] as BadgeType | undefined; + const visibleBadge = shouldHideSidebarBadge(item.url, badge) ? undefined : badge; return ( {item.name} - {badge && ( + {visibleBadge && ( diff --git a/apps/docs/src/lib/version.ts b/apps/docs/src/lib/version.ts index a94852ded0..cc4c2a8cc1 100644 --- a/apps/docs/src/lib/version.ts +++ b/apps/docs/src/lib/version.ts @@ -22,18 +22,41 @@ const LATEST_CLI_ROOT = "/cli"; const NEXT_CLI_ROOT = "/cli/next"; const NEXT_GETTING_STARTED_PATHS_BY_LATEST_PATH = new Map([ ["/", NEXT_GETTING_STARTED_ROOT], - ["/getting-started", NEXT_GETTING_STARTED_ROOT], + ["/getting-started", "/next/getting-started"], ["/prisma-orm", NEXT_GETTING_STARTED_ROOT], - ["/prisma-orm/quickstart/postgresql", "/next/create-prisma"], - ["/prisma-orm/quickstart/mongodb", "/next/create-prisma"], + ["/prisma-orm/quickstart/postgresql", "/next/quickstart/postgresql"], + ["/prisma-orm/quickstart/mongodb", "/next/quickstart/mongodb"], ["/prisma-orm/add-to-existing-project/postgresql", "/next/add-to-existing-project/postgresql"], ["/prisma-orm/add-to-existing-project/mongodb", "/next/add-to-existing-project/mongodb"], + ["/prisma-postgres", "/next/prisma-postgres/quickstart/prisma-next"], + ["/prisma-postgres/quickstart/prisma-orm", "/next/prisma-postgres/quickstart/prisma-next"], + [ + "/prisma-postgres/import-from-existing-database-postgresql", + "/next/prisma-postgres/import-from-existing-database-postgresql", + ], + [ + "/prisma-postgres/import-from-existing-database-mysql", + "/next/prisma-postgres/import-from-existing-database-mysql", + ], + ["/prisma-postgres/from-the-cli", "/next/prisma-postgres/from-the-cli"], ]); const LATEST_GETTING_STARTED_PATHS_BY_NEXT_PATH = new Map([ [NEXT_GETTING_STARTED_ROOT, "/"], - ["/next/create-prisma", "/"], + ["/next/getting-started", "/getting-started"], + ["/next/quickstart/postgresql", "/prisma-orm/quickstart/postgresql"], + ["/next/quickstart/mongodb", "/prisma-orm/quickstart/mongodb"], ["/next/add-to-existing-project/postgresql", "/prisma-orm/add-to-existing-project/postgresql"], ["/next/add-to-existing-project/mongodb", "/prisma-orm/add-to-existing-project/mongodb"], + ["/next/prisma-postgres/quickstart/prisma-next", "/prisma-postgres/quickstart/prisma-orm"], + [ + "/next/prisma-postgres/import-from-existing-database-postgresql", + "/prisma-postgres/import-from-existing-database-postgresql", + ], + [ + "/next/prisma-postgres/import-from-existing-database-mysql", + "/prisma-postgres/import-from-existing-database-mysql", + ], + ["/next/prisma-postgres/from-the-cli", "/prisma-postgres/from-the-cli"], ]); function normalizePathname(pathname: string) { diff --git a/apps/docs/src/lib/versioned-sidebar-tree.ts b/apps/docs/src/lib/versioned-sidebar-tree.ts index 6e7abdde15..23056cad90 100644 --- a/apps/docs/src/lib/versioned-sidebar-tree.ts +++ b/apps/docs/src/lib/versioned-sidebar-tree.ts @@ -45,7 +45,12 @@ function isGettingStartedVersionNode(node: TreeNode, version: Version) { const name = String(node.name ?? "").toLowerCase(); if (version === "next") { - return name === "next" || node.index?.url === "/next"; + return ( + name === "next" || + name === "prisma next" || + node.url === "/next" || + node.index?.url === "/next" + ); } return false;