Skip to content

Effect boundary

Most application code does not need to learn Effect. Schemas, queries, policy rules, optimistic projections, and operation bodies are ordinary typed values. React uses subscriptions and event-handler methods.

Effect owns deployment resources, startup validation, acquisition, cancellation, deadlines, server orchestration, and provider composition. The Alchemy entry point is the main place most applications see it:

export default Alchemy.Stack(
"my-app",
{
providers: Layer.mergeAll(Cloudflare.providers(), Ramose.providers()),
state: Cloudflare.state(),
},
Effect.gen(function* () {
yield* Ramose.Server("App", {
main: import.meta.resolve("./peer.ts"),
storage: Store,
auth,
})
}),
)

Provide shared Layers once at the stack boundary. Keep parameterized Layer instances in constants when several resources reuse them.

Effect also runs the one-time schema assembly in the Worker entry:

const operationCatalogs = await Effect.runPromise(
deployOperationCatalogs(deployment),
)
export default createServer({ operationCatalogs })
export { QueryReplicaDO }
export const TransactorDO = createTransactorDO(operationCatalogs)

Query builders and policy rules compile to data. Operation codecs are Effect Schemas, but operation bodies build one authoritative change through a narrow handle. Optimistic projections must be pure and deterministic. None of these surfaces receives an ambient service context.

That separation makes the same declarations portable to browser type checking, server validation, catalog discovery, MCP schemas, and build-time compatibility checks.

Worker-side application integrations may return or compose Effects around external services, but the final database change still goes through the owned operation boundary. Put retries, timeouts, logging, and spans around service calls; do not retry a committed operation by inventing a second invocation identity.