Recipes
Services And Layers
Provide Effect requirements to client and server runtimes.
Layers keep dependencies explicit. Client effects get browser services from the client runtime, and remote handlers get server services from the server runtime.
When to use this
Use this recipe once Effects need anything beyond pure values: storage, HTTP clients, database access, sessions, clocks, or logging.
Minimal working example
import { Context, Effect, Layer } from "effect";
export class Logger extends Context.Tag("Logger")<
Logger,
{ info: (message: string) => Effect.Effect<void> }
>() {}
export const LoggerLive = Layer.succeed(Logger, {
info: (message) => Effect.sync(() => console.info(message)),
});Realistic variant
Provide different layers to each runtime:
import { ClientRuntime } from "svelte-effect-runtime";
import { LoggerLive } from "$lib/logger";
export const init = () => {
ClientRuntime.make(LoggerLive);
};import { ServerRuntime } from "svelte-effect-runtime/server";
import { DatabaseLive } from "$lib/server/database";
import { LoggerLive } from "$lib/logger";
import { Layer } from "effect";
export const init = () => {
ServerRuntime.make(Layer.mergeAll(LoggerLive, DatabaseLive));
};Common mistakes
- Sharing server-only layers with the browser bundle.
- Making services depend on request data instead of reading
RequestEvent. - Hiding dependency construction inside remote handlers.
- Over-layering small components that only need local state.