Skip to content
6 changes: 3 additions & 3 deletions apps/docs/content/docs/(index)/full-stack-tutorial.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Check the Node.js version first: `node --version` must print 22.18 or newer on t

1. Scaffold: `npm create prisma@latest -- my-app --template hono --provider postgres --yes`. Then run `npx prisma@latest init` in `my-app` to confirm the Prisma agent skills the scaffold installed are current, and use them.
2. Read `module.ts` and `service.ts` first: the Composer module provisions the database and the service, and it is what `dev` and `deploy` operate on.
3. Build and run locally: `npm run build`, then start `npx prisma dev module.ts` in the background and wait until it prints the local URL. This provisions a local Prisma Postgres database and applies the contract; no DATABASE_URL is needed. Sample users are seeded on the app's first query. Verify with curl that the local URL's /users endpoint returns the seeded users, then stop `dev`.
3. Build and run locally: `npm run build`, then `npx prisma dev module.ts --detach`, which returns once the app answers and leaves it running. This provisions a local Prisma Postgres database and applies the contract; no DATABASE_URL is needed. Sample users are seeded on the app's first query. Verify that `curl "$(npx prisma dev url app)/users"` returns the seeded users, then run `npx prisma dev stop`.
4. Deploy: check `npx prisma auth whoami`; if I am not signed in, stop and ask me to run `npx prisma auth login` (it opens a browser). The scaffold already wrote the baseline migration under `migrations/app/`; note its directory name, which ends in `_init`. The `composer` section of the scaffold's `prisma.config.ts` already sets the deploy region, so do not add one. Then run `npx prisma deploy module.ts` and verify the live URL's /users endpoint with curl. The deploy creates the project and provisions the database from the module declaration; do not pass a DATABASE_URL.
5. Evolve the schema: add `role String @default("member")` to the User model in `src/prisma/contract.prisma`, run `npx prisma contract emit`, add `"role"` to the typed select and the returned object in `src/prisma/users.ts`, and plan the migration with `npx prisma migration plan --name add-user-role --from <the init migration directory>`. Then run `npm run build` and `npx prisma deploy module.ts` again, and verify the live /users now returns `role: "member"` with the same createdAt values as before.
```
Expand Down Expand Up @@ -192,10 +192,10 @@ npx prisma dev module.ts

`dev` provisions a local Prisma Postgres database, applies the contract to it, starts the service, and prints the app's local URL when everything is ready. No account, credentials, or connection string are involved; see [Local development](/local-development) for how the local platform works.

Sample users are seeded automatically the first time the app queries the database. Confirm the API serves the seeded rows. `dev` keeps running until you press Ctrl-C, so run the curl in a second terminal. `dev` also picks a free port and prints the URL, so use the one it printed if it differs from the `3000` shown here:
Sample users are seeded automatically the first time the app queries the database. Confirm the API serves the seeded rows. `dev` keeps running until you press Ctrl-C, so run the curl in a second terminal in the same directory. `dev` picks a free port for the service, and `prisma dev url app` prints the URL of the service named `app`, whichever port it got:

```bash
curl http://localhost:3000/users
curl "$(npx prisma dev url app)/users"
```

```json no-copy
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/docs/(index)/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ Compute runs apps declared with Prisma Composer: your server code plus a small T

1. Install `@prisma/composer` and `@prisma/composer-prisma-cloud`, and install `prisma` as a dev dependency. Do not pin `effect`: Composer pins it. Only if another dependency pins a different `effect` and `prisma.config.ts` fails with `CLI.CONFIG_UNREADABLE`, add the override from https://www.prisma.io/docs/composer/deploying#when-prismaconfigts-fails-on-an-effect-version-conflict. Then install the Composer skill with `npx prisma skills sync`, and use it.
2. Declare the app: a `service.ts` with `compute({ name, deps, build })`, a `module.ts` that provisions it, and a `prisma.config.ts` whose `composer` section lists the extensions and the state store (`definePrismaConfig` from `prisma/config`, `defineConfig as composer` from `@prisma/composer/config`). Read the port from `service.port()` and bind 0.0.0.0. Replace other `process.env` reads with the service input schema, binding credentials like DATABASE_URL with `envSecret`. Composer does not build: produce one self-contained entry file per service (for example `esbuild <server> --bundle --platform=node --format=esm --outfile=dist/server.mjs`), or use the framework build adapter (Next.js needs the `nextjs` adapter and `output: "standalone"`).
3. Verify locally: run the build, then `npx prisma dev module.ts`, and curl the printed local URL.
3. Verify locally: run the build, then `npx prisma dev module.ts --detach`, curl each service at the URL `npx prisma dev url <service>` prints, then run `npx prisma dev stop`.
4. Confirm I am signed in with `npx prisma auth whoami`; if not, stop and ask me to run `npx prisma auth login` (it opens a browser).
5. Deploy: run the build, then `npx prisma deploy module.ts` with the app's env values (like DATABASE_URL) exported in the shell; the first deploy copies input values up to the deployment. Verify the printed public URL with curl.

Expand Down
8 changes: 7 additions & 1 deletion apps/docs/content/docs/(index)/prisma-compute/deploy.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,13 @@ npm run build
npx prisma dev module.ts
```

`dev` prints the service's local URL; `curl` it and you get `Hello from Prisma Compute`. See [Local development](/local-development) for the local database, storage, and log workflow.
`dev` prints the service's local URL and keeps running. From a second terminal in the same directory, call the service through `prisma dev url`, which prints the URL of the service named `web`:

```bash
curl "$(npx prisma dev url web)"
```

You get `Hello from Prisma Compute`. See [Local development](/local-development) for the local database, storage, and log workflow.

From here the app grows by declaration: `deps: { db: rawPostgres() }` gives the service a [Prisma Postgres database](/composer/databases) (or `postgres(contract)` from `@prisma/composer-prisma-cloud/orm` for one typed by Prisma ORM), [`bucket()`](/composer/object-storage) gives it object storage, and a second service with a [typed contract](/composer/getting-started) turns cross-service calls into checked function calls. When the app runs locally, continue to [Deploy](#2-deploy).

Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/docs/(index)/prisma-orm/from-scratch.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ npm install @prisma/orm-postgres dotenv
npm install --save-dev prisma tsx typescript
```

`@prisma/orm-postgres` is the library your code imports, and `prisma` is the command-line tool. `dotenv` loads `.env`, `tsx` runs `index.ts` without a build step, and `typescript` 5.9 or newer is a peer dependency of `@prisma/orm-postgres`. So is `temporal-polyfill`, which npm installs for you; with Yarn, add it yourself. The two Prisma packages have different version numbers (for example, `prisma` 8.0.0-rc.23 and `@prisma/orm-postgres` 8.0.0-rc.18); that is normal, and any two `latest` versions work together.
`@prisma/orm-postgres` is the library your code imports, and `prisma` is the command-line tool. `dotenv` loads `.env`, `tsx` runs `index.ts` without a build step, and `typescript` 5.9 or newer is a peer dependency of `@prisma/orm-postgres`. So is `temporal-polyfill`, which npm installs for you; with Yarn, add it yourself. The two Prisma packages have different version numbers (for example, `prisma` 8.0.0-rc.24 and `@prisma/orm-postgres` 8.0.0-rc.18); that is normal, and any two `latest` versions work together.

## 2. Create the config file and `.env`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ installed
├─ dotenv
├─ prisma@latest (dev)
├─ @types/node (dev)
└─ @prisma/cli-engine@0.7.0 (dev)
└─ @prisma/cli-engine@0.9.0 (dev)

✔ Done. Open prisma-8.md to get started.
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ installed
├─ dotenv
├─ prisma@latest (dev)
├─ @types/node (dev)
└─ @prisma/cli-engine@0.7.0 (dev)
└─ @prisma/cli-engine@0.9.0 (dev)

✔ Done. Open prisma-8.md to get started.
```
Expand Down
2 changes: 2 additions & 0 deletions apps/docs/content/docs/cli/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ Use the default text output when running commands locally. Use `--json` in CI or
npx prisma db verify --db "$DATABASE_URL" --json
```

Piping a command does not switch it to JSON: without `--json`, standard output gets the command's plain data, such as one line per item of a list. See [Global flags](/cli/global-flags#output-formats).

For an AI agent that reads the output as text rather than parsing JSON, use `--format markdown`; see [Global flags](/cli/global-flags#output-formats).

Use `--no-interactive` for scripts that must never pause for user input. Use `--confirm <token>` to grant a consent prompt non-interactively. For example, [`db update`](/cli/db-update) asks for the database name before a destructive change.
Expand Down
9 changes: 7 additions & 2 deletions apps/docs/content/docs/cli/contract-print.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ npx prisma contract print [--output <path>]

| Option | What it does |
| --- | --- |
| `--output <path>` | Writes the PSL to this file. Without it, the command prints the PSL and writes no file. |
| `--format human` | Prints the PSL to standard output, so you can redirect it to a file. |
| `--output <path>` | Writes the PSL to this file. Without it, the command writes the PSL to standard output and writes no file. |
| `--config <path>` | Read this config file instead of `./prisma.config.ts`. |
| `--json` | Prints a machine-readable result, with the PSL in `psl.text`. |

Expand All @@ -35,6 +34,12 @@ npx prisma contract print --output ./src/prisma/contract.prisma
npx prisma contract print --json
```

Without `--output`, standard output gets only the PSL, while the status line goes to standard error. So you can redirect or pipe it:

```bash
npx prisma contract print > contract.v8.prisma
```

## What it writes

The file starts with `// use prisma-8`. When you point `contract` at the file and run `contract emit`, you get the same contract as before, with the same hashes, so the database needs no migration and no new `db sign`.
Expand Down
81 changes: 74 additions & 7 deletions apps/docs/content/docs/cli/dev.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,99 @@ title: dev
description: Bring a Composer application up entirely on this machine, with no cloud credentials.
url: /cli/dev
metaTitle: dev | Prisma CLI
metaDescription: Complete reference for the prisma dev command, which runs a Prisma Composer application locally against local emulators for Prisma Compute and Prisma Postgres.
metaDescription: Complete reference for the prisma dev command and its url and stop subcommands, which run a Prisma Composer application locally against local emulators for Prisma Compute and Prisma Postgres.
---

`dev` brings a [Prisma Composer](/composer) application up entirely on this machine. It takes an `<entry>` argument: the module whose default export is the application root, typically `module.ts`. The command runs credential-free against local emulators standing in for Prisma Compute and Prisma Postgres, watches the built output, and restarts a service when its build changes. See [Local development](/composer/local-development).
`dev` brings a [Prisma Composer](/composer) application up entirely on this machine. It takes an `<entry>` argument: the module whose default export is the application root, typically `module.ts`. The command runs credential-free against local emulators, programs on your machine that stand in for Prisma Compute, Prisma Postgres, and buckets. It watches the built output and restarts a service when its build changes. See [Local development](/composer/local-development).

`dev` and [`deploy`](/cli/deploy) are root-level commands of the unified Prisma CLI. There is no `composer` command group. Like `deploy`, `dev` runs your *built* output, so build first.
Like [`deploy`](/cli/deploy), `dev` runs your *built* output, so build first.

## Usage

```npm
npx prisma dev module.ts
npx prisma dev module.ts --fresh
npx prisma dev module.ts --detach
npx prisma dev url gateway
npx prisma dev stop
```

## Commands

| Command | Description |
| --- | --- |
| `dev <entry>` | Run the app on this machine and watch it for changes until you press `Ctrl-C` |
| `dev url <address>` | Print where a service, database, or bucket of the app answers locally |
| `dev stop` | Stop the app that `prisma dev` last ran from this directory |

`dev url`, `dev stop`, and `--detach` are in `prisma` since `8.0.0-rc.24`. Check your version with `npx prisma --version`.

## Flags

| Flag | Description |
| --- | --- |
| `--name <name>` | Override the application name for the local dev instance |
| `--fresh` | Destroy the dev stack and wipe the dev state directory before starting. In this release the flag fails for apps with a database; see [Local development](/composer/local-development#whats-local-vs-whats-real) for the manual reset |
| `--name <name>` | Run the app under this name instead of the name its root module declares. A different name gets its own local services, databases, and buckets |
| `--fresh` | Before starting, delete this app's local services, databases, and buckets, with their data. Other apps run from the same directory keep theirs |
| `--detach` | Return once every service answers, and leave the app running without watching for changes. `prisma dev stop` stops it. Use it in scripts, agents, and CI |

`dev` needs no credentials or environment variables; local runs never talk to the platform.

To tail the running application's merged logs, use the `log` operation of the [control API](/cli/deploy#the-control-api); the unified CLI has no `log` command.
When `dev` ends, by `Ctrl-C` or a failure, it stops the app's service processes and local Postgres servers. The emulators themselves keep running. Their data and ports are kept, so the next `dev` in this directory starts with the same ports and data.

With `--detach`, `dev` prints the same `ready` line and service URLs as a foreground run, then exits with code `0` and leaves the app running. It does not pick up rebuilds: run `prisma dev module.ts --detach` again after a build, or run `prisma dev module.ts` in the foreground, which takes over the running app and watches it. If a detached start fails before every service answers, `dev` stops the whole app and exits non-zero. `--detach` combines with `--fresh` and `--name`.

## dev url

`dev url <address>` prints the local URL of one node of the app that `prisma dev` runs from the current directory. A node is a service, database, or bucket in the app, and its address is its name in the app, with dots for a nested node, such as `catalog.database`.

```npm
npx prisma dev url gateway
```

```text no-copy
✔ The service gateway is running at http://localhost:3001
```

| Node | What `dev url` prints |
| --- | --- |
| Service | `http://localhost:<port>` |
| Database | Its connection string, with its local credentials |
| Bucket | Its S3 endpoint followed by `/<bucket>` |

That line is for you to read. When standard output is a pipe or a file, or `$(...)` captures it, `dev url` writes the URL alone, so a script can use it directly. Check the exit status before using it, so a failure does not run the next command with an empty URL:

```bash
url=$(npx prisma dev url gateway) && curl "$url"
```

Run it from the directory you ran `prisma dev` in, while the app runs. It starts nothing: it reads what the last `prisma dev` in this directory recorded. With `--json`, it prints `{ address, kind, url, state }` instead.

`dev url` prints a URL only for a node that is running, so something is listening at the URL it prints. Otherwise it fails with one of these codes:

| Code | Meaning |
| --- | --- |
| `DEV.NOT_STARTED_HERE` | `prisma dev` never ran in this directory |
| `DEV.ADDRESS_UNKNOWN` | The app has no node at that address. The message lists the addresses it has |
| `DEV.EMULATOR_UNREACHABLE` | The emulator that runs the node is not running. Run `prisma dev` again, which starts it |
| `DEV.NOT_RUNNING` | The node exists but is not running. Usually it was stopped, by `prisma dev stop`, by `prisma dev` ending, or by running another app in this directory. A service that keeps crashing is reported this way too, with the path of its log |

## dev stop

`dev stop` stops the app that `prisma dev` last ran from the current directory: its service processes and local database servers, as `Ctrl-C` does in a foreground `prisma dev`.

```npm
npx prisma dev stop
```

Use it to stop an app started with `--detach`, or when `prisma dev` was killed without a chance to stop the app. It lists the services and databases it stopped. When nothing of the app was running, it prints `Nothing of <app> was running.` and still exits with code `0`. Data and ports are kept, so the next `prisma dev` starts with the same ports and data. The emulators themselves keep running, because apps in other directories may use them.

## Global flags

The Prisma CLI's [global flags](/cli/global-flags) also apply: `--format`, `--json`, `--log-level`, `--verbose`, `--quiet`, `--yes`, `--confirm`, `--interactive`, `--color`, and `--config`.

To tail the running application's merged logs, use the `log` operation of the [control API](/cli/deploy#the-control-api); the unified CLI has no `log` command. To see every local emulator and what runs on it, use [`emulator list`](/cli/emulator).

## Next steps

- [Local development](/composer/local-development): warm restarts, `--fresh`, and what persists.
- [Local development](/composer/local-development): ports, what persists, and running in the background.
- [`deploy`](/cli/deploy): the same application, on Prisma Compute.
Loading
Loading