effect-ts

Write idiomatic Effect v4 TypeScript following official best practices from effect-solutions and the Effect source. Use when writing, reviewing, or refactoring Effect code: services (ServiceMap.Service), layers and dependency injection, error handling (Schema.TaggedErrorClass), data modeling (Schema

By joelhooks · 659 installs

npx skills add joelhooks/effectts-skills --skill effect-ts

Source repository · Upstream listing

Effect TS (v4) Patterns from [effect solutions](https://effect.solutions) and the [Effect source](https://github.com/effect ts/effect). This covers the latest v4 APIs. Source First Rule When working in any repo that uses Effect ( effect or @effect/ in package/dependency files), reference the official Effect source before writing, reviewing, or refactoring Effect code. Do not rely on stale memory, blog posts, or high level docs alone. If the effect source tool is available, use it for status , hydrate , and search instead of hand rolled shell commands. First check for a repo local shallow source mirror at .agent sources/effect/ . If it is missing, create it before doing Effect work: mkdir p .agent sources && git clone depth 1 filter=blob:none https://github.com/effect ts/effect.git .agent sources/effect Keep the mirror out of product commits. If needed, add .agent sources/ to .git/info/exclude , not the project .gitignore , unless Joel explicitly wants it committed. Search the mirror for current patterns and APIs, especially under packages/effect/src/ and package tests/examples, before calling something an Effect best practice. Local Source References repo local Effect source mirror (canonical for current work): .agent sources/effect/ effect solutions (best practices, docs, examples): ~/Code/kitlangton/effect solutions/ fallback global Effect monorepo : ~/Code/effect ts/effect/ Search source for implementations: grep r "pattern" .agent sources/effect/packages/effect/src/ Effect.gen and Effect.fn Effect.gen provides sequential, readable composition (like async/await for Effect): Effect.fn adds call site tracing and named spans. Use for all service methods: ServiceMap.Service Define services as classes with a unique tag and typed interface: Implement with Layer.effect or Layer.sync , using Effect.fn for all methods: Rules: Tag identifiers must be unique. Use @app/ServiceName pattern Service methods should have R = never (dependencies via Layer, not method signatures) Use readonly properties See [references/services and layers.md](references/services and layers.md) for service driven development, test layers, layer memoization, and full composition patterns. Schema.Class and Branded Types Use Schema.Class for domain records. Brand all entity IDs and domain primitives: Use Schema.TaggedClass + Schema.Union for variants (OR types): See [references/data modeling.md](references/data modeling.md) for JSON encoding, Schema.Literals, validation, and full patterns. Schema.TaggedErrorClass Define domain errors with Schema.TaggedErrorClass . They are yieldable (no Effect.fail needed): Recover with catchTag / catchTags : See [references/error handling.md](references/error handling.md) for defects, Schema.Defect, and recovery patterns. Layer Composition Compose layers with Layer.provideMerge (incremental, flat types) and Layer.merge (parallel): Key rules: Store parameterized layers in constants (layer memoization by reference identity) Provide once at app entry, not scattered throughout code Use Layer.sync for synchronous implementations, Layer.effect for effectful ones Testing Quick Start Use it.effect for Effect based tests (provides TestContext with TestClock) Use it.live for real time / real clock Provide fresh layers per test to prevent state leakage Use it.layer only when sharing expensive resources across a suite See [references/testing.md](references/testing.md) for the full worked example and advanced patterns. Pipe for Instrumentation Anti Patterns Do Not Do Instead console.log(...) Effect.log(...) with structured data process.env.KEY Config.string("KEY") or Config.redacted("KEY") throw new Error() inside Effect.gen yield new TaggedError({...}) or Effect.fail(...) Effect.runSync(...) inside services Keep everything effectful Effect.catchAll(() = ...) losing type info Effect.catchTag / Effect.catchTags null / undefined in domain types Option<T with Option.match Option.getOrThrow(...) Option.match({ onNone, onSome }) or Option.getOrElse Effect.Service (v3) ServiceMap.Service (v4) Schema.TaggedError<T () (v3) Schema.TaggedErrorClass("Tag")("Tag", {...}) (v4) Scatter Effect.provide calls Provide once at app entry Call parameterized layer constructors inline Store layers in constants (memoization) Reference Files Load these as needed for deeper patterns: [Services & Layers](references/services and layers.md) : ServiceMap.Service, service driven development, test layers, layer memoization, provide vs provideMerge [Data Modeling](references/data modeling.md) : Schema.Class, branded types, variants, Match.valueTags, JSON encoding [Schema Decisions](references/schema decisions.md) : Schema.Class vs Struct vs TaggedClass decision flowchart, migration patterns [Error Handling](references/error handling.md) : Schema.TaggedErrorClass, catch/catchTag/catchTags, defects, Schema.Defect, TypeId/refail patterns [Testing](references/testing.md) : @effect/vitest setup, it.effect/it.live/it.layer, TestClock, Effect.flip, FiberRef isolation, worked example [HTTP Clients](references/http clients.md) : HttpClient, request building, response decoding, middleware, retries, typed API service [CLI](references/cli.md) : Command.make, Arguments, Flags, subcommands, worked task manager example [Config](references/config.md) : Config module, schema validation, ConfigProvider, Redacted, config layers [Processes & Scopes](references/processes.md) : Fork types, Scope.extend, Command for child processes, killable background tasks [Setup](references/setup.md) : tsconfig, Effect Language Service, project structure, module settings