원클릭으로
effect-ts
Portable Effect v4 guidance for services, layers, schemas, HTTP, runtime boundaries, concurrency, configuration, and testing.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Portable Effect v4 guidance for services, layers, schemas, HTTP, runtime boundaries, concurrency, configuration, and testing.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use when the user asks for ASCII diagrams, timeline diagrams, flow diagrams, schedule explanations, stack traces, flamegraphs, or a single user-friendly ASCII output with Apple/Uber-like clean styling.
Queries local and remote files (Parquet, CSV, JSON) using DuckDB as SQL engine. Use for data analysis, file inspection, S3 queries, or answering questions about tabular data.
Non-obvious SolidJS patterns and reactivity gotchas. Use when authoring or refactoring .tsx/.jsx in a SolidJS app, designing stores/contexts, syncing server state, or debugging reactivity issues (stale reads, missing updates, extra re-runs).
| name | effect-ts |
| description | Portable Effect v4 guidance for services, layers, schemas, HTTP, runtime boundaries, concurrency, configuration, and testing. |
Use this skill for portable Effect v4 TypeScript code.
Effect v4 APIs may move while prereleases evolve. Generic HTTP modules live under effect/unstable/http and effect/unstable/httpapi in current v4 builds. Add a platform package only when its runtime or platform-specific services are required.
Prefer named imports from effect and its subpaths:
import { Context, Effect, Layer, Schema } from "effect";
import {
HttpClient,
HttpClientRequest,
HttpClientResponse,
} from "effect/unstable/http";
Avoid star imports, import aliases, unnecessary barrels, and namespace-based module organization. Follow the project's existing ESM export convention.
Prefer a standalone contract, Context.Service, and an explicit layer when dependencies should remain visible:
export interface UserRepository {
readonly find: (id: UserID) => Effect.Effect<User, UserNotFound>;
}
export class UserRepositoryService extends Context.Service<
UserRepositoryService,
UserRepository
>()("app/UserRepository") {}
export const UserRepositoryLayer = Layer.effect(
UserRepositoryService,
Effect.gen(function* () {
const database = yield* Database;
const find = Effect.fn("UserRepository.find")(function* (id: UserID) {
return yield* database.findUser(id);
});
return UserRepositoryService.of({ find });
}),
);
Effect.fn("Domain.method") for named or traced workflows.Effect.fnUntraced for reusable internal workflows that do not need spans.of(...) helper when available to validate implementations.Keep dependencies explicit:
export const AppLayer = FeatureLayer.pipe(
Layer.provide(DatabaseLayer),
Layer.provide(HttpLayer),
);
Layer.provide satisfies dependencies and hides the provided outputs.Layer.provideMerge satisfies dependencies and retains the provided outputs.Layer.mergeAll combines independent layers.Layer.unwrap builds a layer from an Effect when selection is dynamic.Layer.fresh opts out of normal layer memoization when a new resource instance is intentional.Effect.provideService when a sub-effect needs an already-constructed service value; do not build a one-off layer for that case.Choose schemas by behavior and boundary:
Schema.Struct for serializable data records and wire contracts.Schema.Class when runtime behavior, normalization, or class identity is useful.Schema.TaggedClass for discriminated runtime classes.Schema.TaggedErrorClass for typed expected failures.Schema.brand for nominal scalar types.export class ReadError extends Schema.TaggedErrorClass<ReadError>()(
"ReadError",
{
message: Schema.String,
cause: Schema.optional(Schema.Defect()),
},
) {}
Direct early failures may yield a yieldable error:
if (!record) return yield * new NotFoundError({ id });
Map lower-level failures with Effect error combinators rather than try/catch. Keep domain services independent of transport-specific errors and translate failures at the transport boundary.
Prefer decode-only defaults for external input. Use constructor defaults only when construction-time normalization is part of the domain value. Use Schema.Json for JSON values, Schema.Unknown for opaque values, and avoid Schema.Any outside documented unsafe boundaries.
See reference/schema.md.
Build requests explicitly, execute through an injected client, and decode with Schema:
const client = yield * HttpClient.HttpClient;
const response =
yield *
HttpClient.filterStatusOk(client).execute(
HttpClientRequest.post(url).pipe(
HttpClientRequest.acceptJson,
HttpClientRequest.bodyJson(body),
),
);
const result = yield * HttpClientResponse.schemaBodyJson(Response)(response);
Provide the platform client at the application boundary. Apply retries, redirects, authentication, and observability as client transformations rather than hand-written request loops.
HttpApiBuilder.group for typed handlers.See reference/httpapi.md.
Prefer one deliberately assembled ManagedRuntime at an actual non-Effect application boundary. Do not create a runtime merely to call one service from another Effect workflow.
For callbacks, use Effect.callback when completion is callback-driven. When callbacks must later re-enter a prepared runtime, capture the required runtime, services, and application context explicitly in a small boundary adapter.
See reference/runtime.md.
Effect.forkIn(scope) and Effect.forkScoped for scoped background work.Effect.all or Effect.forEach with explicit concurrency for fan-out.FiberSet and FiberMap for managed dynamic fibers; execute the Effect returned by their operations.Deferred.make in Effect code and unsafe constructors only at justified synchronous boundaries.Effect.callback for callback completion and cancellation cleanup.Use Config combinators for typed environment configuration and read configuration while constructing layers:
const AppConfig = Config.all({
port: Config.integer("PORT").pipe(Config.withDefault(3000)),
token: Config.string("TOKEN").pipe(Config.option),
});
Use ConfigProvider to supply test configuration. Do not mutate environment variables or global flags after dependent layers are built.
See reference/config.md.
See reference/testing.md.
Effect.void instead of Effect.succeed(undefined).DateTime.nowAsDate when an Effect workflow needs the current Date.JSON.parse wrapped in Effect.try.any, non-null assertions, unchecked casts, and broad hidden provisioning.null; reserve optional values for valid absence.