Claude-skill-registry effect-ts
Effect-TS snippets, templates, and examples for Effect usage.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/effect-ts" ~/.claude/skills/majiayu000-claude-skill-registry-effect-ts && rm -rf "$T"
manifest:
skills/data/effect-ts/SKILL.mdsource content
Effect-TS Skill
Use this skill to add or modify Effect-TS code. It provides quick patterns for finding Effect usage and for composing, testing, and structuring Effect-based modules.
Find Effect usage fast
imports or type references.Effect
for generator-based composition.Effect.gen
for dependency wiring.Layer
for functional composition.pipe
orContext.Tag
for services.Context.GenericTag
,Schedule
,Stream
,Fiber
,Ref
for concurrency/streaming.Queue
Snippets
Basic Effect
import { Effect } from "effect"; const program = Effect.succeed("ok");
Generator composition
import { Effect } from "effect"; const program = Effect.gen(function* () { const value = yield* Effect.succeed(42); return value + 1; });
Error handling
import { Effect } from "effect"; const program = Effect.fail(new Error("boom")); const recovered = Effect.catchAll(program, () => Effect.succeed("fallback"));
Resource acquisition
import { Effect } from "effect"; const acquire = Effect.sync(() => ({ close: () => void 0 })); const use = (resource: { close: () => void }) => Effect.succeed(resource); const program = Effect.acquireUseRelease( acquire, use, (resource) => Effect.sync(() => resource.close()), );
Layer and service
import { Context, Effect, Layer } from "effect"; class Logger extends Context.Tag("Logger")<Logger, { log: (msg: string) => Effect.Effect<void> }>() {} const LoggerLive = Layer.succeed(Logger, { log: (msg) => Effect.sync(() => console.log(msg)), }); const program = Effect.gen(function* () { const logger = yield* Logger; yield* logger.log("hi"); });
Templates
Example with Contexts
We use Context tags to yield dependencies in our programs
import { Context, Effect, Layer } from "effect"; class Config extends Context.Tag("Config")<Config, { apiUrl: string }>() {} class Api extends Context.Tag("Api")<Api, { fetchStatus: () => Effect.Effect<string, Error> }>() {} const ConfigLive = Layer.succeed(Config, { apiUrl: "https://api.example.com" }); const ApiLive = Layer.effect(Api, Effect.gen(function* () { const config = yield* Config; return { fetchStatus: () => Effect.tryPromise({ try: async () => { const res = await fetch(`${config.apiUrl}/status`); if (!res.ok) throw new Error("Bad status"); return res.text(); }, catch: (cause) => cause as Error, }), }; })); const program = Effect.gen(function* () { const api = yield* Api; return yield* api.fetchStatus(); }); Effect.runPromise( program.pipe( Effect.provide(ApiLive), Effect.provide(ConfigLive), ), );
Always use Effect.fn with Generator Functions
When converting a function to use
Effect.fn and the generator function doesn't have any yield statements, add yield* Effect.void with a TODO comment:
export const myFunction = Effect.fn('myFunction')( function* (props: {...}): Generator<any, ReturnType, any> { // TODO: yield something or remove function* yield* Effect.void; // ... rest of function } );
Always yield* in Effect.fn
If there is no OTHER yield* in the generator function scope, then use
yield* Effect.void