Infrastructure as Effects
Infrastructure as Effects extends Infrastructure as Code by combining application code and infrastructure configuration into a single type-safe program built from Effects and Layers.
There is no separate “infra” project plus “handler” project — a Worker or Lambda Function is a Resource that ships its runtime code, with the resources it uses wired in as Bindings.
The whole model in one Worker
Section titled “The whole model in one Worker”import * as Cloudflare from "alchemy/Cloudflare";import * as Effect from "effect/Effect";import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse";import { Bucket } from "./bucket.ts";
export default Cloudflare.Worker( "Api", { main: import.meta.url }, Effect.gen(function* () { // Init — runs at deploy time (records the binding) and at cold start (builds the live client) const bucket = yield* Cloudflare.R2.ReadWriteBucket(Bucket);
return { // Runtime — runs per request, inside the deployed Worker fetch: Effect.gen(function* () { const obj = yield* bucket.get("hello.txt"); return obj ? HttpServerResponse.text(yield* obj.text()) : HttpServerResponse.text("Not found", { status: 404 }); }), }; }).pipe(Effect.provide(Cloudflare.R2.ReadWriteBucketBinding)),);- Functions & Servers — the Worker is a Resource that carries its handler; config and code deploy together.
- Bindings —
yield* Cloudflare.R2.ReadWriteBucket(Bucket)declares the capability; the providedReadWriteBucketBindingLayer is what wires it up — here as a native Worker binding — and hands back the typed client. The binding is the SDK; there is noenv.BUCKET. - Phases — the outer Effect runs at plantime to record bindings and again at cold start; the inner Effect runs per request.
- Layers — resources + bindings + runtime glue package into an Effect Layer behind a typed service, so implementations swap without touching consumers.
Effect style is optional — bindings also work as plain props on an
async fetch handler with a typed env via InferEnv; see
Effect handlers vs async handlers.
Where next
Section titled “Where next”- Functions & Servers — Resources that carry runtime code.
- Bindings — what
bind()generates. - Event Sources — resources that trigger your Function, as Effect
Streams. - Sinks — resources you write to, as Effect
Sinks. - APIs — schemaless RPC between your Functions and Servers, plus schema’d surfaces for trust boundaries.
- Phases — plantime vs runtime in depth.
- Layers — encapsulating infrastructure behind services.
- Building with Layers — build one end to end, then swap the backend.
- Circular Bindings — two services that reference each other.
- Custom Runtime — bring the model to a new compute target.