# Deploy your first app (/docs/prisma-compute/deploy) > For the complete Prisma documentation index, see [llms.txt](https://www.prisma.io/docs/llms.txt). A markdown version of any docs page is available by appending `.md` to its URL. Take a TypeScript app from your terminal to a live URL on Prisma Compute with Prisma Composer, starting from scratch or from an app you already have. Location: Prisma Compute > Deploy your first app [Prisma Compute](https://www.prisma.io/docs/compute) is serverless hosting for TypeScript apps. It runs your app right next to your Prisma Postgres database, so the trip from app to data stays short. Apps are declared and deployed with [Prisma Composer](https://www.prisma.io/docs/composer): you describe your app's services in TypeScript, and one command stands them up on Compute. By the end of this page you have a live URL. Start from wherever you are: * **You're starting from scratch.** [Declare a new app](#start-from-scratch) and run it locally, then deploy it. * **You already have an app.** [Add a declaration around your server code](#bring-an-app-you-already-have), then deploy it. Both paths meet in the same [deploy step](#2-deploy), because Composer treats every app the same way. A deployed app becomes a **project**, deploying with no flags targets **production**, and `--stage ` deploys an isolated copy of the whole app as a [preview branch](https://www.prisma.io/docs/compute/branching) of the same project. Local runs never talk to the platform, so you need credentials only when you deploy. For the platform's resource model, see [Compute](https://www.prisma.io/docs/compute#the-model). ## Prerequisites [#prerequisites] Before you start, make sure you have: * **Node.js 22.18 or newer on the 22 line, 24.11 or newer on the 24 line, or 26 or newer.** Composer hands your TypeScript entry file straight to Node, and running `.ts` files directly needs 22.18.0 or later. On older versions, Composer commands stop at `ERR_UNKNOWN_FILE_EXTENSION`. * **[Bun](https://bun.sh).** Prisma Compute runs deployed apps on Bun, so your server code targets it, and `bun build` produces the self-contained entry file a deploy needs. * **A [Prisma Data Platform account](https://pris.ly/pdp)**, free to create. You only need it for the deploy step; [local development](https://www.prisma.io/docs/local-development) runs without an account. ## 1. Get an app declared with Composer [#1-get-an-app-declared-with-composer] A Composer app is your server code plus a small declaration: what each service is called, how it is built, and what it depends on. Pick the path that matches your starting point. ### Start from scratch [#start-from-scratch] Set up the project as in [Composer getting started, step 1](https://www.prisma.io/docs/composer/getting-started#1-set-up-the-project): install `@prisma/composer` and `@prisma/composer-prisma-cloud`, install `prisma` as a dev dependency, and add the `tsconfig.json`. You do not pin `effect`: Composer pins it, and the override in [When prisma.config.ts fails on an effect version conflict](https://www.prisma.io/docs/composer/deploying#when-prismaconfigts-fails-on-an-effect-version-conflict) is only for a tree where another dependency hoists a different version. Then a minimal one-service app is four files. The **server** is ordinary Bun code. The one Composer-specific line reads the port from `service.port()`; bind `0.0.0.0`, because Compute routes external HTTP to the VM and a loopback-only listener would be unreachable: ```ts title="src/server.ts" import service from "./service.ts"; Bun.serve({ port: service.port(), hostname: "0.0.0.0", fetch: () => new Response("Hello from Prisma Compute"), }); ``` The **service declaration** names the service and points at your built output: ```ts title="src/service.ts" import node from "@prisma/composer/node"; import { compute } from "@prisma/composer-prisma-cloud"; export default compute({ name: "web", deps: {}, build: node({ module: import.meta.url, entry: "../dist/server.mjs" }), }); ``` The **root module** is the app: it provisions the service. The **deploy config** next to it is the `composer` section of `prisma.config.ts`, read only by the CLI: ```ts title="module.ts" import { module } from "@prisma/composer"; import webService from "./src/service.ts"; export default module("my-app", ({ provision }) => { provision(webService); }); ``` ```ts title="prisma.config.ts" import { defineConfig as composer } from "@prisma/composer/config"; import { nodeBuild } from "@prisma/composer/node/control"; import { prismaCloud, prismaState } from "@prisma/composer-prisma-cloud/control"; import { definePrismaConfig } from "prisma/config"; export default definePrismaConfig({ composer: composer({ 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](https://www.prisma.io/docs/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" { "scripts": { "build": "bun build src/server.ts --target=bun --outfile dist/server.mjs" } } ``` Now run the app on your machine. No account or credentials are involved: #### bun ```bash bun run build bunx prisma dev module.ts ``` #### pnpm ```bash pnpm run build pnpm prisma dev module.ts ``` #### yarn ```bash yarn build yarn prisma dev module.ts ``` #### npm ```bash npm run build npx prisma dev module.ts ``` `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](https://www.prisma.io/docs/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](https://www.prisma.io/docs/composer/databases) (or `postgres(contract)` from `@prisma/composer-prisma-cloud/orm` for one typed by Prisma ORM), [`bucket()`](https://www.prisma.io/docs/composer/object-storage) gives it object storage, and a second service with a [typed contract](https://www.prisma.io/docs/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 [#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](https://www.prisma.io/docs/composer/porting-an-app) covers that variant. **1. Install the Composer packages.** Same as [step 1 of the scratch path](https://www.prisma.io/docs/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](https://www.prisma.io/docs/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 `rawPostgres()`; S3 credentials become `bucket()`: ```ts title="src/api/service.ts" import node from "@prisma/composer/node"; import { compute, rawPostgres } from "@prisma/composer-prisma-cloud"; export default compute({ name: "api", deps: { db: rawPostgres() }, build: node({ module: import.meta.url, entry: "../../dist/api.mjs" }), }); ``` ```ts title="src/files/service.ts" import node from "@prisma/composer/node"; import { bucket, compute } from "@prisma/composer-prisma-cloud"; export default compute({ name: "files", deps: { store: bucket() }, build: node({ module: import.meta.url, entry: "../../dist/files.mjs" }), }); ``` **3. Provision everything in one module.** The root module owns the resources and wires them to the services; the deploy config next to it is the same one the scratch path uses: ```ts title="module.ts" import { module } from "@prisma/composer"; 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(rawPostgres({ name: "database" })); const store = provision(bucket({ name: "uploads" })); provision(apiService, { deps: { db } }); provision(filesService, { deps: { store } }); }); ``` **4. Port the environment reads.** This is the only change to your server code, and it is what makes every environment work without hand-wired configuration: 1. **The port**: read `service.port()` instead of `process.env.PORT`, and bind `0.0.0.0`. 2. **Dependency values**: read `service.load()` instead of connection-string and credential env vars. The Postgres dependency delivers `db.url` for whatever client you already use; the bucket delivers the standard S3 set. 3. **Everything else** (flags, regions, external URLs, third-party credentials) becomes the service's [input schema](https://www.prisma.io/docs/composer/service-input). ```ts title="src/api/server.ts (the changed lines)" import { SQL } from "bun"; 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, prepare: false }); Bun.serve({ port: service.port(), hostname: "0.0.0.0", fetch: handler }); ``` ```ts title="src/files/server.ts (the changed lines)" import service from "./service.ts"; // before: endpoint, bucket, and keys from four S3_* env vars const { store } = service.load(); const s3 = new Bun.S3Client({ endpoint: store.url, bucket: store.bucket, accessKeyId: store.accessKeyId, secretAccessKey: store.secretAccessKey, }); ``` **5. Build and verify locally.** Your build must produce one self-contained entry file per service; keep your own build if it already does, or use one `bun build --target=bun` line per service. Then run the whole declaration locally: #### bun ```bash bun run build bunx prisma dev module.ts ``` #### pnpm ```bash pnpm run build pnpm prisma dev module.ts ``` #### yarn ```bash yarn build yarn prisma dev module.ts ``` #### npm ```bash npm run build npx prisma dev module.ts ``` `dev` provisions a local Postgres and a local stand-in bucket with working credentials, and every service appears in the startup output with a local URL, so you can exercise the database and upload paths end-to-end before touching the platform. Then continue to [Deploy](#2-deploy): the same deploy command provisions the real database and bucket alongside the services. ## 2. Deploy [#2-deploy] Sign in once. This is the only interactive step, because it opens your browser: #### bun ```bash bunx prisma auth login ``` #### pnpm ```bash pnpm prisma auth login ``` #### yarn ```bash yarn prisma auth login ``` #### npm ```bash npx prisma auth login ``` The session is stored on your machine and every later command reads it, including commands a coding agent runs in your directory. Confirm it any time with `auth whoami`. In CI or a headless environment, set `PRISMA_SERVICE_TOKEN` and `PRISMA_WORKSPACE_ID` instead; see [Deploying](https://www.prisma.io/docs/composer/deploying#credentials). `deploy` does not build for you, so build first, then deploy: #### bun ```bash bun run build bunx prisma deploy module.ts ``` #### pnpm ```bash pnpm run build pnpm prisma deploy module.ts ``` #### yarn ```bash yarn build yarn prisma deploy module.ts ``` #### npm ```bash npm run build npx prisma deploy module.ts ``` 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 "" 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 ` when that happens. ## 3. Verify the deployment [#3-verify-the-deployment] A deploy finishes by printing what it made: each service, the platform resource it became, and its public URL: ```text no-copy my-app └─ web compute-service cps_abc123 https://xyz.ewr.prisma.build ``` Request the printed URL to confirm the app responds: ```bash curl https://xyz.ewr.prisma.build ``` You can also inspect everything in the [Console](https://pris.ly/pdp): projects, branches, services, deployments, and domains. ## 4. Ship changes and environments [#4-ship-changes-and-environments] Re-deploying is idempotent: build again, deploy again, and the platform applies the difference instead of recreating everything. That includes removals: delete a provision from your module and the next deploy deletes the resource; see [Removing resources](https://www.prisma.io/docs/composer/deploying#removing-resources). Production and previews are separated by stages: #### bun ```bash bunx prisma deploy module.ts # production bunx prisma deploy module.ts --stage staging # a persistent staging environment bunx prisma deploy module.ts --stage pr-42 # one environment per PR ``` #### pnpm ```bash pnpm prisma deploy module.ts # production pnpm prisma deploy module.ts --stage staging # a persistent staging environment pnpm prisma deploy module.ts --stage pr-42 # one environment per PR ``` #### yarn ```bash yarn prisma deploy module.ts # production yarn prisma deploy module.ts --stage staging # a persistent staging environment yarn prisma deploy module.ts --stage pr-42 # one environment per PR ``` #### npm ```bash npx prisma deploy module.ts # production npx prisma deploy module.ts --stage staging # a persistent staging environment npx prisma deploy module.ts --stage pr-42 # one environment per PR ``` A stage is a complete, isolated copy of the app: its own services, databases, and configuration, sharing only the code with production. In platform terms it is a [preview branch](https://www.prisma.io/docs/compute/branching) of the same project. Tearing a stage down needs the control API with service-token credentials, or a branch deletion in the Console; see [Destroying](https://www.prisma.io/docs/composer/deploying#destroying). [Deploying](https://www.prisma.io/docs/composer/deploying) covers CI, deploy state, and teardown in full. ## Hand it to your agent [#hand-it-to-your-agent] You can let a coding agent do the work. For an agent with its own credential, permission policy, and approval flow, see [Enroll your agent](https://www.prisma.io/docs/prisma-compute/agent-enrollment). For the simplest path, sign in once yourself ([step 2](#2-deploy)). The browser sign-in is the one step an agent can't do for you. After that, anything running in your environment inherits the session, including your agent. The `@prisma/composer` package ships an [agent skill](https://www.prisma.io/docs/cli/skills) that teaches your agent the installed version's API; [`npx prisma@latest init`](https://www.prisma.io/docs/cli/init) sets the project up so the skill stays in sync across upgrades. Paste this into your agent and fill in the blanks: ```text Build [what you want] as a Prisma Composer app and deploy it to Prisma Compute using `npx prisma@latest`. Notes: - After installing @prisma/composer, install its agent skill so you use the real API: `npx prisma skills sync` (the skill ships inside the package; run `npx prisma skills list` to confirm). - Before deploying, run `npx prisma auth whoami`; if I am not signed in, stop and ask me to run `npx prisma auth login` (it opens a browser). - Composer needs Node.js 22.18 or newer on the 22 line, 24.11 or newer on the 24 line, or 26 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: 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 ``` For example: ```text Build a Bun API with a /todos endpoint backed by an in-memory list as a Prisma Composer app and deploy it to Prisma Compute using `npx prisma@latest`. ``` ## What's next [#whats-next] * [Composer getting started](https://www.prisma.io/docs/composer/getting-started): the two-service version, with a typed contract between services. * [Databases](https://www.prisma.io/docs/composer/databases): give a service a Prisma Postgres database, plain or typed by a Prisma ORM contract. * [Deploying](https://www.prisma.io/docs/composer/deploying): stages, CI, deploy state, and teardown. * [Local development](https://www.prisma.io/docs/local-development): run the app, database, and storage on your machine with the runtime you deploy. ## Related pages - [`Enroll your coding agent: it works on preview branches and asks before changing production`](https://www.prisma.io/docs/prisma-compute/agent-enrollment): Give a coding agent its own Prisma credential and a permission policy you control, so it asks you before sensitive API actions and every request it makes is logged.