Server and client runtimes

The key build block of a React 19 app using Effect is a Runtime.

A Runtime collects a group of services and allows executing Effect.

Since there is a clear distinction between server and client, we define two separate runtimes. Each runtime will contain the services that are specific to either server or client.

By doing this, we keep the dependencies of server and client code separate.

Since Runtime collects all the services on its type, it becomes impossible to execute server-only code on the client.

The client runtime won't have server-only services, and therefore effect will report a compile-time error. This makes the client/server split explicit and type-safe.

Defining the runtime using ManagedRuntime

A basic runtime can be defined using ManagedRuntime. ManagedRuntime creates a runtime from a layer. This layer constructs multiple services that are provided to the runtime.

We start by adding a new services folder inside src:

mkdir src/services

Inside this folder we create two files:

  • RuntimeServer.ts
  • RuntimeClient.ts

Each file exports a ManagedRuntime. For now, we provide an empty layer (Layer.empty) to construct the runtime:

src/services/RuntimeServer.ts
import { Layer, ManagedRuntime } from "effect";

const MainLayer = Layer.empty;

export const RuntimeServer = ManagedRuntime.make(MainLayer);
src/services/RuntimeClient.ts
import { Layer, ManagedRuntime } from "effect";

const MainLayer = Layer.empty;

export const RuntimeClient = ManagedRuntime.make(MainLayer);

If you want to learn more about ManagedRuntime you can read the runtime module in my effect course.