effect-patterns

Effect Patterns plugin for Claude Code - search and generate Effect-TS code patterns

View on GitHub
Author Paul J Philp
Namespace @PaulJPhilp/effect-patterns
Category development
Version 0.1.0
Stars 601
Downloads 6
self.md verified
Table of content

Effect Patterns plugin for Claude Code - search and generate Effect-TS code patterns

Installation

npx claude-plugins install @PaulJPhilp/effect-patterns/effect-patterns

Contents

Folders: commands, skills

Files: README.md

Documentation

A Claude Code plugin providing Effect-TS patterns, code generation, and search capabilities.

Features

๐Ÿ” Commands

๐ŸŽ“ Bundled Skills

This plugin includes 24 Claude Code skills covering Effect-TS patterns across all skill levels.

Categories

The skills cover comprehensive Effect-TS pattern categories:

Using Skills

Skills are automatically available after plugin installation. Claude will invoke them when relevant to your task.

See available skills:

/skills list

Manually invoke a skill:

/skill effect-patterns-error-handling

Skills are context-aware:

๐Ÿ”ง MCP Server

The plugin connects to the Effect Patterns MCP server providing:

Installation

From Repository

# Clone or pull the repository
git clone https://github.com/PaulJPhilp/EffectPatterns
cd EffectPatterns

# Install in Claude Code
/plugin install .claude-plugin/plugins/effect-patterns

Configuration

The plugin will connect to the MCP server at the configured endpoint. API key authentication is required by the HTTP API in production; the MCP transport itself does not validate keys.

For Contributors

Regenerating Skills

Skills are generated from pattern files in content/published/patterns/. To regenerate after pattern updates:

bun run generate:skills

This will:

  1. Read all patterns from content/published/patterns/
  2. Group patterns by category (applicationPatternId)
  3. Generate skills in both:
    • content/published/skills/claude/ (gitignored artifacts)
    • .claude-plugin/plugins/effect-patterns/skills/ (committed for distribution)

Workflow

# 1. Edit patterns
vim content/published/patterns/error-management/handle-errors-with-catch.mdx

# 2. Regenerate skills
bun run generate:skills

# 3. Commit updated plugin skills
git add .claude-plugin/plugins/effect-patterns/skills/
git commit -m "Update error-handling skill with improved examples"

# 4. Push to distribute
git push

Architecture

License

MIT

Included Skills

This plugin includes 5 skill definitions:

README

View skill definition

Effect Patterns Skills

This directory contains 24 auto-generated Claude Code skills for Effect-TS patterns.

Skills Included

All skills are organized by category and include beginner, intermediate, and advanced patterns:

For Developers

Regenerating Skills

When patterns in content/published/patterns/ are updated:

bun run generate:skills

This regenerates all skills in both:

Skill Structure

Each skill follows the format:

effect-patterns-{category}/
โ””โ”€โ”€ SKILL.md              # YAML frontmatter + pattern content

Skills are auto-discovered by Claude Code from this directory.

S

…(truncated)

effect-patterns-building-apis

Effect-TS patterns for Building Apis. Use when working with building apis in Effect-TS applications.

View skill definition

Effect-TS Patterns: Building Apis

This skill provides 13 curated Effect-TS patterns for building apis. Use this skill when working on tasks related to:


๐ŸŸข Beginner Patterns

Handle a GET Request

Rule: Use Http.router.get to associate a URL path with a specific response Effect.

Good Example:

This example defines two separate GET routes, one for the root path (/) and one for /hello. We create an empty router and add each route to it. The resulting app is then served. The router automatically handles sending a 404 Not Found response for any path that doesn’t match.

import { Data, Effect } from "effect";

// Define response types
interface RouteResponse {
  readonly status: number;
  readonly body: string;
}

// Define error types
class RouteNotFoundError extends Data.TaggedError("RouteNotFoundError")<{
  readonly path: string;
}> {}

class RouteHandlerError extends Data.TaggedError("RouteHandlerError")<{
  readonly path: string;
  readonly error: string;
}> {}

// Define route service
class RouteService extends Effect.Service<RouteService>()("RouteService", {
  sync: () => {
    // Create instance methods
    const handleRoute = (
      path: string
    ): Effect.Effect<RouteResponse, RouteNotFoundError | RouteHandlerError> =>
      Effect.gen(function* () {
        yield* Effect.logInfo(`Processing request for path: ${path}`);

        

...(truncated)

</details>

### effect-patterns-building-data-pipelines

> Effect-TS patterns for Building Data Pipelines. Use when working with building data pipelines in Effect-TS applications.

<details>
<summary>View skill definition</summary>

# Effect-TS Patterns: Building Data Pipelines
This skill provides 14 curated Effect-TS patterns for building data pipelines.
Use this skill when working on tasks related to:
- building data pipelines
- Best practices in Effect-TS applications
- Real-world patterns and solutions

---

## ๐ŸŸข Beginner Patterns

### Create a Stream from a List

**Rule:** Use Stream.fromIterable to begin a pipeline from an in-memory collection.

**Good Example:**

This example takes a simple array of numbers, creates a stream from it, performs a transformation on each number, and then runs the stream to collect the results.

```typescript
import { Effect, Stream, Chunk } from "effect";

const numbers = [1, 2, 3, 4, 5];

// Create a stream from the array of numbers.
const program = Stream.fromIterable(numbers).pipe(
  // Perform a simple, synchronous transformation on each item.
  Stream.map((n) => `Item: ${n}`),
  // Run the stream and collect all the transformed items into a Chunk.
  Stream.runCollect
);

const programWithLogging = Effect.gen(function* () {
  const processedItems = yield* program;
  yield* Effect.log(
    `Processed items: ${JSON.stringify(Chunk.toArray(processedItems))}`
  );
  return processedItems;
});

Effect.runPromise(programWithLogging);
/*
Output:
[ 'Item: 1', 'Item: 2', 'Item: 3', 'Item: 4', 'Item: 5' ]
*/

Anti-Pattern:

The common alternative is to use standard array methods like .map() or a for...of loop. While perfectly fine for simple, synchronous tasks,

…(truncated)

effect-patterns-concurrency

Effect-TS patterns for Concurrency. Use when working with concurrency in Effect-TS applications.

View skill definition

Effect-TS Patterns: Concurrency

This skill provides 20 curated Effect-TS patterns for concurrency. Use this skill when working on tasks related to:


๐ŸŸก Intermediate Patterns

Race Concurrent Effects for the Fastest Result

Rule: Use Effect.race to get the result from the first of several effects to succeed, automatically interrupting the losers.

Good Example:

A classic use case is checking a fast cache before falling back to a slower database. We can race the cache lookup against the database query.

import { Effect, Option } from "effect";

type User = { id: number; name: string };

// Simulate a slower cache lookup that might find nothing (None)
const checkCache: Effect.Effect<Option.Option<User>> = Effect.succeed(
  Option.none()
).pipe(
  Effect.delay("200 millis") // Made slower so database wins
);

// Simulate a faster database query that will always find the data
const queryDatabase: Effect.Effect<Option.Option<User>> = Effect.succeed(
  Option.some({ id: 1, name: "Paul" })
).pipe(
  Effect.delay("50 millis") // Made faster so it wins the race
);

// Race them. The database should win and return the user data.
const program = Effect.race(checkCache, queryDatabase).pipe(
  // The result of the race is an Option, so we can handle it.
  Effect.flatMap((result: Option.Option<User>) =>
    Option.match(result, {
      onNone: () => Effect.fail("

...(truncated)

</details>

### effect-patterns-concurrency-getting-started

> Effect-TS patterns for Concurrency Getting Started. Use when working with concurrency getting started in Effect-TS applications.

<details>
<summary>View skill definition</summary>

# Effect-TS Patterns: Concurrency Getting Started
This skill provides 3 curated Effect-TS patterns for concurrency getting started.
Use this skill when working on tasks related to:
- concurrency getting started
- Best practices in Effect-TS applications
- Real-world patterns and solutions

---

## ๐ŸŸข Beginner Patterns

### Race Effects and Handle Timeouts

**Rule:** Use Effect.race for fastest-wins, Effect.timeout for time limits.

**Good Example:**

```typescript
import { Effect, Option } from "effect"

// ============================================
// BASIC RACE: First one wins
// ============================================

const server1 = Effect.gen(function* () {
  yield* Effect.sleep("100 millis")
  return "Response from server 1"
})

const server2 = Effect.gen(function* () {
  yield* Effect.sleep("50 millis")
  return "Response from server 2"
})

const raceServers = Effect.race(server1, server2)

Effect.runPromise(raceServers).then((result) => {
  console.log(result) // "Response from server 2" (faster)
})

// ============================================
// BASIC TIMEOUT: Limit execution time
// ============================================

const slowOperation = Effect.gen(function* () {
  yield* Effect.sleep("5 seconds")
  return "Finally done"
})

// Returns Option.none if timeout
const withTimeout = slowOperation.pipe(
  Effect.timeout("1 second")
)

Effect.runPromise(withTimeout).then((result) => {
  if (Option.isNone(result)) {
    console.log("Operation timed o

...(truncated)

</details>

## Source

[View on GitHub](https://github.com/PaulJPhilp/EffectPatterns)