Prisma 8 is here.Read the docs

Prisma Composer

A TypeScript framework for defining applications composed of multiple services and resources, and deploying them to Prisma Compute and Prisma Postgres.

With Prisma Composer, you describe your whole application in TypeScript: each service, plus whatever it depends on, such as other services, Prisma Postgres databases, scheduled jobs, object storage, and secrets. One deploy command then provisions the services on Prisma 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 for those paths.

What a Composer application is

A Composer application is a tree of services and resources. Each service declares the resources it needs, such as a database. Services call each other through typed contracts. Step through how the pieces relate:

A Prisma App: services, contracts, and resourcesStep 1 of 3
Prisma App · storeResourcesorders contractcatalog contractcatalog contractstorefrontNext.js serviceordersservicecatalogservicePrisma Postgresorders databasePrisma Postgrescatalog database
An application is one or more services. Each service is a process that Composer builds a declaration for: what it is called, how it is built, and what it depends on.

A minimal example

You declare a service as data instead of writing deployment scripts. The declaration below says the storefront service calls the catalog service's API and is built as a Next.js app:

src/storefront/service.ts
import nextjs from '@prisma/composer/nextjs';
import { rpc } from '@prisma/composer/service-rpc';
import { compute } from '@prisma/composer-prisma-cloud';
import { catalogContract } from '../catalog/contract.ts';

export default compute({
  name: 'storefront',
  deps: { catalog: rpc(catalogContract) },
  build: nextjs({ module: import.meta.url, appDir: '..' }),
});

At runtime, the service receives a typed client for each declared dependency from service.load(). The contract determines which methods that client exposes and their TypeScript types, and calling one is an ordinary async function call:

src/storefront/data.ts
import service from './service.ts';

const { catalog } = service.load();
const { products } = await catalog.listProducts({});

The root module ties the application together, wiring each declared dependency to the service or resource that provides it:

module.ts
import { module } from '@prisma/composer';
import catalogModule from './src/catalog/module.ts';
import ordersModule from './src/orders/module.ts';
import storefrontService from './src/storefront/service.ts';

export default module('store', ({ provision }) => {
  const catalog = provision(catalogModule);
  const orders = provision(ordersModule, { deps: { catalog: catalog.rpc } });
  provision(storefrontService, { deps: { catalog: catalog.rpc, orders: orders.rpc } });
});

TypeScript checks the wiring: a dependency bound to a producer with a different contract, a missing RPC handler, or a config value of the wrong shape is a compile error, not a failed deploy.

From declaration to deployment

npx prisma@latest deploy module.ts loads the root module, compares it with the deploy state stored for that environment, and creates or updates the services on Prisma Compute and the databases on Prisma Postgres. Re-running a deploy applies only the difference:

From declarations to running servicesStep 1 of 3
You writecomposer deploy provisionsinjected envService declarationscompute({ name, deps, build })Root modulemodule.ts wires depscomposer deploydiffs against stored statePrisma Computeone service eachPrisma Postgresone database eachservice.load()typed clients at runtime
Each service is declared as data: its name, its dependencies, and how it is built. The root module provisions the services and wires each dependency to the service or resource that provides it.

Core concepts

  • App: the complete deployable application, defined by the root module. Deployed as one Prisma project.
  • Service: a running application component, declared with compute(). Deployed as one Prisma Compute service.
  • Resource: something a service depends on that is not a service: a Prisma Postgres database, a bucket, or a secret.
  • Contract: the typed interface through which services communicate, written as Standard Schema definitions.
  • Module: a reusable unit that provisions services and resources behind a typed boundary, such as a service packaged with its own database.

Apps and Modules covers each in depth.

Design principles

Two choices shape the rest of the framework. First, application code does not read process.env or hardcode URLs. Dependencies arrive typed through service.load(), so production, an isolated stage, and a test all run the same code with different injected values. Second, Composer does not bundle or transform your code. You build with your own bundler, and the deploy assembles what you built.

Get started

Use Composer with an AI coding agent

Composer's declaration-based API works well with coding agents because mistakes fail the TypeScript compile instead of a deploy. The Composer skill ships inside the @prisma/composer package, so it always matches the version you installed. Before your agent writes Composer code, install it:

bunx prisma@latest skills sync

The prisma-composer skill documents the full authoring API, the CLI commands, and the first-party Modules for scheduled jobs, object storage, and event streams. It is one of several Prisma agent skills. Review the generated declarations like any other TypeScript: npx tsc --noEmit checks the wiring before you deploy.

Start with Apps and Modules for how services, resources, and Modules compose into an app, then Services and contracts for the typed RPC between them. When you're ready to run something, Local development works with no cloud credentials, and Deploying covers production, stages, and CI. Check Limitations before committing to a design.

On this page