# Infrastructure as effects

> For agents: start with the [agent guide](https://ratstack.sh/llms.txt). Every page is Markdown by default; add `Accept: text/html` for HTML.

New on /news: [Effect Office Hours 52 with Resonate HQ](/news).

<picture>
<source media="(max-width: 640px)" srcset="/lore/infrastructure-as-effects/portrait.svg" width="600" height="1290" />
<img src="/lore/infrastructure-as-effects/landscape.svg" width="1200" height="720" alt="One Effect program holds three lanes. A contract projects to command line, HTTP, MCP tools, browser RPC and code mode. Code requires bindings, which declare resources. Plan, review and deploy run in order. The compiler checks these relationships before deployment." />
</picture>

Sam relates runtime clients, business logic, infrastructure policies, and deployed resources in [one typed program](/lore/cafe-stack).
The compiler can check these relationships before deployment.

## Contract → surfaces

A [contract](/lore/one-capability-every-surface) defines shared input, output, failures, and metadata.
Projections turn registered capabilities into command line, HTTP, MCP tools, browser RPC, and code mode surfaces.
Each surface derives its input and failure definitions from the same schemas.

## Code → bindings → resources

A client operation can imply a policy requirement supplied when the function is built.
Sam describes [bindings](/lore/bindings) as permissions and environment variables together at [37:09](https://youtu.be/YEn4A7XxgF4?t=2229).
An Alchemy Layer can declare the cloud resources behind a service.
The [Stack](/lore/effect-office-hours-27-alchemy-infrastructure-as-effects) declares cloud resources.

## Worked example: a D1 Layer

In the database [cartridge](/lore/cartridges), `makeD1Vendor` declares SQLite migrations and a D1 database.
The database declaration receives those migrations through its `migrations` option.

packages/database/src/d1.ts at c5e4fc13d7740952fcb1646b29a5cdd1b43001a8; lines 17-29; highlighted none. Title: Declare the schema and database.

```typescript
const makeD1Vendor = Effect.fn("makeD1Vendor")(function* makeD1Vendor({
  id,
}: D1Options) {
  const migrations = yield* Drizzle.Schema(`${id}-d1-schema`, {
    dialect: "sqlite",
    out: databaseMigrationDirectory("d1"),
    schema: databaseSchemaFile("d1"),
  });

  const database = yield* Cloudflare.D1.Database(`${id}-d1`, { migrations });

  return { _tag: "D1" as const, database };
});
```

`D1(options)` builds the Layer below.
It combines `RunLogLayer(vendor)` with the `DatabaseVendor` service and provides `QueryDatabaseBinding`.
The package keeps its database declaration and service construction together.

packages/database/src/d1.ts at c5e4fc13d7740952fcb1646b29a5cdd1b43001a8; lines 34-44; highlighted none. Title: Compose services and supply the query binding.

```typescript
export const D1 = (options: D1Options) =>
  Layer.unwrap(
    Effect.gen(function* buildD1Layer() {
      const vendor = yield* makeD1Vendor(options);

      return Layer.mergeAll(
        RunLogLayer(vendor),
        Layer.succeed(DatabaseVendor, vendor)
      );
    })
  ).pipe(Layer.provide(Cloudflare.D1.QueryDatabaseBinding));
```

Trace the declaration first, then the returned Layer.
Read [Database](/systems/database) for its current callers and local verification commands.

## Plan → review → deploy

A [plan model](/lore/plan-model) describes infrastructure changes before they apply.
Sam connects Effect purity with a reviewable plan and a concrete deployment result at [12:22](https://youtu.be/YEn4A7XxgF4?t=742).
Tests using real infrastructure check behavior after deployment at [16:01](https://youtu.be/fPSxB7ZgSJw?t=961).

## The compiler checks the joins

[Effect](/lore/context-and-requirements) tracks required services in its type.
Effects and Layers let the type system track the resource providers a Stack needs at [07:01](https://youtu.be/fPSxB7ZgSJw?t=421).
Sam describes a type error when code still requires a removed binding at [15:25](https://youtu.be/YEn4A7XxgF4?t=925).
The compiler can check these relationships before deployment: [Happy Path 116, 28:00](https://youtu.be/YEn4A7XxgF4?t=1680).

## Cartridges

A [cartridge](/lore/cartridges) is a package that owns one job and the resources it needs.
Replacing its Layer changes the implementation and dependencies without changing callers.

## Lifecycles

Use an [XState machine](/lore/lifecycles-are-machines) for named states, retries, cancellation, or a lifecycle to resume or inspect.
Model the states and the events that move between them.

## The fence

The [fence](/lore/the-fence) is the compiler checks, lint rules, tests, and hooks that enforce project rules.
These rules cannot establish whole-program behavior.

## Cloud as a library

Sam's phrase is that [the whole cloud becomes a library](/lore/cloud-as-a-library), at [29:50](https://youtu.be/MtKHzAH6uXM?t=1790).
He argues that infrastructure tools can retain application-code properties such as debugging and tests at [03:50](https://youtu.be/YEn4A7XxgF4?t=230).

## The joins at a glance

- **Contract → surfaces**:
  - What the program checks: Shared input and failure schemas
  - Where to read more: [One capability, every surface](/lore/one-capability-every-surface)
- **Code → bindings → resources**:
  - What the program checks: Required services and resource providers
  - Where to read more: [Bindings](/lore/bindings) · [Infrastructure as Effects, Office Hours 27](/lore/effect-office-hours-27-alchemy-infrastructure-as-effects)
- **Plan → review → deploy**:
  - What the program checks: Changes before application; real-infrastructure behavior after deployment
  - Where to read more: [Plan model](/lore/plan-model)
- **Compiler → joins**:
  - What the program checks: Relationships before deployment; code that requires a removed binding
  - Where to read more: [Happy Path 116](/lore/happy-path-116-infrastructure-as-effects-sam-goodwin)
- **Cartridges**:
  - What the program checks: Removal leaves no loose resources or broken imports
  - Where to read more: [Cartridges](/lore/cartridges)
- **Lifecycles**:
  - What the program checks: Named states and the events between them
  - Where to read more: [Lifecycles are machines](/lore/lifecycles-are-machines)
- **Fence**:
  - What the program checks: Project rules; whole-program behavior remains outside these checks
  - Where to read more: [The fence](/lore/the-fence)
- **Cloud as a library**:
  - What the program checks: Debugging and tests for infrastructure code
  - Where to read more: [Cloud as a library](/lore/cloud-as-a-library)

## Sources

1. [#116 Infrastructure as Effects with Sam Goodwin - YouTube](https://youtu.be/YEn4A7XxgF4?t=1831)
   Sam Goodwin. Client and policy discussion; used for resource requirements implied by runtime operations. Accessed 2026-10-01.

2. [Alchemy, Infrastructure as Effects | Office Hours 27 🔥 - YouTube](https://youtu.be/fPSxB7ZgSJw?t=4255)
   Sam Goodwin. Bundle separation discussion; used for keeping providers out of runtime code. Accessed 2026-10-01.

3. [Sam Goodwin - Alchemy - devtools.fm](https://youtu.be/MtKHzAH6uXM?t=1560)
   devtools.fm. Plan model and cloud as a library discussions. Accessed 2026-10-11.

4. [rat-stack D1 resource and service Layer.](https://github.com/joelhooks/rat-stack/blob/c5e4fc13d7740952fcb1646b29a5cdd1b43001a8/packages/database/src/d1.ts)
   rat-stack. The D1 constructor declares migrations and a database, combines service Layers, and supplies the query binding. Accessed 2026-11-08.

## Lore on this page

- [One program can replace several tool calls](/lore/one-program-can-replace-several-tool-calls)
- [One schema, three surfaces](/lore/one-schema-three-surfaces)
- [A service captures its construction dependencies](/lore/services-capture-dependencies)
- [Bindings](/lore/bindings)
- [A cartridge owns one job and its resources](/lore/cartridges)
- [The fence](/lore/the-fence)
- [Cloud as a library](/lore/cloud-as-a-library)

## Linked from

- A cartridge owns one job and its resources → A cartridge owns one job and brings the infrastructure its service needs. → [Read page](https://ratstack.sh/lore/cartridges)

- Agent guide → An Effect stack so pure (aspirational) Kit Langton will blush. → [Read page](https://ratstack.sh/llms.txt)

- Agent rules for rat-stack (AGENTS.md) → What you may change, which commands to run, and which changes need approval. → [Read page](https://ratstack.sh/AGENTS.md)

- CAFE names the Cloudflare, Alchemy, Foldkit and Effect stack → CAFE is a named stack: Cloudflare runs the app, Alchemy declares it, Foldkit draws the UI, and Effect does the typed work. → [Read page](https://ratstack.sh/lore/cafe-stack)

- Change log → What changed in the files served here, newest first. → [Read page](https://ratstack.sh/log)

- Context and requirements → Effect requirements make a computation's needed services visible in its type. → [Read page](https://ratstack.sh/lore/context-and-requirements)

- Full agent guide → An Effect stack so pure (aspirational) Kit Langton will blush. → [Read page](https://ratstack.sh/llms-full.txt)

- Rat Stack lore | rat-stack → Short, source-grounded notes on the ideas and decisions behind rat-stack. → [Read page](https://ratstack.sh/lore)

- Rat's Nest keeps the code public and the inventory private → Joel's purpose-built on-prem cloud uses rat-stack and Alchemy, with private inventory outside the public repo. → [Read page](https://ratstack.sh/lore/rats-nest)

- Source change history (log.md) → The generated change log as Markdown. → [Read page](https://ratstack.sh/log.md)
