โ€ข

tech

A few Effect modules and how I use them

Effect is everywhere in my codebases, full stack, back and front and scripts and whatever. A few core module are always there, and carry most of the logic. Here they are, and how I use them.


Sandro Maglione

Sandro Maglione

Software

2026 is the year of effect (once more), guaranteed ๐Ÿค

Even more than last year ๐Ÿ‘‡

I am refining more and more patterns as I work more and more with effect

Here is a list of modules I am using (and why) with examples ๐Ÿ‘‡


Config

Long gone are the days where I had to bother about .env variables and process ๐Ÿ‘‹

The Config module abstracts all away in a single yield* Config. call:

export class Clerk extends Effect.Service<Clerk>()("Clerk", {
  effect: Effect.gen(function* () {
    const { secretKey, publishableKey } = yield* Config.all({
      secretKey: Config.redacted("CLERK_SECRET_KEY"),
      publishableKey: Config.redacted("CLERK_PUBLISHABLE_KEY"),
    });

    const clerkClient = createClerkClient({
      secretKey: Redacted.value(secretKey),
      publishableKey: Redacted.value(publishableKey),
    });

    return {
      // ...
    };
  }),
}) {}

Furthermore, with Schema even Config can be anything, with proper validation.

Notice how for example .redacted helps prevent leaking secret keys ๐Ÿช„

By default nothing else is necessary, effect picks up process.env by default.

Otherwise, you can use PlatformConfigProvider to read .env (no dotenv necessary):

import { PlatformConfigProvider } from "@effect/platform";
import { NodeFileSystem } from "@effect/platform-node";
import { Effect, Layer } from "effect";

export const ConfigEnvProviderLayer = Layer.unwrapEffect(
  PlatformConfigProvider.fromDotEnv(".env").pipe(
    Effect.map(Layer.setConfigProvider),
    Effect.provide(NodeFileSystem.layer)
  )
);

Array

The Array module gives your arrays superpowers (and immutability) โšก๏ธ

A few that I use all the times:

  • sortBy: sorting doesn't have to be complex, you can just use Order
  • append: don't bother with [...data, newData]
  • modify: safe updates
  • Array.NonEmptyReadonlyArray: makes array[0] always found
Array.sortBy(array, Order.mapInput(Order.Date, ({ createdAt }) => createdAt))
Array.append(array, newValue)
Array.modify(attempts, currentIndex, (attempt) => ({ ...attempt, userAttempt: value }))

You can just pipe a bunch of those to build any complex filtering/validation system.

Match

You won't find switch anymore in my codebases. It's all type-safe Match everywhere.

Match makes code future-proof: adding a new value causes compile errors to pop up here and there, instead of runtime back and forth โ˜‘๏ธ

Match.withReturnType to type the response at the start, Match.exhaustive to close the pipe at the end:

export default function AssignmentIcon({
  assignment,
}: {
  assignment: typeof SkillAssignmentLabel.Type;
}) {
  return Match.value(assignment).pipe(
    Match.withReturnType<React.ReactNode>(),
    Match.when("not_applicable", () => <></>),
    Match.when("critical", () =>  <CircleOff />),
    Match.when("incorrect", () => <Ban />),
    Match.when("slip", () => <Minus />),
    Match.when("passable", () => <Check />),
    Match.when("natural", () => <CheckCheck />),
    Match.when("perfect", () => <Trophy />),
    Match.exhaustive
  );
}

Effect toolkit: Schema, Layer, ManagedRuntime and more

Of course, the core of effect is always there, no matter the codebase (frontend/backend or anything):

  • Effect: Effect.gen/Effect.fn everywhere
  • Schema: must-have for, well, anything and everything
  • Layer: composition solved for you

These 3 alone will carry you a long way forward (error handling, dependency injection, schema validation).

A few others: Function, Predicate, Queue, Stream

A few more ideas for you to explore:

  • Function: a few helper functions you don't need to write (e.g. Function.identity)
  • Predicate: a few helper checks you won't miss (e.g. Predicate.isNotNullable)
  • Stream: AI talks the language of streams, and effect has you covered
  • Queue: I recently used it to integrate a callback API with xstate

Even the above are not found always. In reality, even for a few of my (relatively) big projects with effect, the basics will cover a huge percent of your code.

But when you will go beyond, effect has you covered as well.

Recent example: I used the Ndjson module from @effect/platform to parse AI responses โœจ


I am about to launch a few effect/xstate production apps, and with them I foresee a bunch more tips for patterns I learn while working with those tools.

2026 is gonna be insane.

See you next ๐Ÿ‘‹

Start here.

Every week I dive headfirst into a topic, uncovering every hidden nook and shadow, to deliver you the most interesting insights

Not convinced? Well, let me tell you more about it