โ— PHANTOM
๐Ÿ‡ฎ๐Ÿ‡ณ IN
โœ•
Skip to content

PaulJPhilp/EffectPatterns

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

993 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Warning

This is an auto-generated file. Manual edits will be overwritten by the publishing pipeline. For project information, see ABOUT.md

The Effect Patterns Hub

A community-driven knowledge base of practical, goal-oriented patterns for building robust applications with Effect-TS.

This repository is designed to be a living document that helps developers move from core concepts to advanced architectural strategies by focusing on the "why" behind the code.

EffectTalk.dev โ€” Browse all 300+ patterns, take guided learning tours, and run code examples in the browser. Built on this repo.

Install the CLI to search, browse, and install patterns from your terminal:

bun add -g @effect-patterns/ep-cli
ep search "error handling"

Looking for machine-readable rules for AI IDEs and coding agents? See the AI Coding Rules section below.

Table of Contents

Effect Patterns


Getting Started

Foundational patterns for your first steps with Effect-TS.

Pattern Skill Level Summary
Why Effect? Comparing Effect to Promise ๐ŸŸข Beginner Understand what Effect gives you that Promise doesn't: type-safe errors, dependency injection, and composability.
Hello World: Your First Effect ๐ŸŸข Beginner Create and run your very first Effect program using Effect.succeed and Effect.runSync.
Transform Values with Effect.map ๐ŸŸข Beginner Use Effect.map to transform the success value of an Effect without changing its error or dependency types.
Handle Your First Error with Effect.fail and catchAll ๐ŸŸข Beginner Learn how to create Effects that can fail and how to recover from those failures using Effect.fail and Effect.catchAll.
Run Multiple Effects in Parallel with Effect.all ๐ŸŸข Beginner Use Effect.all to run multiple Effects at the same time and collect all their results.
Retry a Failed Operation with Effect.retry ๐ŸŸข Beginner Use Effect.retry with a Schedule to automatically retry failed operations with customizable delays and limits.

Core Concepts

Essential building blocks for understanding and using Effect.

Pattern Skill Level Summary
Understand the Either Data Type ๐ŸŸข Beginner Use Either<E, A> to represent computations that can fail, allowing you to accumulate multiple errors instead of short-circuiting on the first one.
Chaining Computations with flatMap ๐ŸŸข Beginner Use flatMap to chain together computations where each step may itself be effectful, optional, or error-prone.
Combining Values with zip ๐ŸŸข Beginner Use zip to combine two computations, pairing their results together in Effect, Stream, Option, or Either.
Comparing Data by Value with Data.struct ๐ŸŸข Beginner Use Data.struct to create immutable, structurally-typed objects that can be compared by value, not by reference.
Comparing Data by Value with Structural Equality ๐ŸŸข Beginner Use Data.struct and Equal.equals to safely compare objects by their value instead of their reference, avoiding common JavaScript pitfalls.
Conditional Branching with if, when, and cond ๐ŸŸข Beginner Use combinators like if, when, and cond to express conditional logic declaratively across Effect, Stream, Option, and Either.
Converting from Nullable, Option, or Either ๐ŸŸข Beginner Use fromNullable, fromOption, and fromEither to convert nullable values, Option, or Either into Effects or Streams, enabling safe and composable interop.
Create Pre-resolved Effects with succeed and fail ๐ŸŸข Beginner Use Effect.succeed(value) to create an Effect that immediately succeeds with a value, and Effect.fail(error) for an Effect that immediately fails.
Creating from Collections ๐ŸŸข Beginner Use fromIterable and fromArray to create Streams or Effects from arrays, iterables, or other collections, enabling batch and streaming operations.
Creating from Synchronous and Callback Code ๐ŸŸข Beginner Use sync and async to lift synchronous or callback-based computations into Effect, enabling safe and composable interop with legacy code.
Execute Asynchronous Effects with Effect.runPromise ๐ŸŸข Beginner Use Effect.runPromise at the 'end of the world' to execute an asynchronous Effect and get its result as a JavaScript Promise.
Execute Synchronous Effects with Effect.runSync ๐ŸŸข Beginner Use Effect.runSync at the 'end of the world' to execute a purely synchronous Effect and get its value directly.
Filtering Results with filter ๐ŸŸข Beginner Use filter to keep or discard results based on a predicate, across Effect, Stream, Option, and Either.
Lifting Errors and Absence with fail, none, and left ๐ŸŸข Beginner Use fail, none, and left to represent errors or absence in Effect, Option, or Either, making failures explicit and type-safe.
Lifting Values with succeed, some, and right ๐ŸŸข Beginner Use succeed, some, and right to lift plain values into Effect, Option, or Either, making them composable and type-safe.
Understand the Option Data Type ๐ŸŸข Beginner Use Option to explicitly represent a value that may or may not exist, eliminating null and undefined errors.
Set Up a New Effect Project ๐ŸŸข Beginner Initialize a new Node.js project with the necessary TypeScript configuration and Effect dependencies to start building.
Solve Promise Problems with Effect ๐ŸŸข Beginner Understand how Effect solves the fundamental problems of native Promises, such as untyped errors, lack of dependency injection, and no built-in cancellation.
Transform Effect Values with map and flatMap ๐ŸŸข Beginner Use Effect.map for synchronous transformations and Effect.flatMap to chain operations that return another Effect.
Transforming Values with map ๐ŸŸข Beginner Use map to transform the result of an Effect, Stream, Option, or Either in a declarative, type-safe way.
Understand that Effects are Lazy Blueprints ๐ŸŸข Beginner An Effect is a lazy, immutable blueprint describing a computation, which does nothing until it is explicitly executed by a runtime.
When to Use Chunk vs Array ๐ŸŸข Beginner Choose Chunk for Effect pipelines, Stream results, and immutable collection operations; use Array when interfacing with existing APIs.
Understand the Three Effect Channels (A, E, R) ๐ŸŸข Beginner Learn about the three generic parameters of an Effect: the success value (A), the failure error (E), and the context requirements (R).
Use .pipe for Composition ๐ŸŸข Beginner Use the .pipe() method to chain multiple operations onto an Effect in a readable, top-to-bottom sequence.
Working with Immutable Arrays using Data.array ๐ŸŸข Beginner Use Data.array to create immutable, type-safe arrays that support value-based equality and safe functional operations.
Working with Tuples using Data.tuple ๐ŸŸข Beginner Use Data.tuple to create immutable, type-safe tuples that support value-based equality and pattern matching.
Wrap Asynchronous Computations with tryPromise ๐ŸŸข Beginner Use Effect.tryPromise to safely convert a function that returns a Promise into an Effect, capturing rejections in the error channel.
Wrap Synchronous Computations with sync and try ๐ŸŸข Beginner Use Effect.sync for non-throwing synchronous code and Effect.try for synchronous code that might throw an exception.
Wrapping Synchronous and Asynchronous Computations ๐ŸŸข Beginner Use try and tryPromise to safely wrap synchronous or asynchronous computations that may throw or reject, capturing errors in the Effect world.
Write Sequential Code with Effect.gen ๐ŸŸข Beginner Use Effect.gen with yield* to write sequential, asynchronous code in a style that looks and feels like familiar async/await.
Access Configuration from the Context ๐ŸŸก Intermediate Access your type-safe configuration within an Effect.gen block by yielding the Config object you defined.
Beyond the Date Type - Real World Dates, Times, and Timezones ๐ŸŸก Intermediate Use the Clock service for testable access to the current time and prefer immutable primitives for storing and passing timestamps.
Control Flow with Conditional Combinators ๐ŸŸก Intermediate Use combinators like Effect.if, Effect.when, and Effect.cond to handle conditional logic in a declarative, composable way.
Define a Type-Safe Configuration Schema ๐ŸŸก Intermediate Use Effect.Config primitives to define a schema for your application's configuration, ensuring type-safety and separation from code.
Handling Errors with catchAll, orElse, and match ๐ŸŸก Intermediate Use catchAll, orElse, and match to recover from errors, provide fallbacks, or transform errors in Effect, Either, and Option.
Understand Ref for Atomic State ๐ŸŸก Intermediate Use Ref to model shared, mutable state in a concurrent environment, ensuring all updates are atomic and free of race conditions.
Mapping and Chaining over Collections with forEach and all ๐ŸŸก Intermediate Use forEach and all to apply effectful functions to collections and combine the results, enabling batch and parallel processing.
Modeling Effect Results with Exit ๐ŸŸก Intermediate Use Exit<E, A> to represent the result of running an Effect, capturing both success and failure (including defects) in a type-safe way.
Modeling Tagged Unions with Data.case ๐ŸŸก Intermediate Use Data.case to create tagged unions (algebraic data types) for robust, type-safe domain modeling and pattern matching.
Optional Pattern 1: Handling None and Some Values ๐ŸŸก Intermediate Use Effect's Option type to safely handle values that may not exist, avoiding null/undefined bugs and enabling composable error handling.
Process Streaming Data with Stream ๐ŸŸก Intermediate Use Stream<A, E, R> to represent and process data that arrives over time, such as file reads, WebSocket messages, or paginated API results.
Provide Configuration to Your App via a Layer ๐ŸŸก Intermediate Use Config.layer(schema) to create a Layer that provides your configuration schema to the application's context.
Redact and Handle Sensitive Data ๐ŸŸก Intermediate Use Redacted to securely handle sensitive data, ensuring secrets are not accidentally logged or exposed.
Representing Time Spans with Duration ๐ŸŸก Intermediate Use the Duration data type to represent time intervals in a type-safe, human-readable, and composable way.
Sequencing with andThen, tap, and flatten ๐ŸŸก Intermediate Use andThen, tap, and flatten to sequence computations, run side effects, and flatten nested structures in Effect, Stream, Option, and Either.
Type Classes for Equality, Ordering, and Hashing with Data.Class ๐ŸŸก Intermediate Use Data.Class to derive and implement type classes for equality, ordering, and hashing, enabling composable and type-safe abstractions.
Understand Layers for Dependency Injection ๐ŸŸก Intermediate A Layer is a blueprint that describes how to build a service, detailing its own requirements and any potential errors during its construction.
Use Chunk for High-Performance Collections ๐ŸŸก Intermediate Use Chunk as a high-performance, immutable alternative to JavaScript's Array, especially for data processing pipelines.
Work with Arbitrary-Precision Numbers using BigDecimal ๐ŸŸก Intermediate Use BigDecimal for arbitrary-precision decimal arithmetic, avoiding rounding errors and loss of precision in financial or scientific calculations.
Work with Dates and Times using DateTime ๐ŸŸก Intermediate Use DateTime for immutable, time-zone-aware date and time values, enabling safe and precise time calculations.
Work with Immutable Sets using HashSet ๐ŸŸก Intermediate Use HashSet to model immutable, high-performance sets for efficient membership checks and set operations.
Create a Reusable Runtime from Layers ๐ŸŸ  Advanced Compile your application's layers into a reusable Runtime object to efficiently execute multiple effects that share the same context.
Understand the Cause Data Type ๐ŸŸ  Advanced Use Cause to get rich, structured information about errors and failures, including defects, interruptions, and error traces.
Optional Pattern 2: Optional Chaining and Composition ๐ŸŸ  Advanced Chain optional values across multiple steps with composable operators, enabling elegant data flow through systems with missing values.

Error Management

Patterns for type-safe, composable error handling.

Pattern Skill Level Summary
Checking Option and Either Cases ๐ŸŸข Beginner Use isSome, isNone, isLeft, and isRight to check Option and Either cases for simple, type-safe branching.
Matching on Success and Failure with match ๐ŸŸข Beginner Use match to handle both success and failure cases in a single, declarative place for Effect, Option, and Either.
Pattern Match on Option and Either ๐ŸŸข Beginner Use declarative match() combinators to handle optional and error-prone values
Your First Error Handler ๐ŸŸข Beginner Learn the basics of handling errors in Effect with catchAll and catchTag.
Conditionally Branching Workflows ๐ŸŸก Intermediate Use predicate-based operators like Effect.filter and Effect.if to make decisions and control the flow of your application based on runtime values.
Control Repetition with Schedule ๐ŸŸก Intermediate Use Schedule to create composable, stateful policies that define precisely how an effect should be repeated or retried.
Effectful Pattern Matching with matchEffect ๐ŸŸก Intermediate Use matchEffect to perform effectful branching based on success or failure, enabling rich workflows in the Effect world.
Error Handling Pattern 1: Accumulating Multiple Errors ๐ŸŸก Intermediate Collect multiple errors across operations instead of failing on first error, enabling comprehensive error reporting and validation.
Extract Failures and Defects from a Cause ๐ŸŸก Intermediate Use Cause.failures and Cause.defects to inspect a Cause and handle expected failures differently from unexpected defects.
Handle Errors with catchTag, catchTags, and catchAll ๐ŸŸก Intermediate Use catchTag for type-safe recovery from specific tagged errors, and catchAll to recover from any possible failure.
Handle Flaky Operations with Retries and Timeouts ๐ŸŸก Intermediate Use Effect.retry and Effect.timeout to build resilience against slow or intermittently failing operations, such as network requests.
Handling Specific Errors with catchTag and catchTags ๐ŸŸก Intermediate Use catchTag and catchTags to recover from or handle specific error types in the Effect failure channel, enabling precise and type-safe error recovery.
Mapping Errors to Fit Your Domain ๐ŸŸก Intermediate Use Effect.mapError to transform specific, low-level errors into more general domain errors, creating clean architectural boundaries.
Matching Tagged Unions with matchTag and matchTags ๐ŸŸก Intermediate Use matchTag and matchTags to pattern match on specific tagged union cases, enabling precise and type-safe branching.
Retry Operations Based on Specific Errors ๐ŸŸก Intermediate Use Effect.retry and predicate functions to selectively retry an operation only when specific, recoverable errors occur.
Scheduling Pattern 2: Implement Exponential Backoff for Retries ๐ŸŸก Intermediate Use exponential backoff with jitter to retry failed operations with increasing delays, preventing resource exhaustion and cascade failures in distributed systems.
Error Handling Pattern 2: Error Propagation and Chains ๐ŸŸ  Advanced Propagate errors through effect chains with context, preserving error information and enabling recovery at appropriate layers.
Error Handling Pattern 3: Custom Error Strategies ๐ŸŸ  Advanced Build domain-specific error types and recovery strategies that align with business logic and provide actionable error information.
Handle Unexpected Errors by Inspecting the Cause ๐ŸŸ  Advanced Use Effect.catchAllCause or Effect.runFork to inspect the Cause of a failure, distinguishing between expected errors (Fail) and unexpected defects (Die).

Resource Management

Safe acquisition, use, and release of resources.

Pattern Skill Level Summary
Safely Bracket Resource Usage with acquireRelease ๐ŸŸข Beginner Use Effect.acquireRelease to guarantee a resource's cleanup logic runs, even if errors or interruptions occur.
Guarantee Cleanup Even on Failure ๐ŸŸข Beginner Effect.acquireRelease and Effect.scoped ensure that release logic runs even when the use phase fails or is interrupted.
Compose Resource Lifecycles with Layer.merge ๐ŸŸก Intermediate Combine multiple resource-managing layers, letting Effect automatically handle the acquisition and release order.
Create a Service Layer from a Managed Resource ๐ŸŸก Intermediate Use Layer.scoped with Effect.Service to transform a managed resource into a shareable, application-wide service.
Handle Resource Timeouts ๐ŸŸก Intermediate Set timeouts on resource acquisition and usage to prevent hanging operations.
Pool Resources for Reuse ๐ŸŸก Intermediate Create and manage a pool of reusable resources like database connections or workers.
Choose Between ManagedRuntime and Effect.provide ๐ŸŸก Intermediate Use ManagedRuntime when running many effects with the same layers (servers, workers); use Effect.provide for one-off scripts.
Create a Managed Runtime for Scoped Resources ๐ŸŸ  Advanced Use Layer.launch to safely manage the lifecycle of layers containing scoped resources, ensuring finalizers are always run.
Manage Hierarchical Resources ๐ŸŸ  Advanced Manage parent-child resource relationships where children must be released before parents.
Manually Manage Lifecycles with Scope ๐ŸŸ  Advanced Use Scope directly to manage complex resource lifecycles or when building custom layers.

Concurrency

Patterns for parallel and concurrent execution.

Pattern Skill Level Summary
Race Effects and Handle Timeouts ๐ŸŸข Beginner Race multiple effects to get the fastest result, or add timeouts to prevent hanging operations.
Understanding Fibers ๐ŸŸข Beginner Learn what fibers are, how they differ from threads, and why they make Effect powerful for concurrent programming.
Your First Parallel Operation ๐ŸŸข Beginner Run multiple effects in parallel with Effect.all and understand when to use parallel vs sequential execution.
Fork Background Work ๐ŸŸข Beginner Use Effect.fork to run work in the background while your main code continues.
Concurrency Pattern 1: Coordinate Async Operations with Deferred ๐ŸŸก Intermediate Use Deferred to coordinate async operations where multiple fibers wait for a single event to complete, enabling producer-consumer patterns and async signaling without polling.
Concurrency Pattern 2: Rate Limit Concurrent Access with Semaphore ๐ŸŸก Intermediate Use Semaphore to limit the number of concurrent operations, enabling connection pooling, API rate limiting, and controlled resource access without overload.
Concurrency Pattern 3: Coordinate Multiple Fibers with Latch ๐ŸŸก Intermediate Use Latch to synchronize multiple fibers, enabling patterns like coordinating N async tasks, fan-out/fan-in, and barrier synchronization.
Concurrency Pattern 4: Distribute Work with Queue ๐ŸŸก Intermediate Use Queue to decouple producers and consumers, enabling work distribution, pipeline stages, and backpressure handling across concurrent fibers.
Concurrency Pattern 5: Broadcast Events with PubSub ๐ŸŸก Intermediate Use PubSub to broadcast events to multiple subscribers, enabling event-driven architectures and fan-out patterns without direct coupling.
Concurrency Pattern 6: Race and Timeout Competing Effects ๐ŸŸก Intermediate Use race and timeout to compete multiple effects and enforce deadlines, enabling timeout handling and choosing fastest result.
Manage Shared State Safely with Ref ๐ŸŸก Intermediate Use Ref to model shared, mutable state in a concurrent environment, ensuring all updates are atomic and free of race conditions.
Process a Collection in Parallel with Effect.forEach ๐ŸŸก Intermediate Use Effect.forEach with the concurrency option to process a collection of items in parallel with a fixed limit, preventing resource exhaustion.
Race Concurrent Effects for the Fastest Result ๐ŸŸก Intermediate Use Effect.race to run multiple effects concurrently and proceed with the result of the one that succeeds first, automatically interrupting the others.
Run Independent Effects in Parallel with Effect.all ๐ŸŸก Intermediate Use Effect.all to run multiple independent effects concurrently and collect all their results into a single tuple.
Add Caching by Wrapping a Layer ๐ŸŸ  Advanced Implement caching by creating a new layer that wraps a live service, intercepting method calls to add caching logic without modifying the original service.
Decouple Fibers with Queues and PubSub ๐ŸŸ  Advanced Use Queue for point-to-point work distribution and PubSub for broadcast messaging to enable safe, decoupled communication between concurrent fibers.
Execute Long-Running Apps with Effect.runFork ๐ŸŸ  Advanced Use Effect.runFork at the application's entry point to launch a long-running process as a detached fiber, allowing for graceful shutdown.
Implement Graceful Shutdown for Your Application ๐ŸŸ  Advanced Use Effect.runFork and listen for OS signals (SIGINT, SIGTERM) to trigger a Fiber.interrupt, ensuring all resources are safely released.
Manage Resource Lifecycles with Scope ๐ŸŸ  Advanced Use Scope for fine-grained, manual control over resource lifecycles, ensuring cleanup logic (finalizers) is always executed.
Poll for Status Until a Task Completes ๐ŸŸ  Advanced Use Effect.race to run a repeating polling effect alongside a main task, automatically stopping the polling when the main task finishes.
Run Background Tasks with Effect.fork ๐ŸŸ  Advanced Use Effect.fork to start a computation in a background fiber, allowing the parent fiber to continue its work without waiting.
State Management Pattern 1: Synchronized Reference with SynchronizedRef ๐ŸŸ  Advanced Use SynchronizedRef to safely share mutable state across concurrent fibers, with atomic updates and guaranteed consistency.
State Management Pattern 2: Observable State with SubscriptionRef ๐ŸŸ  Advanced Build observable state that notifies subscribers on changes, enabling reactive patterns and state-driven architecture.
Understand Fibers as Lightweight Threads ๐ŸŸ  Advanced A Fiber is a lightweight, virtual thread managed by the Effect runtime, enabling massive concurrency on a single OS thread without the overhead of traditional threading.

Streams

Processing sequences of values over time.

Pattern Skill Level Summary
Running and Collecting Stream Results ๐ŸŸข Beginner Learn the different ways to run a stream and collect its results: runCollect, runForEach, runDrain, and more.
Stream Pattern 1: Transform Streams with Map and Filter ๐ŸŸข Beginner Use Stream.map and Stream.filter to transform and select stream elements, enabling data pipelines that reshape and filter data in flight.
Stream vs Effect - When to Use Which ๐ŸŸข Beginner Understand when to use Effect (single value) vs Stream (sequence of values) for your use case.
Take and Drop Stream Elements ๐ŸŸข Beginner Control how many stream elements to process using take, drop, takeWhile, and dropWhile.
Your First Stream ๐ŸŸข Beginner Create your first Effect Stream and understand what makes streams different from regular arrays.
Sink Pattern 1: Batch Insert Stream Records into Database ๐ŸŸก Intermediate Use Sink to batch stream records and insert them efficiently into a database in groups, rather than one-by-one, for better performance and resource usage.
Sink Pattern 2: Write Stream Events to Event Log ๐ŸŸก Intermediate Use Sink to append stream events to an event log with metadata and causal ordering, enabling event sourcing and audit trail patterns.
Sink Pattern 3: Write Stream Lines to File ๐ŸŸก Intermediate Use Sink to write stream data as lines to a file with buffering for efficiency, supporting log files and line-oriented formats.
Sink Pattern 4: Send Stream Records to Message Queue ๐ŸŸก Intermediate Use Sink to publish stream records to a message queue with partitioning, batching, and acknowledgment handling for distributed systems.
Sink Pattern 5: Fall Back to Alternative Sink on Failure ๐ŸŸก Intermediate Use Sink to attempt writing to a primary destination, and automatically fall back to an alternative destination if the primary fails, enabling progressive degradation and high availability.
Sink Pattern 6: Retry Failed Stream Operations ๐ŸŸก Intermediate Use Sink with configurable retry policies to automatically retry failed operations with exponential backoff, enabling recovery from transient failures without losing data.
Stream Pattern 2: Merge and Combine Multiple Streams ๐ŸŸก Intermediate Use Stream.merge, Stream.concat, and Stream.mergeAll to combine multiple streams into a single stream, enabling multi-source data aggregation.
Stream Pattern 3: Control Backpressure in Streams ๐ŸŸก Intermediate Use Stream throttling, buffering, and chunk operations to manage backpressure, preventing upstream from overwhelming downstream consumers.
Stream Pattern 4: Stateful Operations with Scan and Fold ๐ŸŸก Intermediate Use Stream.scan and Stream.fold to maintain state across stream elements, enabling cumulative operations, counters, aggregations, and stateful transformations.
Stream Pattern 5: Grouping and Windowing Streams ๐ŸŸ  Advanced Use grouping and windowing to organize streams by key or time window, enabling batch operations and temporal aggregations.
Stream Pattern 6: Resource Management in Streams ๐ŸŸ  Advanced Properly manage resources (connections, files, memory) in streams using acquire/release patterns and ensuring cleanup on error or completion.
Stream Pattern 7: Error Handling in Streams ๐ŸŸ  Advanced Handle errors gracefully in streams with recovery strategies, resuming after failures, and maintaining stream integrity.
Stream Pattern 8: Advanced Stream Transformations ๐ŸŸ  Advanced Apply complex transformations across streams including custom operators, effect-based transformations, and composition patterns.

Scheduling

Patterns for retries, repetition, and time-based execution.

Pattern Skill Level Summary
Retry Failed Operations ๐ŸŸข Beginner Use Effect.retry with Schedule to automatically retry operations that fail.
Your First Schedule ๐ŸŸข Beginner Learn the basics of scheduling in Effect - retry operations and repeat them on intervals.
Scheduling Pattern 1: Repeat an Effect on a Fixed Interval ๐ŸŸก Intermediate Use Schedule.fixed to repeat an effect at regular intervals, enabling polling, health checks, and periodic background tasks without busy-waiting or manual timing logic.
Scheduling Pattern 3: Schedule Tasks with Cron Expressions ๐ŸŸก Intermediate Use cron expressions to schedule tasks at specific times and intervals, enabling calendar-based scheduling with timezone support.
Scheduling Pattern 4: Debounce and Throttle Execution ๐ŸŸก Intermediate Use debouncing and throttling to limit how often effects execute, preventing runaway operations and handling rapid event sequences.
Scheduling Pattern 5: Advanced Retry Chains and Circuit Breakers ๐ŸŸ  Advanced Build sophisticated retry chains with circuit breakers, fallbacks, and complex failure patterns for production-grade reliability.

Domain Modeling

Building robust domain models with Effect and Schema.

Pattern Skill Level Summary
Create Type-Safe Errors ๐ŸŸข Beginner Define domain-specific errors using Data.TaggedError for type-safe error handling.
Handle Missing Values with Option ๐ŸŸข Beginner Use Option to explicitly model values that might not exist, avoiding null/undefined bugs.
Your First Domain Model ๐ŸŸข Beginner Create a simple domain model using TypeScript interfaces and Effect to represent your business entities.
Accumulate Multiple Errors with Either ๐ŸŸก Intermediate Use Either<E, A> to represent computations that can fail, allowing you to accumulate multiple errors instead of short-circuiting on the first one.
Avoid Long Chains of .andThen; Use Generators Instead ๐ŸŸก Intermediate Prefer Effect.gen over long chains of .andThen for sequential logic to improve readability and maintainability.
Define Contracts Upfront with Schema ๐ŸŸก Intermediate Use Schema to define the types for your data models and function signatures before writing the implementation, creating clear, type-safe contracts.
Define Type-Safe Errors with Data.TaggedError ๐ŸŸก Intermediate Create custom, type-safe error classes by extending Data.TaggedError to make error handling robust, predictable, and self-documenting.
Distinguish 'Not Found' from Errors ๐ŸŸก Intermediate Use Effect<Option> to clearly distinguish between a recoverable 'not found' case (None) and a true failure (Fail).
Model Optional Values Safely with Option ๐ŸŸก Intermediate Use Option to explicitly represent a value that may or may not exist, eliminating null and undefined errors.
Model Validated Domain Types with Brand ๐ŸŸก Intermediate Use Brand to turn primitive types like string or number into specific, validated domain types like Email or PositiveInt, making illegal states unrepresentable.
Modeling Validated Domain Types with Brand ๐ŸŸก Intermediate Use Brand to create domain-specific types from primitives, making illegal states unrepresentable and preventing accidental misuse.
Parse and Validate Data with Schema.decode ๐ŸŸก Intermediate Use Schema.decode(schema) to create an Effect that parses and validates unknown data, which integrates seamlessly with Effect's error handling.
Transform Data During Validation with Schema ๐ŸŸก Intermediate Use Schema.transform to safely convert data from one type to another during the parsing phase, such as from a string to a Date.
Use Effect.gen for Business Logic ๐ŸŸก Intermediate Encapsulate sequential business logic, control flow, and dependency access within Effect.gen for improved readability and maintainability.
Validating and Parsing Branded Types ๐ŸŸก Intermediate Use Schema and Brand together to validate and parse branded types at runtime, ensuring only valid values are constructed.

Schema

Validation, parsing, and transformation with @effect/schema.

Pattern Skill Level Summary
Adding Descriptions for AI Context ๐ŸŸข Beginner You define a schema with field names like confidence or category, but the LLM doesn't understand the nuance of what you want. It might interpret fields differently than intended, leading to...
Array Validation ๐ŸŸข Beginner You receive a list of items and need to validate each one. Without schema validation, you'd loop through and check each item manually. You need to define what valid array items look like and validate...
Basic AI Output Schema ๐ŸŸข Beginner You're using an LLM to generate structured data. Without a schema, you get unpredictable JSONโ€”missing fields, wrong types, hallucinated keys. You need to define a schema that tells the LLM exactly...
Basic AI Response Parsing ๐ŸŸข Beginner You've called an LLM with a JSON schema, but the response is still unknown. The model might have hallucinated extra fields, used wrong types, or returned malformed JSON despite your instructions....
Basic API Response Decoding ๐ŸŸข Beginner You're fetching data from an external API. The response is unknown at runtime. TypeScript's type assertions (as User) are liesโ€”they don't validate anything. A malformed API response will silently...
Basic Async Validation with Schema.filterEffect ๐ŸŸข Beginner You have sync validation rules (format, length) handled by schema. But some rules require async operations: checking a username isn't taken, verifying a discount code is valid, calling an external...
Basic Form Validation ๐ŸŸข Beginner You have a form with multiple fieldsโ€”name, email, age. Validation is scattered everywhere: inline JavaScript, backend checks, error messages don't match. You need a single source of truth for form...
Basic JSON File Validation ๐ŸŸข Beginner You have a JSON file on disk and need to read it, parse it, and validate the structure against a schema. Simply reading and parsing can produce runtime errors if the file is missing, corrupted, or...
Basic Object Schemas ๐ŸŸข Beginner Most real data is objects with named fields. You need to define the expected shape, validate each field has the right type, and get a typed result. Without schema validation, you access properties...
Basic Recursive Schemas with Schema.suspend ๐ŸŸข Beginner You need to validate tree-like data: a node with children that are also nodes. Or linked lists where each item points to the next. Without recursion support, you can't express these structuresโ€”the...
Basic Schema Transformations ๐ŸŸข Beginner Your application receives data in one shape but needs it in another. API returns a Unix timestamp; your domain uses Date objects. Form input arrives as strings; you need typed numbers. Database...
Basic Union Types and Alternatives ๐ŸŸข Beginner Your API returns different shapes depending on context. A response could be a user profile OR an error message. A payment could succeed with a transaction ID OR fail with a reason. Without union...
Collecting All Validation Errors ๐ŸŸข Beginner Standard validation stops at the first error: "Username is required". But users want to see ALL problems at onceโ€”missing fields, invalid formats, out-of-range values. Showing one error at a time...
Custom Tagged Errors ๐ŸŸข Beginner Your application throws generic Error objects. When calling a function, you don't know what errors it might throw. Is it a validation error? Network timeout? Permission denied? Code that calls your...
Date Validation and Parsing ๐ŸŸข Beginner Dates arrive in many formats: ISO strings, Unix timestamps, Date objects. JavaScript's Date constructor silently accepts invalid input ("Invalid Date"). You need to parse dates safely and validate...
Decode and Encode Data ๐ŸŸข Beginner You receive data as JSON and need to convert it to typed objects. Later, you need to serialize those objects back to JSON for storage or API responses. Without a consistent approach, you write...
Effect Schema vs Zod ๐ŸŸข Beginner You're familiar with Zod (or similar libraries) and want to understand how Effect Schema differs. The syntax looks similar but Effect Schema offers capabilities Zod doesn't have. You need a quick...
Email Address Validation ๐ŸŸข Beginner You're accepting email addresses from user input or API requests. A simple string type tells you nothingโ€”users submit "not-an-email", "@@invalid", or empty strings. You need validation that checks...
Enums and Literal Types ๐ŸŸข Beginner Some fields only accept specific values: status is "active" or "inactive", role is "admin", "user", or "guest". Using Schema.String allows any string, letting invalid values slip through. You need to...
Environment Variables with Schema Validation ๐ŸŸข Beginner Environment variables power your applicationโ€”database URLs, API keys, ports. But they're just strings. You load them with process.env.DATABASE_URL, hoping it exists and is valid. No type safety, no...
Extending and Adding Fields to Schemas ๐ŸŸข Beginner You have a base schema (User) and need variants with additional fields (AdminUser, PremiumUser). Copy-pasting the schema creates maintenance burdenโ€”change one field and you update three schemas. You...
Handling Decode Failures ๐ŸŸข Beginner You're decoding API responses with a Schema, but validation sometimes fails. You need to know why it failed so you can decide: retry, use a default, log it, or fail explicitly.
Handling Malformed AI Outputs ๐ŸŸข Beginner An LLM returns malformed JSON or fields that don't match your schema. The parse fails and the operation stops. You need graceful recovery strategies: provide sensible defaults, extract partial data,...
Handling Parse Errors ๐ŸŸข Beginner When validation fails, you need to know what went wrong. The default parse error is detailed but hard to read. You need to extract useful error messages for logging, displaying to users, or debugging.
Nested Object Schemas ๐ŸŸข Beginner Real data has nested objects: a user has an address, an order has items with products. You need to define schemas for complex structures where objects contain other objects, and validate the entire...
Number Validation and Refinements ๐ŸŸข Beginner Numbers need constraints: prices must be positive, ages must be integers, percentages must be 0-100. JavaScript's number type accepts any numeric value. You need runtime validation to catch invalid...
Optional and Nullable Fields ๐ŸŸข Beginner Not all fields are required. Some are optional (may be missing), some are nullable (present but null), some accept both. You need to express these different optionality patterns while keeping types...
String Validation and Refinements ๐ŸŸข Beginner Raw strings need constraints: minimum length for passwords, maximum length for tweets, email format, URL format. Without validation, invalid strings propagate through your system causing errors far...
Tuple Schemas ๐ŸŸข Beginner Sometimes you need fixed-length arrays where each position has a specific type. A coordinate is [x, y], an RGB color is [r, g, b], a range is [start, end]. Regular arrays allow any length. You need...
URL Validation ๐ŸŸข Beginner You accept URLs from usersโ€”as links, webhooks, or API endpoints. A string type doesn't validate that it's actually a valid URL. Users submit malformed URLs like "htp://example" or "not a url". You...
UUID Validation (v4, v7) ๐ŸŸข Beginner Your API accepts IDs as strings, but there's no validation that they're actually valid UUIDs. Users submit malformed IDs, truncated strings, or wrong formats. You need to validate UUID format at...
Validating Config Files ๐ŸŸข Beginner Configuration files are often JSON and must be loaded and validated at application startup. Config files have specific requirements: certain fields are required, others are optional, and values must...
Validating JSON Database Columns ๐ŸŸข Beginner Databases store JSON data in columns (MySQL JSON, PostgreSQL JSONB, SQLite JSON), but the database itself doesn't enforce schemaโ€”any JSON is valid from the database's perspective. When you retrieve...
Your First Schema ๐ŸŸข Beginner You have unknown dataโ€”from an API, form, or fileโ€”and need to validate it has the right shape. Without schema validation, your code assumes data is correct and crashes later with cryptic errors. You...
API Validation with Retry ๐ŸŸก Intermediate APIs are flaky. Network timeouts, rate limits, temporary service degradationโ€”these happen. You validate the response with a schema, but what if the API is temporarily down?
Async Validation (Username Availability) ๐ŸŸก Intermediate Some validation requires checking a server: is this username available? Is this email already registered? Standard schema validation is synchronousโ€”you can't check a database or API. You need to...
Bidirectional API โ†” Domain โ†” DB Transformations ๐ŸŸก Intermediate Your application lives in three worlds: API contracts (what clients expect), domain models (your business logic), and database schemas (how data persists). Each world has different requirements. The...
Branded Types for Type-Safe IDs and Strings ๐ŸŸก Intermediate Your domain has user IDs, product IDs, email addresses. They're all strings at runtime, but they mean different things. A function accepting string could receive any stringโ€”wrong ID format, email...
Composable Configuration Layers ๐ŸŸก Intermediate Real applications need configuration from multiple sources: default values, environment variables, config files, runtime overrides. Loading config becomes scattered across the codebase. Layers...
Data Normalization and Canonical Forms ๐ŸŸก Intermediate Raw data is messy: extra whitespace, inconsistent casing, duplicates, mixed formats. You receive product names with leading/trailing spaces, emails in different cases, phone numbers with various...
Database Validation - Uniqueness, Foreign Keys, Constraints ๐ŸŸก Intermediate A username must be unique in the database. A product reference must exist. An email can't belong to two accounts. These database constraints can't be validated with sync schemas. You need async...
Decoding Nested API Responses ๐ŸŸก Intermediate Real APIs rarely return flat objects. Responses are deeply nested: users have profiles, profiles have addresses, addresses have coordinates.
Dependent Field Validation ๐ŸŸก Intermediate Form fields depend on each other: password must match confirmation, checkout address must match billing address, date range end must be after start. Standard field-by-field validation can't check...
Discriminated Unions with Type Narrowing ๐ŸŸก Intermediate You have a union of different event types. Without a discriminator field, checking which type it is means examining multiple fields or using instanceof checks. With a _tag or type discriminator,...
Enums and Literal Types ๐ŸŸก Intermediate You need the LLM to pick from a specific set of valuesโ€”like priority levels, categories, or statuses. Without constraints, the LLM might output variations ("high", "HIGH", "urgent", "priority:...
Error Aggregation and Collection ๐ŸŸก Intermediate Form has 10 fields. User makes mistakes in 5 of them. Current approach: show first error, user fixes it, resubmit, find next error, repeat 5 times. Bad UX. You need to collect all validation errors...
Error Recovery and Fallback Strategies ๐ŸŸก Intermediate An API call fails. Retry immediatelyโ€”it works the second time. But retry too fast and you overload the system. Wait too long and users think the app is broken. Network hiccups, temporary outages,...
Exhaustive Pattern Matching and Never Types ๐ŸŸก Intermediate A union has 5 variants. Developer writes a switch with 4 cases and forgets one. Code compiles. Six months later, a user hits the missing case and the app crashes. Without compiler checks,...
External API Validation During Schema Parsing ๐ŸŸก Intermediate Your system integrates with external APIs (payment processor, geocoding, IP reputation). You need to validate user input against those services during parsing. A card must be valid with the payment...
Feature Flags with Dynamic Validation ๐ŸŸก Intermediate You want to roll out features gradually: enable for 10% of users, then 50%, then 100%. Or toggle features without redeploying. Feature flags scattered across code make it impossible to reason about...
Handling Schema Evolution ๐ŸŸก Intermediate Databases store historical data in JSONB columns that may be from different application versions. Your current schema expects fields that old records don't have. Old records might have fields your...
Handling Union/Discriminated Responses ๐ŸŸก Intermediate APIs often return different response shapes based on success or failure. A user creation endpoint might return: - { success: true, data: User } on success - { success: false, error: string } on...
HTTP Header Validation ๐ŸŸก Intermediate Your HTTP server receives headers as stringsโ€”Content-Type: text/plain, Authorization: Bearer token, etc. Headers are unvalidated and can be malformed, contain invalid values, or abuse your API....
ISO 8601 Date Validation ๐ŸŸก Intermediate Your API accepts dates as strings from JSON. Without validation, you get malformed dates like "2024-13-45" or timezone-naive strings. You need to validate ISO 8601 format at runtime, ensure dates are...
Merging Multiple Schemas into One ๐ŸŸก Intermediate You need to validate that incoming data satisfies multiple schemas at once. A request must be valid JSON AND match your custom business rules. A document must have base metadata AND domain-specific...
MIME Type Validation ๐ŸŸก Intermediate Your application accepts file uploads or specifies content types. Users submit unknown MIME types, you get files with mismatched extensions, or malicious uploads bypass checks. You need to validate...
Nested Comments and Threaded Discussions ๐ŸŸก Intermediate Reddit, HN, YouTubeโ€”all have nested comment threads. A comment can have replies, which have replies. Users expect arbitrary nesting depth. Without recursive schemas, you'd store flat comments and...
Nested Form Structures ๐ŸŸก Intermediate Complex forms have nested data: a user form with multiple addresses, an order with line items, a profile with emergency contacts. These nested structures need validation at each levelโ€”addresses must...
Nested Object Schemas ๐ŸŸก Intermediate You need to represent complex, hierarchical data from an LLMโ€”like a document with sections, paragraphs, and metadata. Flat schemas don't capture this structure. You need to compose schemas into...
Parsing Partial/Incomplete Responses ๐ŸŸก Intermediate An LLM streaming response gets cut off mid-generation, or the user cancels before completion. You receive incomplete JSON with missing closing braces or truncated fields. Standard parsing fails. You...
Pick and Omit - Selecting and Excluding Fields ๐ŸŸก Intermediate You have a comprehensive User schema with 15 fields. For the public profile API, you only need 5 fields. For the admin export, you need everything except passwords and tokens. Writing three separate...
Polymorphic API Responses and Data Shaping ๐ŸŸก Intermediate Your API returns different response shapes for different endpoints. Search returns paginated results; detail returns single object; batch returns array. Each endpoint has its own shape. Without...
PostgreSQL JSONB Validation ๐ŸŸก Intermediate PostgreSQL JSONB columns are powerful and flexible, but that flexibility is dangerous. You can store any JSON, but your application expects specific fields with specific types. When you query JSONB...
Retry Strategies for Parse Failures ๐ŸŸก Intermediate Parsing an LLM response failsโ€”maybe the model hallucinated, generated malformed JSON, or the response was incomplete. Retrying with a fresh API call might succeed. You need to distinguish retryable...
Schema Inheritance and Specialization ๐ŸŸก Intermediate Your domain has a base entity (Product) with common fields and many specializations (PhysicalProduct, DigitalProduct, ServiceProduct). Each has unique fields. You need a type hierarchy where...
Schema with Default Values ๐ŸŸก Intermediate Configuration files often have optional fields where users can omit them and use sensible defaults. Manually checking if a field exists and assigning defaults is repetitive and error-prone. You need...
Secrets Redaction and Masking ๐ŸŸก Intermediate Logs contain API keys, database passwords, and authentication tokens. A developer accidentally logs config, exposing secrets. An error gets reported with stack traces containing credentials. You need...
Tree Structures - File Systems, Org Charts, Hierarchies ๐ŸŸก Intermediate Real applications work with trees constantly: file systems, org charts, category hierarchies, DOM trees. Each node has metadata and children. You need to parse, validate, and manipulate these...
Union Types for Flexible Outputs ๐ŸŸก Intermediate An LLM needs to return different response shapes depending on context. For example, a query might succeed with data, fail with an error, or be pending. Without union types, you either get a flat...
User-Friendly Error Messages ๐ŸŸก Intermediate Internal error: "TypeError: Cannot read property 'value' of undefined at line 342". Users see this and think the app is broken. Developers see it in logs and can debug. But showing technical errors...
Validating Multiple Config Files ๐ŸŸก Intermediate Complex applications often need to load multiple configuration files: database config, API keys, logging settings, feature flags, etc. Loading them one-by-one is slow, and you need to handle both...
Validating Partial Documents ๐ŸŸก Intermediate REST APIs support PATCH requests that update only specific fieldsโ€”users don't send the entire document, just the fields they want to change. But you still need to validate those fields against your...
Efficient Batched Async Validation and Deduplication ๐ŸŸ  Advanced Validating 100 items individually makes 100 API calls. But the API accepts batch operations. You need async validation that deduplicates requests and validates in batches for efficiency. Validate...
Full Pipeline with @effect/platform ๐ŸŸ  Advanced Production code needs more than fetch(): connection pooling, request timeouts, retries, logging, metrics, and proper resource management. Using Effect.tryPromise with raw fetch is fragile.
Integration with Vercel AI SDK ๐ŸŸ  Advanced You're using Vercel AI SDK's generateObject function to get structured output from LLMs. The SDK expects a specific schema format. You need to convert Effect schemas to Vercel's format, handle the...
Parsing JSON into Typed Abstract Syntax Trees ๐ŸŸ  Advanced You need to parse arbitrary JSON into a typed, manipulable structure. A JSON file could contain numbers, strings, arrays, objectsโ€”all nested. Without an AST schema, you work with any and lose type...
Validating Streaming AI Responses ๐ŸŸ  Advanced An LLM streams JSON responses back in chunks. You need to validate incrementally as data arrivesโ€”catching schema violations early without waiting for the full response, updating UI in real-time, and...

Platform

Cross-platform utilities from @effect/platform.

Pattern Skill Level Summary
Access Environment Variables ๐ŸŸข Beginner Read environment variables safely with Effect Platform, handling missing values gracefully.
Platform Pattern 2: Filesystem Operations ๐ŸŸข Beginner Use FileSystem module to read, write, list, and manage files with proper resource cleanup and error handling.
Platform Pattern 4: Interactive Terminal I/O ๐ŸŸข Beginner Use Terminal module to read user input and write formatted output, enabling interactive CLI applications with proper buffering and encoding.
Your First Platform Operation ๐ŸŸข Beginner Get started with Effect Platform by reading a file and understanding how Platform differs from Node.js APIs.
Platform Pattern 1: Execute Shell Commands ๐ŸŸก Intermediate Use Command module to execute shell commands, capture output, and handle exit codes, enabling integration with system tools and external programs.
Platform Pattern 3: Persistent Key-Value Storage ๐ŸŸก Intermediate Use KeyValueStore for simple persistent key-value storage, enabling caching, session management, and lightweight data persistence.
Platform Pattern 5: Cross-Platform Path Manipulation ๐ŸŸก Intermediate Use platform-aware path operations to handle file system paths correctly across Windows, macOS, and Linux with proper resolution and normalization.
Platform Pattern 6: Advanced FileSystem Operations ๐ŸŸ  Advanced Handle complex file system scenarios including watching files, recursive operations, atomic writes, and efficient bulk operations.

Building APIs

Patterns for building robust API services.

Pattern Skill Level Summary
Create a Basic HTTP Server ๐ŸŸข Beginner Launch a simple, effect-native HTTP server to respond to incoming requests.
Extract Path Parameters ๐ŸŸข Beginner Capture and use dynamic segments from a request URL, such as a resource ID.
Handle a GET Request ๐ŸŸข Beginner Define a route that responds to a specific HTTP GET request path.
Send a JSON Response ๐ŸŸข Beginner Create and send a structured JSON response with the correct headers and status code.
Add Rate Limiting to APIs ๐ŸŸก Intermediate Protect your API from abuse by limiting request rates per client.
Compose API Middleware ๐ŸŸก Intermediate Build reusable middleware for logging, authentication, validation, and more.
Configure CORS for APIs ๐ŸŸก Intermediate Enable Cross-Origin Resource Sharing to allow browser clients from different domains.
Handle API Errors ๐ŸŸก Intermediate Translate application-specific errors from the Effect failure channel into meaningful HTTP error responses.
Implement API Authentication ๐ŸŸก Intermediate Add JWT or session-based authentication to protect your API endpoints.
Make an Outgoing HTTP Client Request ๐ŸŸก Intermediate Use the built-in Effect HTTP client to make safe and composable requests to external services from within your API.
Provide Dependencies to Routes ๐ŸŸก Intermediate Inject services like database connections into HTTP route handlers using Layer and Effect.Service.
Validate Request Body ๐ŸŸก Intermediate Safely parse and validate an incoming JSON request body against a predefined Schema.
Generate OpenAPI Documentation ๐ŸŸ  Advanced Auto-generate OpenAPI/Swagger documentation from your Effect HTTP API definitions.

Making HTTP Requests

HTTP client patterns with @effect/platform.

Pattern Skill Level Summary
Parse JSON Responses Safely ๐ŸŸข Beginner Use Effect Schema to validate and parse HTTP JSON responses with type safety.
Your First HTTP Request ๐ŸŸข Beginner Learn how to make HTTP requests using Effect's HttpClient with proper error handling.
Add Timeouts to HTTP Requests ๐ŸŸก Intermediate Set timeouts on HTTP requests to prevent hanging operations.
Cache HTTP Responses ๐ŸŸก Intermediate Implement response caching to reduce API calls and improve performance.
Create a Testable HTTP Client Service ๐ŸŸก Intermediate Define an HttpClient service with separate 'Live' and 'Test' layers to enable robust, testable interactions with external APIs.
Handle Rate Limiting Responses ๐ŸŸก Intermediate Gracefully handle 429 responses and respect API rate limits.
Log HTTP Requests and Responses ๐ŸŸก Intermediate Add request/response logging for debugging and observability.
Model Dependencies as Services ๐ŸŸก Intermediate Abstract external dependencies and capabilities into swappable, testable services using Effect's dependency injection system.
Retry HTTP Requests with Backoff ๐ŸŸก Intermediate Implement robust retry logic for HTTP requests with exponential backoff.
Build a Basic HTTP Server ๐ŸŸ  Advanced Combine Layer, Runtime, and Effect to create a simple, robust HTTP server using Node.js's built-in http module.

Building Data Pipelines

Patterns for data ingestion, transformation, and processing.

Pattern Skill Level Summary
Collect All Results into a List ๐ŸŸข Beginner Run a pipeline and gather all of its results into an in-memory array.
Create a Stream from a List ๐ŸŸข Beginner Turn a simple in-memory array or list into a foundational data pipeline using Stream.
Run a Pipeline for its Side Effects ๐ŸŸข Beginner Execute a pipeline for its effects without collecting the results, saving memory.
Automatically Retry Failed Operations ๐ŸŸก Intermediate Build a self-healing pipeline that can automatically retry failed processing steps using a configurable backoff strategy.
Merge Multiple Streams ๐ŸŸก Intermediate Combine data from multiple streams into a single unified stream.
Process a Large File with Constant Memory ๐ŸŸก Intermediate Create a data pipeline from a file on disk, processing it line-by-line without loading the entire file into memory.
Process collections of data asynchronously ๐ŸŸก Intermediate Process collections of data asynchronously in a lazy, composable, and resource-safe manner using Effect's Stream.
Process Items Concurrently ๐ŸŸก Intermediate Perform an asynchronous action for each item in a stream with controlled parallelism to dramatically improve performance.
Process Items in Batches ๐ŸŸก Intermediate Group items into chunks for efficient bulk operations, like database inserts or batch API calls.
Turn a Paginated API into a Single Stream ๐ŸŸก Intermediate Convert a paginated API into a continuous, easy-to-use stream, abstracting away the complexity of fetching page by page.
Fan Out to Multiple Consumers ๐ŸŸ  Advanced Distribute stream data to multiple parallel consumers for processing.
Implement Backpressure in Pipelines ๐ŸŸ  Advanced Control data flow rates to prevent overwhelming slow consumers.
Implement Dead Letter Queues ๐ŸŸ  Advanced Route failed items to a separate queue for later analysis and reprocessing.
Manage Resources Safely in a Pipeline ๐ŸŸ  Advanced Ensure resources like file handles or connections are safely acquired at the start of a pipeline and always released at the end, even on failure.

Testing

Patterns for testing Effect-based applications.

Pattern Skill Level Summary
Test Effects with Services ๐ŸŸข Beginner Learn how to test Effect programs that depend on services by providing test implementations.
Your First Effect Test ๐ŸŸข Beginner Write your first test for an Effect program using Vitest and Effect's testing utilities.
Accessing the Current Time with Clock ๐ŸŸก Intermediate Use the Clock service to access the current time in a testable, deterministic way, avoiding direct calls to Date.now().
Mocking Dependencies in Tests ๐ŸŸก Intermediate Use a test-specific Layer to provide mock implementations of services your code depends on, enabling isolated and deterministic unit tests.
Use the Auto-Generated .Default Layer in Tests ๐ŸŸก Intermediate When testing, always use the MyService.Default layer that is automatically generated by the Effect.Service class for dependency injection.
Write Tests That Adapt to Application Code ๐ŸŸก Intermediate A cardinal rule of testing: Tests must adapt to the application's interface, not the other way around. Never modify application code solely to make a test pass.
Organize Layers into Composable Modules ๐ŸŸ  Advanced Structure a large application by grouping related services into 'module' layers, which are then composed together with a shared base layer.
Property-Based Testing with Effect ๐ŸŸ  Advanced Use fast-check with Effect for property-based testing of pure functions and effects.
Test Concurrent Code ๐ŸŸ  Advanced Test race conditions, parallelism, and concurrent behavior in Effect programs.
Test Streaming Effects ๐ŸŸ  Advanced Write tests for Stream operations, transformations, and error handling.

Observability

Logging, metrics, and tracing patterns.

Pattern Skill Level Summary
Debug Effect Programs ๐ŸŸข Beginner Learn techniques for debugging Effect programs using logging, tap, and cause inspection.
Your First Logs ๐ŸŸข Beginner Learn the basics of logging in Effect using the built-in structured logging system.
Add Custom Metrics to Your Application ๐ŸŸก Intermediate Use Effect's Metric module to instrument your code with counters, gauges, and histograms to track key business and performance indicators.
Compose Metrics into Effect Pipelines ๐ŸŸก Intermediate Add Metric.increment, Metric.trackDuration, and other metrics to your Effect pipelines without changing core logic.
Instrument and Observe Function Calls with Effect.fn ๐ŸŸก Intermediate Use Effect.fn to wrap, instrument, and observe function calls, enabling composable logging, metrics, and tracing at function boundaries.
Leverage Effect's Built-in Structured Logging ๐ŸŸก Intermediate Use Effect's built-in logging functions for structured, configurable, and context-aware logging.
Trace Operations Across Services with Spans ๐ŸŸก Intermediate Use Effect.withSpan to create custom tracing spans, providing detailed visibility into the performance and flow of your application's operations.
Create Observability Dashboards ๐ŸŸ  Advanced Design effective dashboards to visualize your Effect application metrics.
Export Metrics to Prometheus ๐ŸŸ  Advanced Expose application metrics in Prometheus format for monitoring and alerting.
Implement Distributed Tracing ๐ŸŸ  Advanced Set up end-to-end distributed tracing across services with trace context propagation.
Integrate Effect Tracing with OpenTelemetry ๐ŸŸ  Advanced Connect Effect's tracing spans to OpenTelemetry for end-to-end distributed tracing and visualization.
Set Up Alerting ๐ŸŸ  Advanced Configure alerts to notify you when your Effect application has problems.

Tooling & Debugging

Developer tools and debugging techniques for Effect.

Pattern Skill Level Summary
Read Effect Type Errors ๐ŸŸข Beginner Learn how to read and understand Effect's TypeScript error messages.
Set Up Your Effect Development Environment ๐ŸŸข Beginner Configure your editor and tools for the best Effect development experience.
Configure Linting for Effect ๐ŸŸก Intermediate Set up Biome or ESLint with Effect-specific rules for code quality.
Set Up CI/CD for Effect Projects ๐ŸŸก Intermediate Configure GitHub Actions to build, test, and deploy Effect applications.
Supercharge Your Editor with the Effect LSP ๐ŸŸก Intermediate Install the Effect Language Server (LSP) extension for your editor to get rich, inline type information and enhanced error checking for your Effect code.
Use Effect DevTools ๐ŸŸก Intermediate Debug Effect applications with specialized developer tools.
Profile Effect Applications ๐ŸŸ  Advanced Measure and optimize performance of Effect applications.
Teach your AI Agents Effect with the MCP Server ๐ŸŸ  Advanced Use the Effect MCP server to provide live, contextual information about your application's structure directly to AI coding agents.