Skip to main content
Handlers get their dependencies, such as a database, an API client or a queue, as Effect services. Each piece records the services it yields in its type, the app collects them, and the compiler refuses to serve the app until every one is provided.

How requirements are tracked

A piece needs every service its handler yields. A block also needs the services of its view and its actions, and a command or message action needs the services of the Effect it defers. The app needs the services of all its pieces:
moveTask needs Tracker, so does any block that lists it in actions, and so does the app that adds the block. Until Tracker is provided, calling app.fetch or toNodeHandler(app) is a type error that names Tracker. ReintersectApp.layer(app) accepts the app and passes Tracker on as a requirement of the router layer. Services read inside a component that returns an Effect aren’t tracked, so provide those yourself.

Provide services with a layer

provide(app, layer) returns a new app whose remaining requirements are the layer’s own:
src/app.ts
Export the app before provide too, so tests can provide fakes instead. See Testing. When a layer needs another service, provide that one as well, either by composing layers first or by calling provide again:

When the layer is built

The SDK builds the layer the first time a delivery needs it and keeps it for the life of the process, so every delivery shares the same services. Resources acquired with Layer.scoped, such as a connection pool, stay open until the process exits. If the layer fails to build, the SDK logs the cause and that delivery answers 500 with the code configuration (“The app’s services failed to start.”). The next delivery tries to build it again. On app.fetch, a layer that reads Config sees the string values in the env argument first, such as Cloudflare Workers bindings, then process.env.

Serve the app

ReintersectApp.layer(app, { path }) mounts the delivery path (default /reintersect), every route and the MCP server at /mcp, under the same root. It merges with your own routes, and the app’s unprovided services become requirements of the server:
src/server.ts
ReintersectApp.layer only accepts a complete app, the same check reintersect build makes: an app with a missing block or an undeclared environment value is a type error. For other servers, mount app.fetch or toNodeHandler(app) as in Self-hosted.