effect-service

legacy3's avatarfrom legacy3

Generate new Effect-TS services with proper patterns. Use when creating new services, layers, or adding methods to existing services.

⭐1stars🔀0forks📁View on GitHub🕐Updated Jan 4, 2026

When & Why to Use This Skill

The Effect Service Generator is a specialized Claude skill designed to automate the creation of Effect-TS services and layers within TypeScript projects. It streamlines the development workflow by generating standardized boilerplate code, including interfaces, dependency injection tags, and layer implementations, ensuring that all services adhere to project-specific architectural patterns and naming conventions.

Use Cases

  • Rapidly bootstrapping new backend services: Automatically generate the interface, Context Tag, and Live Layer implementation for new domain logic.
  • Extending existing services: Efficiently add new methods and dependencies to established Effect-TS services while maintaining type safety and consistent patterns.
  • Standardizing architecture in monorepos: Enforce uniform file structures and naming conventions across large-scale TypeScript codebases to improve maintainability.
  • Implementing Dependency Injection: Simplify the setup of complex service dependencies using Effect-TS's Layer and Context modules without manual boilerplate.
  • Error Handling Standardization: Generate consistent error types using Data.TaggedError as part of the service generation process.
nameeffect-service
descriptionGenerate new Effect-TS services with proper patterns. Use when creating new services, layers, or adding methods to existing services.

Effect Service Generator

Generate Effect-TS services following project conventions.

Service Template

import * as Context from "effect/Context";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";

// Interface defines the contract
export interface MyServiceInterface {
  readonly doSomething: (
    input: InputType,
  ) => Effect.Effect<OutputType, MyError>;
}

// Tag for dependency injection
export class MyService extends Context.Tag("@wowlab/services/MyService")<
  MyService,
  MyServiceInterface
>() {}

// Live implementation
export const MyServiceLive: Layer.Layer<MyService, never, Dependencies> =
  Layer.effect(
    MyService,
    Effect.gen(function* () {
      const dep = yield* SomeDependency;

      return {
        doSomething: (input) =>
          Effect.gen(function* () {
            // implementation
            return result;
          }),
      } satisfies MyServiceInterface;
    }),
  );

Alternative: Effect.Service Pattern

For simpler services with built-in Default layer:

export class MyService extends Effect.Service<MyService>()("MyService", {
  dependencies: [Dep1.Default, Dep2.Default],
  effect: Effect.gen(function* () {
    const dep1 = yield* Dep1;
    const dep2 = yield* Dep2;

    return {
      doSomething: (input) => Effect.gen(function* () { ... }),
    };
  }),
}) {}

File Location

  • New service: packages/wowlab-services/src/internal/{domain}/
  • Re-export from: packages/wowlab-services/src/{Domain}.ts

Naming Conventions

  • Interface: {Name}Interface or {Name}Service
  • Tag: @wowlab/services/{Name}
  • Layer: {Name}Live or {Name}.Default
  • Errors: {Name}Error using Data.TaggedError

Instructions

  1. Ask what the service should do
  2. Identify dependencies needed
  3. Generate interface with typed methods
  4. Generate Layer implementation
  5. Add re-export to barrel file