effect-service
Generate new Effect-TS services with proper patterns. Use when creating new services, layers, or adding methods to existing services.
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.
| name | effect-service |
|---|---|
| description | Generate 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}Interfaceor{Name}Service - Tag:
@wowlab/services/{Name} - Layer:
{Name}Liveor{Name}.Default - Errors:
{Name}ErrorusingData.TaggedError
Instructions
- Ask what the service should do
- Identify dependencies needed
- Generate interface with typed methods
- Generate Layer implementation
- Add re-export to barrel file