2026 is the year of effect (once more), guaranteed 🤝
Even more than last year 👇
Technologies that you should be on the lookout for 2025 Local-first Many new tools available and a growing community. 2025 will bring even more innovation To follow: @localfirstconf @schickling Sync engines The UX and DX of sync engines is magical. They will become more and Show more
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
.redactedhelps 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 useOrderappend: don't bother with[...data, newData]modify: safe updatesArray.NonEmptyReadonlyArray: makesarray[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.
Matchmakes 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.fneverywhereSchema: must-have for, well, anything and everythingLayer: 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, andeffecthas you coveredQueue: I recently used it to integrate a callback API withxstate
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
Ndjsonmodule from@effect/platformto parse AI responses ✨
Typical @EffectTS_ experience 👇 Use the API to implement your solution, then discover that somewhere there is already a module for that, and replace all with 1 line 🪄
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 👋
