diff --git a/apps/docs/content/docs/guides/meta.json b/apps/docs/content/docs/guides/meta.json index 64190da715..c3be0c49be 100644 --- a/apps/docs/content/docs/guides/meta.json +++ b/apps/docs/content/docs/guides/meta.json @@ -4,6 +4,7 @@ "icon": "NotebookTabs", "pages": [ "index", + "next", "frameworks", "runtimes", "deployment", diff --git a/apps/docs/content/docs/guides/next/frameworks/astro.mdx b/apps/docs/content/docs/guides/next/frameworks/astro.mdx new file mode 100644 index 0000000000..7b6526e9d3 --- /dev/null +++ b/apps/docs/content/docs/guides/next/frameworks/astro.mdx @@ -0,0 +1,73 @@ +--- +title: Astro +description: Set up Prisma Next in a Astro app with create-prisma, from scaffold to rendered data. +url: /guides/next/frameworks/astro +metaTitle: How to use Prisma Next with Astro +metaDescription: Scaffold a Astro project with Prisma Next and Prisma Postgres, initialize the database, seed it, and see your data, with tested commands. +--- + +## Introduction + +This guide shows you how to use Prisma Next in an Astro site. You scaffold a project that queries users during server rendering and exposes a JSON API route, initialize the schema, and see your data render. + +Every command below was run end to end against a live [Prisma Postgres](/postgres) database. + +## Quick start + +One command scaffolds the project with Prisma Next wired in: + +```npm +npx create-prisma@next --template astro --provider postgres +``` + +Pick Prisma Postgres at the database prompt to have a database created for you, or paste your own `DATABASE_URL`. + +## Prerequisites + +- [Node.js](https://nodejs.org) v20.19 or later +- A PostgreSQL connection string, or nothing at all: the scaffold can create the database for you + +## 1. Scaffold and enter the project + +```npm +npx create-prisma@next --template astro --provider postgres +cd my-app +``` + +The scaffold writes your connection string to `.env`, generates the Astro app with Prisma Next wired in, installs dependencies, and emits the contract your queries are type-checked against. + +## 2. Initialize and seed the database + +```npm +npm run db:init +npm run db:seed +``` + +```text no-copy +"summary": "Applied 5 operation(s) across 1 space(s), database signed" +Seeded 3 users. +``` + +`db:init` applies your schema (`src/prisma/contract.prisma`) to the database and signs it; the seed gives the first page something to show. + +## 3. Run and verify + +```npm +npm run dev +``` + +Open [http://localhost:4321](http://localhost:4321). The page lists the seeded users; `GET /api/users` returns them as JSON. + +## Where things live + +- `src/pages/index.astro`: queries users in the frontmatter and renders them +- `src/pages/api/users.ts`: a JSON API route backed by the same query +- `src/prisma/db.ts`: the Prisma Next client both import + +Model access is namespace-qualified on PostgreSQL: `db.orm.public.User`. The [Prisma Next overview](/orm/next) covers the contract-first model behind it. + +## Next steps + +- Change the schema in `src/prisma/contract.prisma`, then run `npm run contract:emit` and `npm run db:update`. +- [Learn the fundamentals](/orm/next/fundamentals/reading-data): filtering, sorting, pagination, and writes. +- [Read the Prisma Next overview](/orm/next) for the concepts behind contracts and typed queries. diff --git a/apps/docs/content/docs/guides/next/frameworks/elysia.mdx b/apps/docs/content/docs/guides/next/frameworks/elysia.mdx new file mode 100644 index 0000000000..f3dfa4c195 --- /dev/null +++ b/apps/docs/content/docs/guides/next/frameworks/elysia.mdx @@ -0,0 +1,91 @@ +--- +title: Elysia +description: Build an Elysia API on Prisma Next with the elysia template. +url: /guides/next/frameworks/elysia +metaTitle: How to use Prisma Next with Elysia +metaDescription: Scaffold an Elysia API backed by Prisma Next and Prisma Postgres, seed it, and serve users over HTTP, with tested commands and output. +--- + +## Introduction + +In this guide, you scaffold an Elysia API backed by Prisma Next, initialize and seed a PostgreSQL database, and serve data over HTTP. The `elysia` template generates the server, so most of the work is understanding the pieces. + +Every command and response below was run end to end against a live Prisma Postgres database. + +## Prerequisites + +- [Bun](https://bun.sh/) 1.1 or later (Elysia is Bun-first) +- A PostgreSQL connection string, or nothing at all: the scaffold can create a [Prisma Postgres](/postgres) database for you + +## 1. Scaffold the project + +```bash +bunx create-prisma@next create my-elysia-api --provider postgres --template elysia +``` + +Pick your database at the prompt. The template generates an Elysia server in `src/index.ts` with `GET /` and `GET /users` routes, the Prisma Next setup in `src/prisma/`, and package scripts for the database steps. + +```bash +cd my-elysia-api +``` + +## 2. Initialize and seed the database + +```bash +bun run db:init +bun run db:seed +``` + +```text no-copy +"summary": "Applied 5 operation(s) across 1 space(s), database signed" +Seeded 3 users. +``` + +:::note + +Scaffolded with an older `create-prisma` and seeing `Cannot read properties of undefined (reading 'where')`? Update `db.orm.User` to `db.orm.public.User` in `src/prisma/seed.ts` and `src/prisma/users.ts`. Current templates generate the qualified form. + +::: + +## 3. Run the server + +```bash +bun run dev +``` + +The server starts on port 3000 (set `PORT` to change it): + +```bash +curl http://localhost:3000/users +``` + +```json no-copy +[ + { "id": "1", "email": "alice@prisma.io", "username": "alice", "name": "Alice", "createdAt": "2026-07-07T08:51:14.054Z" }, + { "id": "2", "email": "bob@prisma.io", "username": "bob", "name": "Bob", "createdAt": "2026-07-07T08:51:14.089Z" }, + { "id": "3", "email": "carol@prisma.io", "username": "carol", "name": "Carol", "createdAt": "2026-07-07T08:51:14.122Z" } +] +``` + +The route handler is ordinary Elysia code calling an ordinary Prisma Next query; there is no framework adapter in between. To add write routes, follow the same pattern as the [Hono guide's POST route](/guides/next/frameworks/hono#4-add-a-post-route); the query code is identical. + +## Common gotchas + +:::warning + +In a long-running server, don't call `db.close()` in route handlers; the client's connection pool is shared across requests. Close it only on process shutdown. + +::: + +## Prompt your coding agent + +The scaffold installs Prisma Next skills for your coding agent. Prompts that map to this guide: + +- "Using the prisma-next-queries skill, add GET /users/:id that returns one user or a 404." +- "Add a POST /users route that creates a user from the request body." + +## Next steps + +- [Learn the fundamentals](/orm/next/fundamentals/reading-data): filtering, sorting, pagination, and writes. +- [Read the Prisma Next overview](/orm/next) for the concepts behind contracts and typed queries. +- [Use the Hono guide](/guides/next/frameworks/hono) for the tested POST route pattern. diff --git a/apps/docs/content/docs/guides/next/frameworks/hono.mdx b/apps/docs/content/docs/guides/next/frameworks/hono.mdx new file mode 100644 index 0000000000..e7623d4268 --- /dev/null +++ b/apps/docs/content/docs/guides/next/frameworks/hono.mdx @@ -0,0 +1,121 @@ +--- +title: Hono +description: Build a Hono API on Prisma Next with the hono template, then add your own routes. +url: /guides/next/frameworks/hono +metaTitle: How to use Prisma Next with Hono +metaDescription: Scaffold a Hono API backed by Prisma Next and Prisma Postgres, seed it, serve users over HTTP, and add a POST route, with tested commands and output. +--- + +## Introduction + +In this guide, you scaffold a Hono API backed by Prisma Next, initialize and seed a PostgreSQL database, serve data over HTTP, and add your own POST route. The `hono` template generates the server for you, so most of the work is understanding the pieces and extending them. + +Every command, route, and response below was run end to end against a live Prisma Postgres database. + +## Prerequisites + +- Node.js 24 or later, or [Bun](https://bun.sh/) (this guide uses Bun for speed; npm works the same) +- A PostgreSQL connection string, or nothing at all: the scaffold can create a [Prisma Postgres](/postgres) database for you + +## 1. Scaffold the project + +```bash +bunx create-prisma@next create my-hono-api --provider postgres --template hono +``` + +Pick your package manager and database at the prompts. The template generates a Hono server in `src/index.ts` with two routes (`GET /` and `GET /users`), the Prisma Next setup in `src/prisma/`, and package scripts for the database steps. + +```bash +cd my-hono-api +``` + +## 2. Initialize and seed the database + +```bash +bun run db:init +bun run db:seed +``` + +```text no-copy +"summary": "Applied 5 operation(s) across 1 space(s), database signed" +Seeded 3 users. +``` + +:::note + +Scaffolded with an older `create-prisma` and seeing `Cannot read properties of undefined (reading 'where')`? Update `db.orm.User` to `db.orm.public.User` in `src/prisma/seed.ts` and `src/prisma/users.ts`. Current templates generate the qualified form. + +::: + +## 3. Run the server + +```bash +bun run dev +``` + +The server starts on port 3000 (set `PORT` to change it). Check both routes: + +```bash +curl http://localhost:3000/users +``` + +```json no-copy +[ + { "id": "1", "email": "alice@prisma.io", "username": "alice", "name": "Alice", "createdAt": "2026-07-06T23:37:32.440Z" }, + { "id": "2", "email": "bob@prisma.io", "username": "bob", "name": "Bob", "createdAt": "2026-07-06T23:37:32.474Z" }, + { "id": "3", "email": "carol@prisma.io", "username": "carol", "name": "Carol", "createdAt": "2026-07-06T23:37:32.507Z" } +] +``` + +The route handler is ordinary Hono code calling an ordinary Prisma Next query; there is no framework adapter in between. + +## 4. Add a POST route + +Add a route that creates a user from the request body. Add this to `src/index.ts` above the `serve(...)` call: + +```ts title="src/index.ts" +app.post("/users", async (c) => { + const body = await c.req.json<{ email: string; name?: string }>(); + const { db } = await import("./prisma/db"); + const user = await db.orm.public.User.create({ + email: body.email, + name: body.name ?? null, + }); + return c.json(user, 201); +}); +``` + +Restart the server and create a user: + +```bash +curl -X POST http://localhost:3000/users \ + -H "content-type: application/json" \ + -d '{"email":"dev@prisma.io","name":"Dev"}' +``` + +```json no-copy +{ "createdAt": "2026-07-06T23:37:56.184Z", "email": "dev@prisma.io", "id": 4, "name": "Dev", "username": null } +``` + +`.create(...)` returns the full inserted record, database defaults included, so the response needs no second query. + +## Common gotchas + +:::warning + +In a long-running server, don't call `db.close()` in route handlers; the client's connection pool is shared across requests. Close it only on process shutdown. + +::: + +## Prompt your coding agent + +The scaffold installs Prisma Next skills for your coding agent. Prompts that map to this guide: + +- "Using the prisma-next-queries skill, add GET /users/:id that returns one user or a 404." +- "Add a Post model related to User, update the database, and expose GET /users/:id/posts." +- "Wrap the signup route's writes in a [transaction](/orm/next/fundamentals/transactions)." + +## Next steps + +- [Learn the fundamentals](/orm/next/fundamentals/reading-data): filtering, sorting, pagination, and writes. +- [Read the Prisma Next overview](/orm/next) for the concepts behind contracts and typed queries. diff --git a/apps/docs/content/docs/guides/next/frameworks/meta.json b/apps/docs/content/docs/guides/next/frameworks/meta.json new file mode 100644 index 0000000000..bc44218fe6 --- /dev/null +++ b/apps/docs/content/docs/guides/next/frameworks/meta.json @@ -0,0 +1,14 @@ +{ + "title": "Frameworks", + "defaultOpen": true, + "pages": [ + "nextjs", + "astro", + "nuxt", + "sveltekit", + "tanstack-start", + "nestjs", + "hono", + "elysia" + ] +} diff --git a/apps/docs/content/docs/guides/next/frameworks/nestjs.mdx b/apps/docs/content/docs/guides/next/frameworks/nestjs.mdx new file mode 100644 index 0000000000..bae676e1d6 --- /dev/null +++ b/apps/docs/content/docs/guides/next/frameworks/nestjs.mdx @@ -0,0 +1,83 @@ +--- +title: NestJS +description: Set up Prisma Next in a NestJS app with create-prisma, from scaffold to rendered data. +url: /guides/next/frameworks/nestjs +metaTitle: How to use Prisma Next with NestJS +metaDescription: Scaffold a NestJS project with Prisma Next and Prisma Postgres, initialize the database, seed it, and see your data, with tested commands. +--- + +## Introduction + +This guide shows you how to use Prisma Next in a NestJS API. You scaffold a project with a users controller backed by Prisma Next, initialize the schema, and query it over HTTP. + +Every command below was run end to end against a live [Prisma Postgres](/postgres) database. + +## Quick start + +One command scaffolds the project with Prisma Next wired in: + +```npm +npx create-prisma@next --template nest --provider postgres +``` + +Pick Prisma Postgres at the database prompt to have a database created for you, or paste your own `DATABASE_URL`. + +## Prerequisites + +- [Node.js](https://nodejs.org) v20.19 or later +- A PostgreSQL connection string, or nothing at all: the scaffold can create the database for you + +## 1. Scaffold and enter the project + +```npm +npx create-prisma@next --template nest --provider postgres +cd my-app +``` + +The scaffold writes your connection string to `.env`, generates the NestJS app with Prisma Next wired in, installs dependencies, and emits the contract your queries are type-checked against. + +## 2. Initialize and seed the database + +```npm +npm run db:init +npm run db:seed +``` + +```text no-copy +"summary": "Applied 5 operation(s) across 1 space(s), database signed" +Seeded 3 users. +``` + +`db:init` applies your schema (`src/prisma/contract.prisma`) to the database and signs it; the seed gives the first page something to show. + +## 3. Run and verify + +```npm +npm run dev +``` + +Query the API: + +```bash +curl http://localhost:3000/users +``` + +```json no-copy +[ + { "id": "1", "email": "alice@prisma.io", "username": "alice", "name": "Alice", "createdAt": "2026-07-07T09:44:19.201Z" } +] +``` + +## Where things live + +- `src/users.controller.ts`: the `GET /users` route +- `src/users.service.ts`: the service that runs the Prisma Next query +- `src/prisma/db.ts`: the Prisma Next client the service imports + +Model access is namespace-qualified on PostgreSQL: `db.orm.public.User`. The [Prisma Next overview](/orm/next) covers the contract-first model behind it. + +## Next steps + +- Change the schema in `src/prisma/contract.prisma`, then run `npm run contract:emit` and `npm run db:update`. +- [Learn the fundamentals](/orm/next/fundamentals/reading-data): filtering, sorting, pagination, and writes. +- [Read the Prisma Next overview](/orm/next) for the concepts behind contracts and typed queries. diff --git a/apps/docs/content/docs/guides/next/frameworks/nextjs.mdx b/apps/docs/content/docs/guides/next/frameworks/nextjs.mdx new file mode 100644 index 0000000000..d51a7a7b26 --- /dev/null +++ b/apps/docs/content/docs/guides/next/frameworks/nextjs.mdx @@ -0,0 +1,73 @@ +--- +title: Next.js +description: Set up Prisma Next in a Next.js app with create-prisma, from scaffold to rendered data. +url: /guides/next/frameworks/nextjs +metaTitle: How to use Prisma Next with Next.js +metaDescription: Scaffold a Next.js project with Prisma Next and Prisma Postgres, initialize the database, seed it, and see your data, with tested commands. +--- + +## Introduction + +This guide shows you how to use Prisma Next in a Next.js app. You scaffold a project where a server component queries your database, initialize the schema, and see your data render. + +Every command below was run end to end against a live [Prisma Postgres](/postgres) database. + +## Quick start + +One command scaffolds the project with Prisma Next wired in: + +```npm +npx create-prisma@next --template next --provider postgres +``` + +Pick Prisma Postgres at the database prompt to have a database created for you, or paste your own `DATABASE_URL`. + +## Prerequisites + +- [Node.js](https://nodejs.org) v20.19 or later +- A PostgreSQL connection string, or nothing at all: the scaffold can create the database for you + +## 1. Scaffold and enter the project + +```npm +npx create-prisma@next --template next --provider postgres +cd my-app +``` + +The scaffold writes your connection string to `.env`, generates the Next.js app with Prisma Next wired in, installs dependencies, and emits the contract your queries are type-checked against. + +## 2. Initialize and seed the database + +```npm +npm run db:init +npm run db:seed +``` + +```text no-copy +"summary": "Applied 5 operation(s) across 1 space(s), database signed" +Seeded 3 users. +``` + +`db:init` applies your schema (`src/prisma/contract.prisma`) to the database and signs it; the seed gives the first page something to show. + +## 3. Run and verify + +```npm +npm run dev +``` + +Open [http://localhost:3000](http://localhost:3000). The page lists the seeded users, rendered by a server component that calls Prisma Next directly. + +## Where things live + +- `src/app/page.tsx`: a server component that queries users and renders them +- `src/prisma/db.ts`: the Prisma Next client your components import +- `src/prisma/contract.prisma`: your schema + +Model access is namespace-qualified on PostgreSQL: `db.orm.public.User`. The [Prisma Next overview](/orm/next) covers the contract-first model behind it. + +## Next steps + +- Change the schema in `src/prisma/contract.prisma`, then run `npm run contract:emit` and `npm run db:update`. +- [Learn the fundamentals](/orm/next/fundamentals/reading-data): filtering, sorting, pagination, and writes. +- [Read the Prisma Next overview](/orm/next) for the concepts behind contracts and typed queries. diff --git a/apps/docs/content/docs/guides/next/frameworks/nuxt.mdx b/apps/docs/content/docs/guides/next/frameworks/nuxt.mdx new file mode 100644 index 0000000000..8b1fd1815b --- /dev/null +++ b/apps/docs/content/docs/guides/next/frameworks/nuxt.mdx @@ -0,0 +1,73 @@ +--- +title: Nuxt +description: Set up Prisma Next in a Nuxt app with create-prisma, from scaffold to rendered data. +url: /guides/next/frameworks/nuxt +metaTitle: How to use Prisma Next with Nuxt +metaDescription: Scaffold a Nuxt project with Prisma Next and Prisma Postgres, initialize the database, seed it, and see your data, with tested commands. +--- + +## Introduction + +This guide shows you how to use Prisma Next in a Nuxt app. You scaffold a project where a server API route queries your database and the page renders it, initialize the schema, and see your data. + +Every command below was run end to end against a live [Prisma Postgres](/postgres) database. + +## Quick start + +One command scaffolds the project with Prisma Next wired in: + +```npm +npx create-prisma@next --template nuxt --provider postgres +``` + +Pick Prisma Postgres at the database prompt to have a database created for you, or paste your own `DATABASE_URL`. + +## Prerequisites + +- [Node.js](https://nodejs.org) v20.19 or later +- A PostgreSQL connection string, or nothing at all: the scaffold can create the database for you + +## 1. Scaffold and enter the project + +```npm +npx create-prisma@next --template nuxt --provider postgres +cd my-app +``` + +The scaffold writes your connection string to `.env`, generates the Nuxt app with Prisma Next wired in, installs dependencies, and emits the contract your queries are type-checked against. + +## 2. Initialize and seed the database + +```npm +npm run db:init +npm run db:seed +``` + +```text no-copy +"summary": "Applied 5 operation(s) across 1 space(s), database signed" +Seeded 3 users. +``` + +`db:init` applies your schema (`src/prisma/contract.prisma`) to the database and signs it; the seed gives the first page something to show. + +## 3. Run and verify + +```npm +npm run dev +``` + +Open [http://localhost:3000](http://localhost:3000). The page lists the seeded users, fetched from the `/api/users` server route. + +## Where things live + +- `server/api/users.get.ts`: the server route that queries users +- `app/pages/index.vue`: the page that fetches and renders them +- `src/prisma/db.ts`: the Prisma Next client the server route imports + +Model access is namespace-qualified on PostgreSQL: `db.orm.public.User`. The [Prisma Next overview](/orm/next) covers the contract-first model behind it. + +## Next steps + +- Change the schema in `src/prisma/contract.prisma`, then run `npm run contract:emit` and `npm run db:update`. +- [Learn the fundamentals](/orm/next/fundamentals/reading-data): filtering, sorting, pagination, and writes. +- [Read the Prisma Next overview](/orm/next) for the concepts behind contracts and typed queries. diff --git a/apps/docs/content/docs/guides/next/frameworks/sveltekit.mdx b/apps/docs/content/docs/guides/next/frameworks/sveltekit.mdx new file mode 100644 index 0000000000..e28ca489cc --- /dev/null +++ b/apps/docs/content/docs/guides/next/frameworks/sveltekit.mdx @@ -0,0 +1,73 @@ +--- +title: SvelteKit +description: Set up Prisma Next in a SvelteKit app with create-prisma, from scaffold to rendered data. +url: /guides/next/frameworks/sveltekit +metaTitle: How to use Prisma Next with SvelteKit +metaDescription: Scaffold a SvelteKit project with Prisma Next and Prisma Postgres, initialize the database, seed it, and see your data, with tested commands. +--- + +## Introduction + +This guide shows you how to use Prisma Next in a SvelteKit app. You scaffold a project where a server load function queries your database, initialize the schema, and see your data render. + +Every command below was run end to end against a live [Prisma Postgres](/postgres) database. + +## Quick start + +One command scaffolds the project with Prisma Next wired in: + +```npm +npx create-prisma@next --template svelte --provider postgres +``` + +Pick Prisma Postgres at the database prompt to have a database created for you, or paste your own `DATABASE_URL`. + +## Prerequisites + +- [Node.js](https://nodejs.org) v20.19 or later +- A PostgreSQL connection string, or nothing at all: the scaffold can create the database for you + +## 1. Scaffold and enter the project + +```npm +npx create-prisma@next --template svelte --provider postgres +cd my-app +``` + +The scaffold writes your connection string to `.env`, generates the SvelteKit app with Prisma Next wired in, installs dependencies, and emits the contract your queries are type-checked against. + +## 2. Initialize and seed the database + +```npm +npm run db:init +npm run db:seed +``` + +```text no-copy +"summary": "Applied 5 operation(s) across 1 space(s), database signed" +Seeded 3 users. +``` + +`db:init` applies your schema (`src/prisma/contract.prisma`) to the database and signs it; the seed gives the first page something to show. + +## 3. Run and verify + +```npm +npm run dev +``` + +Open [http://localhost:5173](http://localhost:5173). The page lists the seeded users, loaded on the server by the `+page.server.ts` load function. + +## Where things live + +- `src/routes/+page.server.ts`: the server `load` function that queries users +- `src/routes/+page.svelte`: the page that renders them +- `src/prisma/db.ts`: the Prisma Next client the load function imports + +Model access is namespace-qualified on PostgreSQL: `db.orm.public.User`. The [Prisma Next overview](/orm/next) covers the contract-first model behind it. + +## Next steps + +- Change the schema in `src/prisma/contract.prisma`, then run `npm run contract:emit` and `npm run db:update`. +- [Learn the fundamentals](/orm/next/fundamentals/reading-data): filtering, sorting, pagination, and writes. +- [Read the Prisma Next overview](/orm/next) for the concepts behind contracts and typed queries. diff --git a/apps/docs/content/docs/guides/next/frameworks/tanstack-start.mdx b/apps/docs/content/docs/guides/next/frameworks/tanstack-start.mdx new file mode 100644 index 0000000000..8be51d4a64 --- /dev/null +++ b/apps/docs/content/docs/guides/next/frameworks/tanstack-start.mdx @@ -0,0 +1,73 @@ +--- +title: TanStack Start +description: Set up Prisma Next in a TanStack Start app with create-prisma, from scaffold to rendered data. +url: /guides/next/frameworks/tanstack-start +metaTitle: How to use Prisma Next with TanStack Start +metaDescription: Scaffold a TanStack Start project with Prisma Next and Prisma Postgres, initialize the database, seed it, and see your data, with tested commands. +--- + +## Introduction + +This guide shows you how to use Prisma Next in a TanStack Start app. You scaffold a project where a server function queries your database and a route loader feeds it to the page, initialize the schema, and see your data. + +Every command below was run end to end against a live [Prisma Postgres](/postgres) database. + +## Quick start + +One command scaffolds the project with Prisma Next wired in: + +```npm +npx create-prisma@next --template tanstack-start --provider postgres +``` + +Pick Prisma Postgres at the database prompt to have a database created for you, or paste your own `DATABASE_URL`. + +## Prerequisites + +- [Node.js](https://nodejs.org) v20.19 or later +- A PostgreSQL connection string, or nothing at all: the scaffold can create the database for you + +## 1. Scaffold and enter the project + +```npm +npx create-prisma@next --template tanstack-start --provider postgres +cd my-app +``` + +The scaffold writes your connection string to `.env`, generates the TanStack Start app with Prisma Next wired in, installs dependencies, and emits the contract your queries are type-checked against. + +## 2. Initialize and seed the database + +```npm +npm run db:init +npm run db:seed +``` + +```text no-copy +"summary": "Applied 5 operation(s) across 1 space(s), database signed" +Seeded 3 users. +``` + +`db:init` applies your schema (`src/prisma/contract.prisma`) to the database and signs it; the seed gives the first page something to show. + +## 3. Run and verify + +```npm +npm run dev +``` + +Open [http://localhost:3000](http://localhost:3000). The page lists the seeded users, provided by the route loader's server function. + +## Where things live + +- `src/routes/index.tsx`: the route: a `createServerFn` queries users, the loader passes them to the page +- `src/prisma/users.ts`: the query helper the server function calls +- `src/prisma/db.ts`: the Prisma Next client behind it + +Model access is namespace-qualified on PostgreSQL: `db.orm.public.User`. The [Prisma Next overview](/orm/next) covers the contract-first model behind it. + +## Next steps + +- Change the schema in `src/prisma/contract.prisma`, then run `npm run contract:emit` and `npm run db:update`. +- [Learn the fundamentals](/orm/next/fundamentals/reading-data): filtering, sorting, pagination, and writes. +- [Read the Prisma Next overview](/orm/next) for the concepts behind contracts and typed queries. diff --git a/apps/docs/content/docs/guides/next/index.mdx b/apps/docs/content/docs/guides/next/index.mdx new file mode 100644 index 0000000000..fd9af46f11 --- /dev/null +++ b/apps/docs/content/docs/guides/next/index.mdx @@ -0,0 +1,55 @@ +--- +title: Overview +description: Practical, step-by-step guides for building with Prisma Next, each one run end to end before it ships. +url: /guides/next +metaTitle: Prisma Next guides +metaDescription: Hands-on Prisma Next guides for frameworks and runtimes, with tested examples. More categories land incrementally, including migration, deployment, and testing. +--- + +Practical, step-by-step guides for building with Prisma Next. They mirror the structure of the [Prisma 7 guides](/guides), and every command in a published guide was run end to end against a live database before it landed here. + +Use the version dropdown in the sidebar to switch between these guides and the Prisma 7 guides. + +## Frameworks + +Each framework guide scaffolds a working app with `create-prisma`, initializes the database, and ends with your data rendering: + + + + + + + + + + + + +## Runtimes + + + + + + +## Coming as they land + +The remaining categories follow the [Prisma Next docs plan](https://linear.app/prisma-company/issue/DR-8689/docs-guides-incremental-migration-deployment-performance-testing) and land one guide at a time, each tested before it ships: + +- **Upgrading**: moving from Prisma 7, and between Prisma Next releases +- **Migrations**: down migrations, handling schema conflicts, and working with the migration graph +- **Deployment**: Vercel, Fly.io, AWS Lambda, Cloudflare Workers, Docker +- **Extensions**: using pgvector, using ParadeDB, building your own +- **Databases**: PostgreSQL tips, MongoDB tips, adding a new database +- **Patterns**: multi-tenant apps, soft deletes, audit logs, pagination at scale +- **Performance**: query limits in CI, reading query plans, indexing +- **Testing**: unit tests, integration tests, testing against the contract +- **Operations**: connection management, backups, health checks, zero-downtime migrations + +Until a Prisma Next guide exists for your topic, the [Prisma 7 guide](/guides) still applies to Prisma 7 projects, and the [Fundamentals section](/orm/next/fundamentals/reading-data) covers the query patterns any guide builds on. + +## Next steps + +- [Start with the quickstart](/next/quickstart/postgresql) if you don't have a Prisma Next project yet. +- [Learn the fundamentals](/orm/next/fundamentals/reading-data): reading, writing, relations, transactions, and advanced queries. +- [Read the Prisma Next overview](/orm/next) for the concepts behind contracts, typed queries, and migrations. diff --git a/apps/docs/content/docs/guides/next/meta.json b/apps/docs/content/docs/guides/next/meta.json new file mode 100644 index 0000000000..6f57759d5a --- /dev/null +++ b/apps/docs/content/docs/guides/next/meta.json @@ -0,0 +1,8 @@ +{ + "title": "Next", + "pages": [ + "index", + "frameworks", + "runtimes" + ] +} diff --git a/apps/docs/content/docs/guides/next/runtimes/bun.mdx b/apps/docs/content/docs/guides/next/runtimes/bun.mdx new file mode 100644 index 0000000000..a5a7fe90e2 --- /dev/null +++ b/apps/docs/content/docs/guides/next/runtimes/bun.mdx @@ -0,0 +1,96 @@ +--- +title: Bun +description: Scaffold a Prisma Next app with Bun, initialize your database, and run your first typed query. +url: /guides/next/runtimes/bun +metaTitle: How to use Prisma Next with Bun +metaDescription: Set up a Prisma Next project with Bun and Prisma Postgres, from scaffold to first query, with tested commands and real output. +--- + +## Introduction + +In this guide, you scaffold a Prisma Next project with Bun, initialize a PostgreSQL database from your schema, and run your first typed query. Bun runs TypeScript directly, so there is no build step anywhere in the flow. + +Every command and code sample below was run end to end against a live Prisma Postgres database. + +## Prerequisites + +- [Bun](https://bun.sh/) 1.1 or later (`bun --version`) +- A PostgreSQL connection string, or nothing at all: the scaffold can create a [Prisma Postgres](/postgres) database for you + +## 1. Scaffold the project + +Create the project with `create-prisma`. Pick Bun as the package manager when prompted, or pass everything up front: + +```bash +bunx create-prisma@next create my-bun-app --provider postgres --package-manager bun +``` + +When the prompt asks about the database, pick Prisma Postgres to have one created for you, or paste your own `DATABASE_URL`. The scaffold writes the connection string to `.env`, sets up `src/prisma/` with a starter schema, and installs dependencies with Bun. + +```bash +cd my-bun-app +``` + +## 2. Emit the contract and initialize the database + +Prisma Next compiles your schema (`src/prisma/contract.prisma`) into a contract that your queries are type-checked against. Emit it, then apply the schema to the database: + +```bash +bun run contract:emit +bun run db:init +``` + +`db:init` creates the tables and signs the database: + +```text no-copy +"summary": "Applied 5 operation(s) across 1 space(s), database signed" +``` + +If `db:init` reports that the contract file is missing, run `bun run contract:emit` first; the emit step generates `src/prisma/contract.json`. + +## 3. Write your first query + +Replace `src/index.ts` with a script that creates a user and reads every user back. Model access is namespace-qualified on PostgreSQL: `db.orm.public.User`, where `public` is the default schema. + +```ts title="src/index.ts" +import { db } from "./prisma/db"; + +// Create a user, then read every user back +const user = await db.orm.public.User.create({ + email: `ada+${Date.now()}@prisma.io`, + name: "Ada Lovelace", +}); +console.log(`created user ${user.email}`); + +const users = await db.orm.public.User.select("id", "email", "name").all(); +console.log(`there are now ${users.length} users`); + +await db.close(); +``` + +`await db.close()` at the end lets the script exit cleanly; without it, the connection pool keeps the process alive. + +## 4. Run it + +```bash +bun run dev +``` + +```text no-copy +created user ada+1783380852695@prisma.io +there are now 2 users +``` + +That is the whole loop: schema to contract, contract to database, typed queries against both. + +## Prompt your coding agent + +The scaffold installs Prisma Next skills for your coding agent. Prompts that map to this guide: + +- "Using the prisma-next-queries skill, add a script that lists the 10 newest users." +- "Add a Post model related to User, emit the contract, and update the database." + +## Next steps + +- [Learn the fundamentals](/orm/next/fundamentals/reading-data): filtering, sorting, pagination, and writes. +- [Read the Prisma Next overview](/orm/next) for the concepts behind contracts and typed queries. diff --git a/apps/docs/content/docs/guides/next/runtimes/deno.mdx b/apps/docs/content/docs/guides/next/runtimes/deno.mdx new file mode 100644 index 0000000000..be0aa9e9c2 --- /dev/null +++ b/apps/docs/content/docs/guides/next/runtimes/deno.mdx @@ -0,0 +1,98 @@ +--- +title: Deno +description: Run Prisma Next on Deno, including the import-extension and permission differences that matter. +url: /guides/next/runtimes/deno +metaTitle: How to use Prisma Next with Deno +metaDescription: Set up a Prisma Next project on Deno with Prisma Postgres, from scaffold to first query, with tested commands and real output. +--- + +## Introduction + +In this guide, you scaffold a Prisma Next project for Deno, initialize a PostgreSQL database, and run your first typed query. Deno runs TypeScript natively and installs npm packages on demand, so the flow is close to the [Bun guide](/guides/next/runtimes/bun) with two Deno-specific differences this guide calls out: explicit import extensions and permission flags. + +Every command and code sample below was run end to end against a live Prisma Postgres database. + +## Prerequisites + +- [Deno](https://deno.com/) 2.0 or later (`deno --version`) +- A PostgreSQL connection string, or nothing at all: the scaffold can create a [Prisma Postgres](/postgres) database for you + +## 1. Scaffold the project + +`create-prisma` supports Deno as a package manager choice: + +```bash +deno run -A npm:create-prisma@next create my-deno-app --provider postgres --package-manager deno +``` + +Pick Prisma Postgres at the database prompt to have a database created for you, or paste your own `DATABASE_URL`. The generated `package.json` scripts wrap every command in `deno run -A --env-file=.env`, so environment variables load without a dotenv import. + +```bash +cd my-deno-app +deno install +``` + +## 2. Emit the contract and initialize the database + +```bash +deno run -A --env-file=.env npm:prisma-next contract emit +deno run -A --env-file=.env npm:prisma-next db init +``` + +The first command compiles `src/prisma/contract.prisma` into the contract your queries are type-checked against. The second creates the tables and signs the database. + +The `-A` flag grants the permissions the CLI needs (network for the database, filesystem for the generated files). To scope permissions tighter, start from `--allow-net --allow-read --allow-write --allow-env` and adjust to your setup. + +## 3. Write your first query + +Replace `src/index.ts`. Two things to notice: Deno requires the `.ts` extension on relative imports, and model access is namespace-qualified on PostgreSQL (`db.orm.public.User`): + +```ts title="src/index.ts" +import { db } from "./prisma/db.ts"; + +// Create a user, then read every user back +const user = await db.orm.public.User.create({ + email: `grace+${Date.now()}@prisma.io`, + name: "Grace Hopper", +}); +console.log(`created user ${user.email}`); + +const users = await db.orm.public.User.select("id", "email", "name").all(); +console.log(`there are now ${users.length} users`); + +await db.close(); +``` + +If you see `Module not found "file:///…/src/prisma/db"`, the import is missing its `.ts` extension. Deno does not resolve relative imports without an extension. + +## 4. Run it + +```bash +deno task dev +``` + +```text no-copy +created user grace+1783380988819@prisma.io +there are now 3 users +``` + +## Common gotchas + +:::warning + +Deno reports `Unsupported compiler options in tsconfig.json` for a few options the scaffold sets for Node compatibility. The warning is harmless: Deno ignores those options and runs the code the same way. + +::: + +## Prompt your coding agent + +The scaffold installs Prisma Next skills for your coding agent. Prompts that map to this guide: + +- "Using the prisma-next-queries skill, add a Deno task that prints every user created in the last day." +- "Tighten the Deno permissions for this project from -A to an explicit allow list." + +## Next steps + +- [Learn the fundamentals](/orm/next/fundamentals/reading-data): filtering, sorting, pagination, and writes. +- [Read the Prisma Next overview](/orm/next) for the concepts behind contracts and typed queries. +- [Use the Bun guide](/guides/next/runtimes/bun) if you also target Bun; the flow is the same apart from the runtime differences above. diff --git a/apps/docs/content/docs/guides/next/runtimes/meta.json b/apps/docs/content/docs/guides/next/runtimes/meta.json new file mode 100644 index 0000000000..e44177cc17 --- /dev/null +++ b/apps/docs/content/docs/guides/next/runtimes/meta.json @@ -0,0 +1 @@ +{ "title": "Runtimes", "pages": ["bun", "deno"] } diff --git a/apps/docs/next.config.mjs b/apps/docs/next.config.mjs index f1f1fbfc13..d4b7dc7ed7 100644 --- a/apps/docs/next.config.mjs +++ b/apps/docs/next.config.mjs @@ -319,6 +319,34 @@ const config = { // SEO owner at cutover): /orm/prisma-client/queries/full-text-search, // /orm/prisma-client/queries/advanced/query-optimization-performance, // /orm/prisma-client/queries/excluding-fields. + // + // ── Guides URL cutover (DR-8689 / DR-8687) — DO NOT ENABLE YET ──────── + // Today: Prisma 7 guides live at /guides/* and Prisma Next guides at + // /guides/next/* (the "Guides version" dropdown switches between them). + // When Prisma Next becomes the default docs version ("/" becomes the + // Prisma Next docs and Prisma 7 moves to v7), the guides flip the same + // way: the Prisma 7 guide tree moves under /guides/v7, and the + // /guides/next tree is promoted to /guides. The redirects to enable at + // that cutover, kept here so the map builds up in one reviewable place: + // + // The /guides/next tree mirrors the Prisma 7 folder structure, so the + // promotion is one wildcard: + // { source: "/guides/next/:path*", destination: "/guides/:path*", permanent: false }, + // + // Park the Prisma 7 versions under /guides/v7 (only for guides that + // have a Prisma Next replacement; unconverted guides keep their URL): + // { source: "/guides/runtimes/bun", destination: "/guides/v7/runtimes/bun", permanent: false }, + // { source: "/guides/runtimes/deno", destination: "/guides/v7/runtimes/deno", permanent: false }, + // { source: "/guides/frameworks/nextjs", destination: "/guides/v7/frameworks/nextjs", permanent: false }, + // { source: "/guides/frameworks/astro", destination: "/guides/v7/frameworks/astro", permanent: false }, + // { source: "/guides/frameworks/nuxt", destination: "/guides/v7/frameworks/nuxt", permanent: false }, + // { source: "/guides/frameworks/sveltekit", destination: "/guides/v7/frameworks/sveltekit", permanent: false }, + // { source: "/guides/frameworks/tanstack-start", destination: "/guides/v7/frameworks/tanstack-start", permanent: false }, + // { source: "/guides/frameworks/nestjs", destination: "/guides/v7/frameworks/nestjs", permanent: false }, + // { source: "/guides/frameworks/hono", destination: "/guides/v7/frameworks/hono", permanent: false }, + // { source: "/guides/frameworks/elysia", destination: "/guides/v7/frameworks/elysia", permanent: false }, + // + // Each future guide conversion appends its pair here in the same PR. // ─────────────────────────────────────────────────────────────────────── ]; }, diff --git a/apps/docs/src/components/version-switcher.tsx b/apps/docs/src/components/version-switcher.tsx index 1c7b0369d6..42ec916fe4 100644 --- a/apps/docs/src/components/version-switcher.tsx +++ b/apps/docs/src/components/version-switcher.tsx @@ -6,11 +6,13 @@ import { ChevronDownIcon } from "lucide-react"; import { getCliVersionFromPathname, getGettingStartedVersionFromPathname, + getGuidesVersionFromPathname, getOrmVersionFromPathname, getVersionLabel, getVersionSwitchPathname, isCliVersionPathname, isGettingStartedVersionPathname, + isGuidesVersionPathname, LATEST_VERSION, type Version, } from "@/lib/version"; @@ -34,6 +36,7 @@ export function VersionSwitcher({ const router = useRouter(); const isGettingStartedVersion = isGettingStartedVersionPathname(pathname); const isCliVersion = isCliVersionPathname(pathname); + const isGuidesVersion = isGuidesVersionPathname(pathname); // Getting Started no longer has a version toggle: Prisma Next lives inline in the // getting-started sidebar as its own sections, so there is no "Docs version" dropdown. @@ -44,9 +47,10 @@ export function VersionSwitcher({ const detectedVersion = getGettingStartedVersionFromPathname(pathname) ?? getCliVersionFromPathname(pathname) ?? + getGuidesVersionFromPathname(pathname) ?? getOrmVersionFromPathname(pathname); const currentVersion = detectedVersion ?? null; - const usesScopedVersions = isGettingStartedVersion || isCliVersion; + const usesScopedVersions = isGettingStartedVersion || isCliVersion || isGuidesVersion; const visibleVersions = usesScopedVersions ? versions.filter((version) => version === LATEST_VERSION || version === "next") : versions; @@ -54,7 +58,9 @@ export function VersionSwitcher({ ? "Docs version" : isCliVersion ? "CLI version" - : "ORM version"; + : isGuidesVersion + ? "Guides version" + : "ORM version"; if (!currentVersion || !visibleVersions.includes(currentVersion)) { return null; diff --git a/apps/docs/src/lib/version.ts b/apps/docs/src/lib/version.ts index f19a63c1b8..484209e3a7 100644 --- a/apps/docs/src/lib/version.ts +++ b/apps/docs/src/lib/version.ts @@ -20,6 +20,8 @@ const DOCS_PREFIX = "/docs"; const NEXT_GETTING_STARTED_ROOT = "/next"; const LATEST_CLI_ROOT = "/cli"; const NEXT_CLI_ROOT = "/cli/next"; +const LATEST_GUIDES_ROOT = "/guides"; +const NEXT_GUIDES_ROOT = "/guides/next"; const NEXT_GETTING_STARTED_PATHS_BY_LATEST_PATH = new Map([ ["/", NEXT_GETTING_STARTED_ROOT], ["/getting-started", "/next/getting-started"], @@ -220,6 +222,62 @@ function isNextCliPathname(pathname: string) { return pathname === NEXT_CLI_ROOT || pathname.startsWith(`${NEXT_CLI_ROOT}/`); } +function isLatestGuidesPathname(pathname: string) { + return ( + pathname === LATEST_GUIDES_ROOT || + (pathname.startsWith(`${LATEST_GUIDES_ROOT}/`) && !isNextGuidesPathname(pathname)) + ); +} + +function isNextGuidesPathname(pathname: string) { + return pathname === NEXT_GUIDES_ROOT || pathname.startsWith(`${NEXT_GUIDES_ROOT}/`); +} + +function getGuidesSwitchPathname( + docsPathname: string, + targetVersion: Version, + availablePathnames: Iterable, +) { + if (targetVersion !== LATEST_VERSION && targetVersion !== "next") { + return getVersionRoot(targetVersion); + } + + const targetRoot = targetVersion === "next" ? NEXT_GUIDES_ROOT : LATEST_GUIDES_ROOT; + const currentRoot = isNextGuidesPathname(docsPathname) ? NEXT_GUIDES_ROOT : LATEST_GUIDES_ROOT; + const suffix = + docsPathname === currentRoot + ? "" + : docsPathname.startsWith(`${currentRoot}/`) + ? docsPathname.slice(currentRoot.length) + : ""; + const candidate = `${targetRoot}${suffix}`; + const available = getAvailablePathnameSet(availablePathnames); + + if (available.size === 0 || available.has(candidate)) { + return candidate; + } + + return targetRoot; +} + +export function getGuidesVersionFromPathname(pathname: string): Version | null { + const docsPathname = withoutDocsPrefix(pathname); + + if (isNextGuidesPathname(docsPathname)) { + return "next"; + } + + if (isLatestGuidesPathname(docsPathname)) { + return LATEST_VERSION; + } + + return null; +} + +export function isGuidesVersionPathname(pathname: string) { + return getGuidesVersionFromPathname(pathname) !== null; +} + function getAvailablePathnameSet(availablePathnames: Iterable) { return new Set( Array.from(availablePathnames, (availablePathname) => withoutDocsPrefix(availablePathname)), @@ -324,6 +382,12 @@ export function getVersionSwitchPathname( return getCliSwitchPathname(docsPathname, targetVersion, availablePathnames); } + const guidesVersion = getGuidesVersionFromPathname(docsPathname); + + if (guidesVersion) { + return getGuidesSwitchPathname(docsPathname, targetVersion, availablePathnames); + } + const currentVersion = getOrmVersionFromPathname(docsPathname); const targetRoot = getVersionRoot(targetVersion); @@ -353,7 +417,8 @@ export function getVersionedNavPathname(targetPathname: string, currentPathname: const isNextDocsPathname = getGettingStartedVersionFromPathname(currentPathname) === "next" || getOrmVersionFromPathname(currentPathname) === "next" || - getCliVersionFromPathname(currentPathname) === "next"; + getCliVersionFromPathname(currentPathname) === "next" || + getGuidesVersionFromPathname(currentPathname) === "next"; // Bare "/" redirects to /next, so route the Getting Started tab to the reachable // landing for the active version instead of the redirecting root. @@ -373,6 +438,10 @@ export function getVersionedNavPathname(targetPathname: string, currentPathname: return NEXT_CLI_ROOT; } + if (targetDocsPathname === LATEST_GUIDES_ROOT) { + return NEXT_GUIDES_ROOT; + } + return targetPathname; } diff --git a/apps/docs/src/lib/versioned-sidebar-tree.ts b/apps/docs/src/lib/versioned-sidebar-tree.ts index 23056cad90..a350490968 100644 --- a/apps/docs/src/lib/versioned-sidebar-tree.ts +++ b/apps/docs/src/lib/versioned-sidebar-tree.ts @@ -3,6 +3,7 @@ import { LATEST_VERSION, getCliVersionFromPathname, getGettingStartedVersionFromPathname, + getGuidesVersionFromPathname, getOrmVersionFromRoute, getOrmVersions, getVersionRoot, @@ -37,6 +38,10 @@ function isCliNode(node: TreeNode) { return node.type === "folder" && (node.name === "CLI" || node.index?.url === "/cli"); } +function isGuidesNode(node: TreeNode) { + return node.type === "folder" && (node.name === "Guides" || node.index?.url === "/guides"); +} + function isGettingStartedVersionNode(node: TreeNode, version: Version) { if (node.type !== "folder") { return false; @@ -70,6 +75,20 @@ function isCliVersionNode(node: TreeNode, version: Version) { return false; } +function isGuidesVersionNode(node: TreeNode, version: Version) { + if (node.type !== "folder") { + return false; + } + + const name = String(node.name ?? "").toLowerCase(); + + if (version === "next") { + return name === "next" || node.index?.url === "/guides/next"; + } + + return false; +} + function isVersionNode(node: TreeNode, version: Version) { if (node.type !== "folder") { return false; @@ -183,6 +202,40 @@ function filterCliSidebarTree(node: TreeNode, version: Version): TreeNode { }; } +function filterGuidesSidebarTree(node: TreeNode, version: Version): TreeNode { + const children = node.children?.map((child) => filterGuidesSidebarTree(child, version)); + + if (!children) { + return node; + } + + if (isGuidesNode(node)) { + const versionChildren = children.filter((child) => isGuidesVersionNode(child, "next")); + + if (version === "next") { + const selectedVersion = versionChildren.find((child) => isGuidesVersionNode(child, version)); + + if (selectedVersion?.children) { + return { + ...node, + index: selectedVersion.index ?? node.index, + children: selectedVersion.children, + }; + } + } + + return { + ...node, + children: children.filter((child) => !versionChildren.includes(child)), + }; + } + + return { + ...node, + children, + }; +} + function filterOrmSidebarTree(node: TreeNode, version: Version): TreeNode { const children = node.children?.map((child) => filterOrmSidebarTree(child, version)); @@ -257,6 +310,40 @@ function getGettingStartedSidebarTree(tree: TreeRootNode, version: Version): Tre }; } +function findGuidesNode(node: TreeNode): TreeNode | null { + if (isGuidesNode(node)) { + return node; + } + + for (const child of node.children ?? []) { + const guidesNode = findGuidesNode(child); + if (guidesNode) { + return guidesNode; + } + } + + return null; +} + +function getGuidesSidebarTree(tree: TreeRootNode, version: Version): TreeRootNode { + const filteredTree = filterGuidesSidebarTree(tree, version) as TreeRootNode; + + if (isGuidesNode(filteredTree)) { + return filteredTree; + } + + const guidesNode = findGuidesNode(filteredTree); + + if (!guidesNode) { + return filteredTree; + } + + return { + ...filteredTree, + children: [guidesNode], + }; +} + function getCliSidebarTree(tree: TreeRootNode, version: Version): TreeRootNode { const filteredTree = filterCliSidebarTree(tree, version) as TreeRootNode; @@ -293,6 +380,12 @@ export function getVersionedSidebarTree(tree: PageTree.Root, route?: string | st return getCliSidebarTree(tree as TreeRootNode, cliVersion) as PageTree.Root; } + const guidesVersion = typeof route === "string" ? getGuidesVersionFromPathname(route) : null; + + if (guidesVersion) { + return getGuidesSidebarTree(tree as TreeRootNode, guidesVersion) as PageTree.Root; + } + const versions = getOrmVersions(tree); const explicitVersions = versions.filter((version) => version !== LATEST_VERSION); const version = getOrmVersionFromRoute(route);