Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ That is the stack we want to build.

## Start building with Prisma Compute

Prisma Compute is the newest step toward that vision. It works with the coding agents you already use, including Claude, Codex, and Composer, and comes with Prisma Postgres and [Object Storage](https://www.prisma.io/docs/storage) so you can give an agent a real project, let it build against real infrastructure, and run what it made.
Prisma Compute is the newest step toward that vision. It works with the coding agents you already use, including Claude, Codex, and Cursor, and comes with Prisma Postgres and [Object Storage](https://www.prisma.io/docs/storage) so you can give an agent a real project, let it build against real infrastructure, and run what it made.

<Button asChild variant="ink" size="2xl">
<a href="https://console.prisma.io/?utm_source=blog&utm_medium=blog&utm_campaign=prisma-rebrand-2026&utm_content=launch-post">Start building in Prisma Console</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,6 @@ One prompt, and the agent reads the project, provisions a branch database, appli

Want the full walkthrough, from signing in to connecting GitHub for deploy-on-push? Read the [Compute quickstart](https://www.prisma.io/docs/compute/getting-started).

We're early and shipping fast, so tell us what breaks or feels rough in [the `prisma-compute` channel on our Discord](https://pris.ly/discord-compute).
We're early and shipping fast, so tell us what breaks or feels rough in the `prisma-compute` channel on [our Discord](https://pris.ly/discord).

Go build something.
23 changes: 13 additions & 10 deletions apps/docs/content/docs/(index)/prisma-compute/deploy.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,14 @@ import { definePrismaConfig } from "prisma/config";

export default definePrismaConfig({
composer: composer({
extensions: [prismaCloud(), nodeBuild()],
extensions: [prismaCloud({ region: "us-east-1" }), nodeBuild()],
state: prismaState(),
}),
});
```

The `region` is where the first deploy creates the project. Pick any region listed under [Known limitations](/compute/limitations#runtime), or leave it out and set `PRISMA_REGION` when you deploy; a project that already exists keeps its region.

You own the build; Composer assembles what you built. Add a build script that produces one self-contained file per service:

```json title="package.json"
Expand All @@ -100,23 +102,23 @@ 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.

From here the app grows by declaration: `deps: { db: postgres() }` gives the service a [Prisma Postgres database](/composer/databases), [`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).
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).

### Bring an app you already have

Porting an app does not mean rewriting it. Your server code stays the server, your build stays the build, and you add a declaration around them. The steps below port a two-service app, a notes API on Postgres and an uploads service on S3 credentials, to a Composer app that provisions its own database and bucket. For a Next.js service, use the `nextjs` build adapter with `output: "standalone"` instead; [Port an existing app](/composer/porting-an-app) covers that variant.

**1. Install the Composer packages.** Same as [step 1 of the scratch path](/composer/getting-started#1-set-up-the-project): install `@prisma/composer` and `@prisma/composer-prisma-cloud`, and install `prisma` as a dev dependency. Composer pins `effect` for you; if one of your existing dependencies pins a different `effect`, use the override in [When prisma.config.ts fails on an effect version conflict](/composer/deploying#when-prismaconfigts-fails-on-an-effect-version-conflict).

**2. Declare each service.** A `service.ts` next to each server names the service, declares what it consumes as dependencies, and points at your built output. A Postgres connection becomes `postgres()`; S3 credentials become `bucket()`:
**2. Declare each service.** A `service.ts` next to each server names the service, declares what it consumes as dependencies, and points at your built output. A Postgres connection becomes `rawPostgres()`; S3 credentials become `bucket()`:

```ts title="src/api/service.ts"
import node from "@prisma/composer/node";
import { compute, postgres } from "@prisma/composer-prisma-cloud";
import { compute, rawPostgres } from "@prisma/composer-prisma-cloud";

export default compute({
name: "api",
deps: { db: postgres() },
deps: { db: rawPostgres() },
build: node({ module: import.meta.url, entry: "../../dist/api.mjs" }),
});
```
Expand All @@ -136,12 +138,12 @@ export default compute({

```ts title="module.ts"
import { module } from "@prisma/composer";
import { bucket, postgres } from "@prisma/composer-prisma-cloud";
import { bucket, rawPostgres } from "@prisma/composer-prisma-cloud";
import apiService from "./src/api/service.ts";
import filesService from "./src/files/service.ts";

export default module("my-app", ({ provision }) => {
const db = provision(postgres({ name: "database" }));
const db = provision(rawPostgres({ name: "database" }));
const store = provision(bucket({ name: "uploads" }));
provision(apiService, { deps: { db } });
provision(filesService, { deps: { store } });
Expand All @@ -160,7 +162,7 @@ import service from "./service.ts";

// before: new SQL({ url: process.env.DATABASE_URL })
const { db } = service.load();
const sql = new SQL({ url: db.url, max: 1, idleTimeout: 10 });
const sql = new SQL({ url: db.url, max: 1, idleTimeout: 10, prepare: false });

Bun.serve({ port: service.port(), hostname: "0.0.0.0", fetch: handler });
```
Expand Down Expand Up @@ -204,7 +206,7 @@ npm run build
npx prisma deploy module.ts
```

The CLI creates a project named after your root module, provisions the services on Compute and any databases on Prisma Postgres, wires the dependencies, and starts everything. The project name identifies the app in your workspace: redeploying reuses the project this module created, and a same-name project whose hosted state the CLI cannot verify stops the command with `HostedStateBootstrapError`. Deploy under another name with `--name <unique-name>` when that happens.
The CLI creates a project named after your root module in the region from `prismaCloud({ region })` or `PRISMA_REGION` (without one, the first deploy stops with `project "<name>" does not exist yet and no deploy region is configured`), provisions the services on Compute and any databases on Prisma Postgres, wires the dependencies, and starts everything. The project name identifies the app in your workspace: redeploying reuses the project this module created, and a same-name project whose hosted state the CLI cannot verify stops the command with `HostedStateBootstrapError`. Deploy under another name with `--name <unique-name>` when that happens.

## 3. Verify the deployment

Expand Down Expand Up @@ -249,7 +251,8 @@ Notes:
- Composer needs Node.js 22.18 or newer, and server code targets Bun. Read the port with `service.port()` and bind 0.0.0.0. For a Next.js service, use the nextjs build adapter and set `output: "standalone"`.
- Composer does not build; produce one self-contained entry file per service (for example `bun build --target=bun`), then run it locally with `npx prisma dev module.ts` and verify each service's local URL responds.
- Deploy with `npx prisma deploy module.ts` and verify the printed public URL with curl.
- To give a service a database, declare `deps: { db: postgres() }` and build the client from the injected `db.url`; do not read connection strings from process.env.
- To give a service a database, declare `deps: { db: rawPostgres() }` (imported from @prisma/composer-prisma-cloud) and build the client from the injected `db.url`; do not read connection strings from process.env. For a database typed by Prisma ORM, use `postgres(contract)` from @prisma/composer-prisma-cloud/orm instead.
- A new project needs a region: set `prismaCloud({ region: "us-east-1" })` (or another region) in the `composer` section of prisma.config.ts, or set PRISMA_REGION, before the first deploy.
- Current docs: https://www.prisma.io/docs/composer.md and https://www.prisma.io/docs/prisma-compute/deploy.md
```

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.21 and `@prisma/orm-postgres` 8.0.0-rc.16); 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.21 and `@prisma/orm-postgres` 8.0.0-rc.17); that is normal, and any two `latest` versions work together.

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

Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/docs/cli/service.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ metaDescription: 'Learn how to manage Prisma Compute services, service versions,

Use `service` commands to manage the services in a project. A deploy produces a **version** of a service; one version is live at a time. Deploys start from [`deploy`](/cli/deploy) for a Composer app, from a git push once you [set up deploy on push](/compute/deploy-on-push), or from the [Console](https://pris.ly/pdp). The commands below inspect and manage services and the versions that already exist.

Commands are targeted by parameters, not by ambient state. A command that acts on a service takes the service as its first positional argument (`service show <service>`), with `PRISMA_SERVICE_ID` as the environment fallback; the argument wins when both are set. Scope with `--branch <name>` and `--project <id-or-name>`. There is no interactive picker: a missing target fails with a structured `SERVICE.TARGET_REQUIRED` error (exit 2) before any network call, even in an interactive terminal. Commands targeted by a globally unique version id (`service version promote|start|stop|delete <version-id>`) need no other context.
Commands are targeted by parameters, not by ambient state. A command that acts on a service takes the service as its first positional argument (`service show <service>`); the CLI does not read a service from the environment. Scope with `--branch <name>` and `--project <id-or-name>`. There is no interactive picker: a missing target fails with a structured `SERVICE.TARGET_REQUIRED` error (exit 2) before any network call, even in an interactive terminal. Commands targeted by a globally unique version id (`service version promote|start|stop|delete <version-id>`) need no other context.

## Usage

Expand Down
6 changes: 3 additions & 3 deletions apps/docs/content/docs/composer/apps-and-modules.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ A service declares everything about itself in one `compute()` call. It is pure d
```ts
compute({
name: 'auth', // the service's name in the app graph
deps: { db: postgres() }, // what it needs -> read via service.load()
deps: { db: rawPostgres() }, // what it needs -> read via service.load()
input: authInput, // its incoming config -> read via service.input()
build: node({ module: import.meta.url, entry: '../dist/server.mjs' }),
expose: { rpc: authContract }, // what it offers to other services
Expand Down Expand Up @@ -60,15 +60,15 @@ A Module declares its boundary (what it needs, what it offers) in the second arg

```ts title="src/auth/module.ts"
import { module, secret } from '@prisma/composer';
import { postgres } from '@prisma/composer-prisma-cloud';
import { rawPostgres } from '@prisma/composer-prisma-cloud';
import { authContract } from './contract.ts';
import authService from './service.ts';

export default module(
'auth',
{ secrets: { signingKey: secret() }, expose: { rpc: authContract } },
({ secrets, provision }) => {
const db = provision(postgres({ name: 'database' }));
const db = provision(rawPostgres({ name: 'database' }));
const service = provision(authService, {
id: 'service',
deps: { db },
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/content/docs/composer/databases.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ export default compute({
import { SQL } from 'bun';

const { db } = service.load();
const sql = new SQL({ url: db.url, max: 1, idleTimeout: 10 });
const sql = new SQL({ url: db.url, max: 1, idleTimeout: 10, prepare: false });
```

Those pool settings matter. Prisma Compute scales to zero and closes idle connections, so keep the pool small and reconnect-friendly. See [Deploying](/composer/deploying#production-behavior).
Those pool settings matter. Prisma Compute scales to zero and closes idle connections, so keep the pool small and reconnect-friendly. `prepare: false` turns off Bun's named prepared statements: the local Postgres that `npx prisma dev` runs shares one session across client connections, so after the pool reconnects, the first query fails with `prepared statement "..." already exists` unless prepared statements are off. See [Deploying](/composer/deploying#production-behavior).

The module that owns the database provisions it:

Expand Down
4 changes: 2 additions & 2 deletions apps/docs/content/docs/composer/deploying.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,10 @@ Fix it at whichever end is wrong: add the name to the outputs the producer retur

Behavior you will run into once the app is deployed, and what to do about it:

- **Compute scales to zero, and idle database connections get closed.** A long-lived client that treats a dropped connection as fatal will crash-loop through 502s. Keep the pool small and reconnect-friendly, and do not let an async error kill the process:
- **Compute scales to zero, and idle database connections get closed.** A long-lived client that treats a dropped connection as fatal will crash-loop through 502s. Keep the pool small and reconnect-friendly, turn off named prepared statements so a reconnect against the local `prisma dev` database does not fail with `prepared statement "..." already exists`, and do not let an async error kill the process:

```ts
const sql = new SQL({ url: db.url, max: 1, idleTimeout: 10 });
const sql = new SQL({ url: db.url, max: 1, idleTimeout: 10, prepare: false });
process.on('uncaughtException', (err) => console.error('uncaughtException', err));
process.on('unhandledRejection', (err) => console.error('unhandledRejection', err));
```
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/docs/composer/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ metaDescription: Prisma Composer lets you declare services, their contracts, and

With Prisma Composer, you describe your whole application in TypeScript: each service, plus whatever it depends on, such as other services, [Prisma Postgres](/postgres) databases, scheduled jobs, object storage, and secrets. One deploy command then provisions the services on [Prisma Compute](/compute), the databases on Prisma Postgres, and the authenticated connections between them.

You do not need Composer to deploy to Prisma Compute. If your application is a single service, you can deploy it to Compute directly. See [Deployments](/compute/deployments) for those paths.
The Prisma CLI's `deploy` command, the GitHub deploy action, and the Deploy Button all deploy a Composer module. You do not need Composer to deploy to Prisma Compute through the [REST API](/rest-api), though: it creates a deployment for a service and returns an upload URL for your built artifact, and tools such as [Alchemy](/compute/alchemy) deploy that way. See [Deployments](/compute/deployments) for every path.

:::info[Early Access]

Expand Down
6 changes: 3 additions & 3 deletions apps/docs/content/docs/composer/porting-an-app.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ To delegate the port, run this from your project's root and hand the prompt to y
```text
Port this app to Prisma Composer.

1. Install `@prisma/composer` and `@prisma/composer-prisma-cloud`, then install the Composer skill with `npx prisma@latest skills sync` (the skill ships inside the package; run `npx prisma@latest skills list` to confirm). Then read https://www.prisma.io/docs/composer/porting-an-app.md and follow it for this repository.
1. Install `@prisma/composer` and `@prisma/composer-prisma-cloud`, and install `prisma` as a dev dependency (the deploy config in `prisma.config.ts` imports `prisma/config`), then install the Composer skill with `npx prisma@latest skills sync` (the skill ships inside the package; run `npx prisma@latest skills list` to confirm). Then read https://www.prisma.io/docs/composer/porting-an-app.md and follow it for this repository.
2. Survey the repo before changing anything and report back: every deployable server, its runtime (Node, Bun, or Next.js), its build command and entry file, every `process.env` read, and any database it connects to. Ask me about anything ambiguous.
3. Declare each server as a service with `compute()`, using the `node` or `nextjs` build adapter as appropriate, and compose them in a single `module.ts`.
4. Replace the `process.env` reads: the listen port becomes `service.port()` bound to `0.0.0.0`, config and credentials become fields of the service input schema, and anything another service provides becomes a typed dependency. Replace the URLs services use to reach each other with contracts.
5. If the app talks to Postgres, declare `postgres()` as a dependency and build the existing client from the injected `db.url` instead of a connection-string variable.
5. If the app talks to Postgres, declare `rawPostgres()` (from `@prisma/composer-prisma-cloud`) as a dependency and build the existing client from the injected `db.url` instead of a connection-string variable.
6. Verify with `npx tsc --noEmit`, then build and run `npx prisma dev module.ts` and confirm every service boots with a local URL. Do not deploy; show me the diff first.
```

Expand All @@ -39,7 +39,7 @@ Add a `service.ts` with `compute({ name, deps, build: node({ module, entry }) })

2. **Replace every other `process.env` read.** Config and credentials become fields of the service's [input schema](/composer/service-input). Anything another service provides becomes a [dependency](/composer/services-and-contracts). If a value differs per stage (an app origin, an external URL), bind it with `envParam`. Bind a credential with `envSecret`.

3. **If it talks to Postgres**: declare `deps: { db: postgres() }` and build your existing client (`pg`, Bun's `SQL`, whatever you use today) from the injected `db.url` instead of a connection-string env var. See [Databases](/composer/databases).
3. **If it talks to Postgres**: declare `deps: { db: rawPostgres() }`, imported from `@prisma/composer-prisma-cloud`, and build your existing client (`pg`, Bun's `SQL`, whatever you use today) from the injected `db.url` instead of a connection-string env var. See [Databases](/composer/databases).

Your build must produce a self-contained entry file, with everything inlined except runtime built-ins. Keep your own build if it already does this. Otherwise, a one-line `bun build --target=bun` produces one. See [Getting started](/composer/getting-started#5-build).

Expand Down
Loading
Loading