# Port an existing app (/docs/composer/porting-an-app) > 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. Bring an app you already have to Prisma Composer by declaring it, keeping your server code and your build. Location: Composer > Port an existing app Bringing an existing app to Composer does not mean rewriting it. The server code you already have stays the server, and you add a service declaration around it. This page covers the three common cases. ## Use with your agent [#use-with-your-agent] To delegate the port, run this from your project's root and hand the prompt to your coding agent: ```text Port this app to Prisma Composer. 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 `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. ``` ## A Node.js or Bun service [#a-nodejs-or-bun-service] Add a `service.ts` with `compute({ name, deps, build: node({ module, entry }) })` pointing `entry` at your built server file, then make three changes to the server itself: 1. **Read the port from `service.port()`**, never `process.env`, and bind `0.0.0.0`: ```ts Bun.serve({ port: service.port(), hostname: '0.0.0.0', fetch: handler }); ``` 2. **Replace every other `process.env` read.** Config and credentials become fields of the service's [input schema](https://www.prisma.io/docs/composer/service-input). Anything another service provides becomes a [dependency](https://www.prisma.io/docs/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: 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](https://www.prisma.io/docs/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](https://www.prisma.io/docs/composer/getting-started#5-build). ## A Next.js app [#a-nextjs-app] Use the `nextjs` build adapter instead of `node`. With `output: 'standalone'` set, `next build` is the whole build: ```ts title="src/service.ts" import nextjs from '@prisma/composer/nextjs'; import { rpc } from '@prisma/composer/service-rpc'; import { compute } from '@prisma/composer-prisma-cloud'; import { apiContract } from '../api/contract.ts'; export default compute({ name: 'web', deps: { api: rpc(apiContract) }, build: nextjs({ module: import.meta.url, appDir: '..' }), }); ``` ```ts title="next.config.ts" export default { output: 'standalone' }; ``` `prisma.config.ts` imports `prisma/config`, which resolves from your project's `node_modules`, so install the Prisma CLI as a dev dependency if the project does not have it yet: #### bun ```bash bun add --dev prisma ``` #### pnpm ```bash pnpm add -D prisma ``` #### yarn ```bash yarn add --dev prisma ``` #### npm ```bash npm install -D prisma ``` Then add `nextjsBuild()` from `@prisma/composer/nextjs/control` to the `extensions` of the `composer` section in `prisma.config.ts`: ```ts title="prisma.config.ts" import { defineConfig as composer } from '@prisma/composer/config'; import { nextjsBuild } from '@prisma/composer/nextjs/control'; 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(), nodeBuild(), nextjsBuild()], state: prismaState(), }), }); ``` Add `export const dynamic = 'force-dynamic'` to any page or server action that calls `service.load()`. The runtime environment does not exist at build time, and Next.js will not re-read it for prerendered routes. [`examples/storefront-auth`](https://github.com/prisma/composer/tree/main/examples/storefront-auth) in the Composer repository is a complete example of a ported app: a Next.js frontend calling a Bun API service that owns a Postgres. ## More than one service [#more-than-one-service] Port them into one `module.ts` and replace the URLs they used to reach each other with [contracts](https://www.prisma.io/docs/composer/services-and-contracts). The payoff is that the calls between services become typed, and every environment (production, stages, tests) gets the wiring for free. ## Verify the port [#verify-the-port] Build, then run the app locally before you deploy: #### 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 ``` Every service should appear in the startup output with a local URL. If a service fails at boot with a module-resolution error, its build left something un-inlined. Check that the entry file is self-contained. ## Next steps [#next-steps] * [Getting started](https://www.prisma.io/docs/composer/getting-started): the same shape, built from scratch. * [Deploying](https://www.prisma.io/docs/composer/deploying): take the ported app to production. ## Related pages - [`Apps and Modules`](https://www.prisma.io/docs/composer/apps-and-modules): How services, resources, and Modules compose into a Prisma App, and how provision() wires them together. - [`Building blocks`](https://www.prisma.io/docs/composer/building-blocks): Compose the ready-made cron, storage, and streams Modules instead of building scheduled jobs, blob storage, or event streams yourself. - [`Core concepts`](https://www.prisma.io/docs/composer/core-concepts): The ideas every Composer declaration and command builds on: services, resources, Modules, ports, contracts, stages, and the deploy model. - [`Databases`](https://www.prisma.io/docs/composer/databases): Give a service a Postgres database, either as a plain connection or typed by a Prisma ORM contract with managed migrations. - [`Deploying`](https://www.prisma.io/docs/composer/deploying): Deploy a Prisma App to production or an isolated stage, run it in CI, and tear environments down safely.