svelte-effect-runtime
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.

On this page