# 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 the Composer skill with `npx skills add prisma/composer`, 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.
6. Verify with `npx tsc --noEmit`, then build and run `npx prisma@latest composer 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: 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](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' };
```

Add `nextjsBuild()` from `@prisma/composer/nextjs/control` to the deploy config's `extensions`:

```ts title="prisma-composer.config.ts"
import { defineConfig } 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';

export default defineConfig({
  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@latest dev module.ts
```

#### pnpm

```bash
pnpm run build
pnpm dlx prisma@latest dev module.ts
```

#### yarn

```bash
yarn build
yarn dlx prisma@latest dev module.ts
```

#### npm

```bash
npm run build
npx prisma@latest 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 8 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.