Help us improve
Share bugs, ideas, or general feedback.
From effect-ts
Guides Effect's fiber-based concurrency: forking, Effect.all/Effect.forEach with concurrency limits, racing, interruption, Deferred, Queue, Semaphore, PubSub.
npx claudepluginhub andrueandersoncs/claude-skill-effect-ts --plugin effect-tsHow this skill is triggered — by the user, by Claude, or both
Slash command
/effect-ts:concurrencyThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Effect provides lightweight fiber-based concurrency:
Manages Effect concurrency with fibers for forking, joining, interruption, parallel Effect.all execution, and race conditions in Effect apps.
Provides expert guidance on Effect-TS for functional TypeScript including typed errors, dependency injection, Effect Layers, concurrency, pipelines, and production patterns.
Provides expert guidance on Effect-TS patterns including services, layers, error handling, service composition, and refactoring code with 'effect' imports. Covers Effect + Next.js integration.
Share bugs, ideas, or general feedback.
Effect provides lightweight fiber-based concurrency:
import { Effect } from "effect";
const results = yield * Effect.all([fetchUser(1), fetchUser(2), fetchUser(3)], { concurrency: "unbounded" });
const results = yield * Effect.all(tasks, { concurrency: 5 });
const results = yield * Effect.all(tasks);
const users = yield * Effect.forEach(userIds, (id) => fetchUser(id), { concurrency: 10 });
const program = Effect.gen(function* () {
const fiber = yield* Effect.fork(longRunningTask);
yield* doOtherWork();
const result = yield* Fiber.join(fiber);
});
const fiber = yield * Effect.fork(task);
const fiber = yield * Effect.forkDaemon(task);
const fiber = yield * Effect.forkIn(scope)(task);
const fiber = yield * Effect.forkWithErrorHandler(task, onError);
import { Fiber } from "effect";
const result = yield * Fiber.join(fiber);
const exit = yield * Fiber.await(fiber);
yield * Fiber.interrupt(fiber);
const maybeResult = yield * Fiber.poll(fiber);
const fastest = yield * Effect.race(fetchFromServer1(), fetchFromServer2());
const fastest = yield * Effect.raceAll([fetchFromCDN1(), fetchFromCDN2(), fetchFromCDN3()]);
const first = yield * Effect.raceFirst(task1, task2);
import { Deferred } from "effect";
const program = Effect.gen(function* () {
const deferred = yield* Deferred.make<string, never>();
const fiber = yield* Effect.fork(
Effect.gen(function* () {
const value = yield* Deferred.await(deferred);
yield* Effect.log(`Got: ${value}`);
}),
);
yield* Deferred.succeed(deferred, "Hello!");
yield* Fiber.join(fiber);
});
import { Queue } from "effect";
const program = Effect.gen(function* () {
const queue = yield* Queue.bounded<number>(100);
yield* Effect.fork(Effect.forEach([1, 2, 3, 4, 5], (n) => Queue.offer(queue, n)));
const items = yield* Effect.forEach(Array.from({ length: 5 }), () => Queue.take(queue));
});
const bounded = yield * Queue.bounded<number>(100);
const unbounded = yield * Queue.unbounded<number>();
const dropping = yield * Queue.dropping<number>(100);
const sliding = yield * Queue.sliding<number>(100);
import { PubSub } from "effect";
const program = Effect.gen(function* () {
const pubsub = yield* PubSub.bounded<string>(100);
const sub1 = yield* PubSub.subscribe(pubsub);
const sub2 = yield* PubSub.subscribe(pubsub);
yield* PubSub.publish(pubsub, "Hello!");
const msg1 = yield* Queue.take(sub1);
const msg2 = yield* Queue.take(sub2);
});
import { Effect } from "effect";
const program = Effect.gen(function* () {
const semaphore = yield* Effect.makeSemaphore(3);
yield* Effect.forEach(tasks, (task) => semaphore.withPermits(1)(task), { concurrency: "unbounded" });
});
import { Latch } from "effect";
const program = Effect.gen(function* () {
const latch = yield* Latch.make(false);
yield* Effect.fork(
Effect.forEach(
workers,
(worker) =>
Effect.gen(function* () {
yield* Latch.await(latch);
yield* worker.start();
}),
{ concurrency: "unbounded" },
),
);
yield* Latch.open(latch);
});
const fiber = yield * Effect.fork(longTask);
yield * Fiber.interrupt(fiber);
const critical = Effect.uninterruptible(
Effect.gen(function* () {
yield* beginTransaction();
yield* performOperations();
yield* commitTransaction();
}),
);
const program = Effect.uninterruptible(
Effect.gen(function* () {
yield* criticalSetup();
// This part can be interrupted
yield* Effect.interruptible(longOperation);
yield* criticalTeardown();
}),
);
Structured concurrency ensures child fibers are managed:
const parent = Effect.gen(function* () {
const child1 = yield* Effect.fork(task1);
const child2 = yield* Effect.fork(task2);
// If parent fails/interrupts, children are interrupted
yield* failingOperation();
});
// child1 and child2 automatically interrupted
Escape supervision with daemon:
const daemon = yield * Effect.forkDaemon(backgroundTask);
const withTimeout = task.pipe(Effect.timeout("5 seconds"), Effect.map(Option.getOrElse(() => defaultValue)));
const workerPool = Effect.gen(function* () {
const semaphore = yield* Effect.makeSemaphore(numWorkers);
return (task: Effect.Effect<A>) => semaphore.withPermits(1)(task);
});
const results =
yield *
Effect.all(tasks, {
concurrency: "unbounded",
mode: "either", // Collect all results
});
For comprehensive concurrency documentation, consult ${CLAUDE_PLUGIN_ROOT}/references/llms-full.txt.
Search for these sections: