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
71 changes: 53 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,48 @@
# Prisma Composer

**Prisma Composer** deploys multi-service TypeScript apps to Prisma Cloud
from a description you write in TypeScript. You declare each service and what
it depends on — other services, databases, schedules, secrets — compose them
into a **Prisma App**, and `prisma-composer deploy` provisions all of it:
Compute services, Prisma Postgres databases, the wiring between them. There
is no infrastructure configuration to write or maintain.
**The fastest, most reliable way to build an app with your agent.** Start from
scratch and deploy the whole thing — services, databases, and the wiring
between them — to Prisma Cloud in minutes.

It earns its keep when an app is more than one piece. A lone server is easy
to deploy anywhere; the work starts when the storefront needs the catalog's
URL, the catalog needs its database's connection string, the cron job needs
credentials, and every one of those has to be repeated per environment.
Composer makes each of those edges a typed declaration and derives the rest.
Prisma Composer is a TypeScript framework for apps made of more than one
piece. You declare each service and what it depends on — other services,
databases, schedules, secrets — compose them into a **Prisma App**, and
`prisma-composer deploy` provisions all of it. There is no infrastructure
configuration to write or maintain.

Two rules shape everything:
## Start with the skill

Composer is built to be driven by an agent, so the first thing to do is give
your agent the skill:

```sh
npx skills add prisma/composer --skill prisma-composer
```

That's the whole setup. Your agent now knows the entire API and arrives
prepped with the **building blocks** it can snap together — ready-made
Modules for scheduled jobs, blob storage, and event streams, alongside the
ones you write. Ask it for what you want ("a Next.js storefront calling an
orders API with its own Postgres, deployed to a staging stage") and let it
compose.

Three properties are why this works, rather than producing a plausible app
that doesn't run:

- **Modules snap together.** A capability arrives as a Module that owns its
own internals and exposes a typed port. Adding scheduled jobs or a blob
store is a couple of lines of composition — not an integration your agent
has to invent.
- **Everything is typechecked.** A dependency wired to the wrong producer, a
missing RPC handler, a config value of the wrong shape — none of it
compiles. Your agent's mistakes get caught by `tsc` in seconds, not by a
broken deploy ten minutes later.
- **Deploys are deterministic.** One command, no infrastructure config to
hallucinate, and re-running it converges instead of drifting.

The same material, written for humans, is in the [guides](#getting-started).

## Two rules shape everything

- **Your code never reaches for its environment.** No `process.env`, no URLs.
Every dependency arrives typed, through one call — which is also why any
Expand Down Expand Up @@ -119,15 +148,21 @@ Complete, deployable apps under [`examples/`](examples/):
| [storage](examples/storage/) | The S3-backed blob store module |
| [streams](examples/streams/) | Durable append-only event streams over storage |

## For agents
## Building blocks and extensions

A condensed version of the guides ships as an installable agent skill:
A **Module** is the unit of reuse: it owns its internals and exposes a typed
port, so composing one is a couple of lines and never an integration you have
to invent. Three ship inside `@prisma/composer-prisma-cloud` today — `cron`
(scheduled jobs), `storage` (S3-backed blobs), and `streams` (durable event
streams) — alongside the Modules you write yourself.

```sh
npx skills add prisma/composer --skill prisma-composer
```
An **extension** is a package that brings its own Modules, resources, or
deploy target. The convention is an npm package named `prisma-composer-*` —
that name is how you (and your agent) find one. The ecosystem is new: the
first-party set above is the whole catalogue today, and it's growing.

See [`skills/`](skills/).
The agent-facing version of the guides lives in [`skills/`](skills/) and
installs with `npx skills add prisma/composer --skill prisma-composer`.

## Design & internals

Expand Down
19 changes: 18 additions & 1 deletion docs/guides/building-an-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,11 @@ three characters (call a database `'database'`, not `'db'` — the wiring key
on the service side can still be `db`), and ids must be unique within their
module.

## The modules that ship with the framework
## The building blocks that ship with the framework

These are the Modules you compose instead of building the capability
yourself. Each owns its internals and hands you a typed port, so adding one
is a couple of lines:

| Import | What you get | Exposes |
| --- | --- | --- |
Expand Down Expand Up @@ -244,6 +248,19 @@ provision(cron({ schedule, runner: promotionsService }), {
[`examples/streams`](../../examples/streams/) show the other two, including
the streams module's secret binding.

### Where new blocks come from

An **extension** is a package that brings its own Modules, resources, or
deploy target — the same mechanism `@prisma/composer-prisma-cloud` itself
uses. The convention is an npm package named `prisma-composer-*`, which is
how you and your agent find one; an extension is installed like any
dependency and enters the deploy through the `extensions` array in
`prisma-composer.config.ts`.

The ecosystem is new. Today the three Modules above plus the ones you write
are the whole set, so treat `prisma-composer-*` as the place to look rather
than a catalogue that already has what you need.

## Config params

A param is a value you want to configure per environment without a redeploy
Expand Down
35 changes: 32 additions & 3 deletions docs/guides/getting-started.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,37 @@
# Getting started

This guide takes you from an empty directory to a two-service app running on
Prisma Cloud. Along the way you'll meet every core idea once: a contract, a
service, a root module, a build, a deploy. At the end there's a section on
## First: give your agent the skill

Composer is built to be driven by an agent, and this is the whole setup:

```sh
npx skills add prisma/composer --skill prisma-composer
```

Your agent now knows the entire API and arrives prepped with the building
blocks it can compose — the ready-made Modules for scheduled jobs, blob
storage, and event streams, plus the ones you write. From there you describe
what you want ("a Next.js storefront calling an orders API with its own
Postgres, deployed to a staging stage") and it composes the app; you review
TypeScript, not YAML.

Do this even if you intend to write every line yourself. It costs one command,
and it stops your agent inventing an API that doesn't exist the first time you
ask it for help.

It works because of three properties you'll see throughout this guide:
capabilities arrive as **Modules** that snap together instead of integrations
you assemble; **the compiler checks the wiring**, so a mistake fails `tsc` in
seconds rather than a deploy ten minutes later; and **the deploy is
deterministic** — one command, no infrastructure config, and re-running it
converges instead of drifting.

## The rest of this guide

The point of what follows is that you can read what your agent writes. It
takes you from an empty directory to a two-service app running on Prisma
Cloud, meeting every core idea once: a contract, a service, a root module, a
build, a deploy. At the end there's a section on
[porting an app you already have](#porting-an-existing-app).

The app is deliberately tiny — a `quotes` API and a public `gateway` that
Expand Down
33 changes: 27 additions & 6 deletions skills/prisma-composer/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ description: >-
How to write, test, and deploy an app with Prisma Composer
(`@prisma/composer`): declare services with `compute()` and typed
dependencies, define RPC contracts, compose Modules, read config and
secrets, use the shared cron/storage/streams modules, test with
secrets, compose the ready-made cron/storage/streams Modules, find
extensions (npm packages named `prisma-composer-*`), test with
`mockService`/`bootstrapService`, and deploy with `prisma-composer deploy`
(stages, destroy). Use when building a Prisma App, wiring a service
dependency, adding a Postgres database, writing tests for composed
services, or deploying/tearing down an environment. Triggers on
dependency, adding a Postgres database, adding scheduled jobs / blob
storage / event streams, writing tests for composed services, or
deploying/tearing down an environment. Triggers on
"prisma composer", "@prisma/composer", "prisma app", "compute()",
"service.load()", "module()", "contract()", "mockService",
"bootstrapService", "prisma-composer deploy", "--stage",
"prisma-composer destroy".
"prisma-composer destroy", "prisma-composer-".
---

# Writing apps with Prisma Composer
Expand All @@ -30,6 +32,15 @@ The framework never bundles or transforms your code. You build your app
(`tsdown`, `next build`); `prisma-composer deploy` assembles the built output
and provisions it on Prisma Cloud (Compute + Prisma Postgres).

Two things make building here fast and hard to get wrong — lean on both:

- **Compose before you write.** Reach for an existing Module (below) before
implementing a capability yourself; wiring one in is a couple of lines.
- **The compiler checks the wiring.** A dependency wired to the wrong
producer, a missing RPC handler, a config value of the wrong shape — all of
it fails `tsc`, not the deploy. Typecheck, then build, then deploy; don't
reach for the cloud to find out whether the app is correct.

Two packages, and only two, appear in your `package.json`:

| Package | Provides |
Expand Down Expand Up @@ -265,16 +276,26 @@ it an explicit `id`.
A module can also declare boundary `deps` — inputs the parent wires exactly as
it would wire a service's. The consumer never sees the module's internals.

### Shared modules
### The building blocks you can compose

First-party Modules ship under `@prisma/composer-prisma-cloud`:
Modules are the building blocks: provision one, wire its exposed port, and
you're done — you never reimplement what a Module already owns. The
first-party set ships inside `@prisma/composer-prisma-cloud`. It's small, and
growing:

| Import | What it provisions | Exposes |
| --- | --- | --- |
| `cron` from `/cron` | An always-on scheduler firing your schedule at your runner service | nothing |
| `storage` from `/storage` | An S3-backed blob store (own Postgres + minted credentials) | `store` |
| `streams` from `/streams` | Durable append-only event streams over a `store` | `streams` |

**Finding more.** A Composer extension — a package that brings its own
Modules, resources, or deploy target — is published on npm under the name
`prisma-composer-*`. That name is the convention, so it's how you look for
one. The ecosystem is new: today the blocks above plus the app Modules you
write are the whole set, so don't reach for a `prisma-composer-*` package
without checking that it actually exists on npm first.

Cron end to end — the schedule is one source of truth; `serveSchedule` is
exhaustive over its job ids at compile time:

Expand Down