effect-ts について
Effect-TSを使うTypeScript開発者向けのコーディングガイドです。導入済みのバージョンに合わせた実装とAPI確認を支援し、エラー、依存性注入、並行処理、リソース管理などを扱います。
主な機能
- 01Effect v3とv4の判別
- 02型付きエラー設計の案内
- 03サービスと依存性注入の解説
- 04並行処理とリソースライフサイクルの説明
- 05API確認と誤用の修正
活用シーン
- 01既存バージョンに合わせたEffectコード作成
- 02新規プロジェクトでのv4方式の選択
- 03誤ったAPIやバージョン混在の調査
- 04並行処理、リトライ、リソース管理の実装
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ tenequm/ skills --skill effect-tsインストール後、Claude Code で/effect-tsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
CHANGELOG.mdLICENSE.txtevals/evals.jsonreferences/cli.mdconcurrency.mdconfiguration.mdcore-patterns.mddatetime.mddependency-injection.mddistributed.mdeffect-ai.mderror-modeling.mdgraph.mdhttp.mdllm-corrections.mdmigration-async.mdmigration-v4.mdobservability.mdoptics.mdresource-management.mdretry-scheduling.mdrpc.mdschema.mdsql.mdstm.mdstreams.mdtesting.md詳細
Effect-TS
Effect は、型付きエラー、構造化された並行処理、依存性注入、組み込みの可観測性を備えた、本番環境向けソフトウェアを構築するための TypeScript ライブラリです。
バージョンの検出
Effect コードを書く前に、ユーザーが使用しているバージョンを検出してください。
# Check installed version
cat package.json | grep '"effect"'
- v4.x(推奨。Effect が目指している方向):
Context.Service、Effect.catch、Effect.forkChild、Schema.TaggedErrorClass - v3.x(安定版。本番環境で現在も広く使われています):
Context.Tag、Effect.catchAll、Effect.fork、Data.TaggedError
注:v4 のベータ版では一時期
ServiceMapモジュールが使われていましたが、2026-04-07 にContextへ戻されました(PR #1961)。ドキュメントや古いベータ版のコードにServiceMap.*があれば、現在のContext.*に相当します。v3 と v4 のどちらも"effect"からContextをインポートしますが、エクスポート内容は異なります(v4 はContext.Service、v3 はContext.Tag)。
新規プロジェクトでは v4 を優先してください。Effect が目指しているのは v4 です。既存のコードベースでは、インストールされているバージョンに合わせてください。依頼されない限り、v3 のコードを v4 の構文に書き換えないでください。バージョンが本当に不明な場合は v4 を既定とし、その旨を伝えてください。v4 はまだベータ版のため、正確なバージョン(4.0.0-beta.x)を固定し、API が時折変更されることを想定してください。
主なドキュメントソース
v4(主なソース):
- https://github.com/Effect-TS/effect-smol(v4 のソースと移行ガイド)
- https://github.com/Effect-TS/effect-smol/blob/main/LLMS.md(v4 の LLM ガイド)
v3(既存のコードベース向け):
- https://effect.website/docs(v3 安定版ドキュメント)
- https://effect.website/llms.txt(LLM トピックのインデックス)
- https://effect.website/llms-full.txt(大きなコンテキスト向けの全ドキュメント)
両バージョン共通:
AI のガードレール:重要な修正点
LLM の出力には、誤った Effect API が頻繁に含まれます。使用する前に、すべての API をリファレンスドキュメントで確認してください。
よくあるハルシネーション(両バージョン共通):
| 誤り(AI がよく生成するもの) | 正しいもの |
|---|---|
Effect.cachedWithTTL(...) | Cache.make({ capacity, timeToLive, lookup }) |
Effect.cachedInvalidateWithTTL(...) | cache.invalidate(key) / cache.invalidateAll() |
Effect.mapError(effect, fn) | パイプ内で Effect.mapError(fn) を使うか、Effect.catchTag を使う |
import { Schema } from "@effect/schema" | import { Schema } from "effect"(v3.10 以降およびすべての v4) |
import { JSONSchema } from "@effect/schema" | import { JSONSchema } from "effect"(v3.10 以降) |
| JSON Schema Draft 2020-12 | Effect Schema が生成するのは Draft-07 |
| "thread-local storage" | FiberRef(v3)/Context.Reference(v4)による「ファイバーローカルストレージ」 |
| ファイバーが「キャンセル」される | ファイバーは「中断」される |
| すべてのキューにバックプレッシャーがある | 有界キューのみ。スライディングキュー/ドロッピングキューにはありません |
new MyError("message") | new MyError({ message: "..." })(Schema エラーはオブジェクトを受け取ります) |
v3 固有のハルシネーション:
| 誤り | 正しいもの(v3) |
|---|---|
Effect.Service(関数呼び出し) | class Foo extends Effect.Service<Foo>()("id", {}) |
Effect.match(effect, { ... }) | Effect.match(effect, { onSuccess, onFailure }) |
Effect.provide(layer1, layer2) | Effect.provide(Layer.merge(layer1, layer2)) |
v4 固有のハルシネーション(AI が v3 と v4 を混同することがあります):
| 誤り(v4 のコードで v3 の API を使用) | 正しい記述(v4) |
|---|---|
Context.Tag("X")(v3 の形式) | Context.Service<X>(id) またはクラス構文 |
ServiceMap.Service / ServiceMap.Reference | 2026-04-07 に Context.Service / Context.Reference に名称が戻されました |
Effect.catchAll(fn) | Effect.catch(fn) |
Effect.fork(effect) | Effect.forkChild(effect) |
Effect.forkDaemon(effect) | Effect.forkDetach(effect) |
Data.TaggedError | Schema.TaggedErrorClass |
FiberRef.get(ref) | yield* References.X(Context.Reference) |
yield* ref(Effect としての Ref) | yield* Ref.get(ref)(Ref は Effect ではなくなりました) |
yield* fiber(Effect としての Fiber) | yield* Fiber.join(fiber)(Fiber は Effect ではなくなりました) |
Logger.Default / Logger.Live | Logger.layer(v4 の命名規則) |
Schema.TaggedError | Schema.TaggedErrorClass |
Schema.makeUnsafe(input) | Schema.make(input)(SchemaError をスローします)。インスタンスメソッド schema.makeOption(...)、schema.makeEffect(...) もあります |
ParseResult("effect" から) | SchemaIssue モジュールと SchemaError クラス。Schema.isSchemaError で型を絞り込みます |
HttpApiEndpoint.get(n, p).pipe(HttpApiEndpoint.setPath(...), setPayload(...), setSuccess(...)) | HttpApiEndpoint.get(n, p, { params, query, payload, success, error })(オブジェクトオプション形式) |
Otlp.layer({ url, serviceName }) | OtlpTracer.layer({ url, resource: { serviceName } }) + OtlpSerialization.layerJson + FetchHttpClient.layer |
import { HttpApi } from "@effect/platform"(v4) | import { HttpApi } from "effect/unstable/httpapi" |
| HttpApi エンドポイントのスキーマエラーはデフォルトで型付きエラーです | 現在の v4 ベータ版では、変換されない限りデフォルトで defect になります |
すべての修正を網羅した表は references/llm-corrections.md をご覧ください。
段階的な開示
タスクに関連するリファレンスファイルのみを読みます。
- エラーのモデリングまたは型付きエラー →
references/error-modeling.md - サービス、DI、または Layer の配線 →
references/dependency-injection.md - キーごとの動的レイヤー(テナントごとのリソース、
LayerMap) →references/dependency-injection.md - Effect を非 Effect フレームワーク(Hono/Express、
ManagedRuntime)に橋渡しする →references/dependency-injection.md - リトライ、タイムアウト、またはバックオフ →
references/retry-scheduling.md - ファイバー、フォーク、または並行処理 →
references/concurrency.md - リクエストのバッチ処理、N+1 の解消、DataLoader パターン →
references/concurrency.md - 複数プロバイダーへのフォールバック(
ExecutionPlan) →references/effect-ai.md/references/retry-scheduling.md - ストリーム、キュー、または SSE →
references/streams.md - ストリームのフレーミング(NDJSON / MessagePack のエンコード・デコード) →
references/streams.md - 子プロセスの実行/シェルコマンドの実行 →
references/concurrency.md - リソースのライフサイクルまたはクリーンアップ →
references/resource-management.md - 更新可能な値(ローテーションする認証情報、ポーリングされる設定) →
references/resource-management.md - 参照カウント方式の共有リソース(
RcRef/RcMap) →references/resource-management.md - スキーマの検証またはデコード →
references/schema.md - ブランド型/名目的型(
Brand) →references/schema.md - ログ、メトリクス、またはトレース →
references/observability.md - HTTP クライアントまたは API 呼び出し →
references/http.md - HTTP API サーバー →
references/http.md(クライアントとサーバーの両方を扱います) - ファイルのアップロード/マルチパートフォームデータ →
references/http.md - LLM/AI の統合 →
references/effect-ai.md - 設定、環境変数、シークレット →
references/configuration.md - SQL/データベースアクセス →
references/sql.md - コマンドラインアプリ →
references/cli.md - 型付きクライアント/サーバー RPC →
references/rpc.md - シャーディングされたエンティティ、永続的なワークフロー、イベントソーシング →
references/distributed.md - トランザクション状態(STM、
Tx*) →references/stm.md - 日付/時刻の処理 →
references/datetime.md - 不変のネストされた更新(オプティクス) →
references/optics.md - グラフ、依存関係の順序付け、最短経路、サイクル検出 →
references/graph.md - パターンマッチング(
Match) →references/core-patterns.md - リソースのプーリング(
Pool) →references/resource-management.md - ファイバーセット、SubscriptionRef、ワーカースレッド →
references/concurrency.md - Effect コードのテスト →
references/testing.md - プロパティベーステスト/スキーマからのデータ生成 →
references/testing.md - async/await からの移行 →
references/migration-async.md - v3 から v4 への移行 →
references/migration-v4.md - コア型、gen、pipe、実行 →
references/core-patterns.md - 誤りと正しい API の完全な一覧表 →
references/llm-corrections.md
基本的なワークフロー
- コードを書く前に
package.jsonからバージョンを特定します - 境界を明確にします。IO が発生する箇所を特定し、コアロジックは
Effectの値として保ちます - スタイルを選択します。順次処理には
Effect.genを、単純な変換にはパイプラインを使用します。v4 では、名前付き関数にEffect.fn("name")を優先して使用します - エラーを明示的にモデル化します。想定されるエラーは
Eチャネルで型付けし、バグは欠陥として扱います - サービスとレイヤーを使って依存関係をモデル化します。インターフェースに構築ロジックを含めないようにします
- ファイルや接続などを開閉するときは、
Scopeを使ってリソースを管理します - レイヤーを提供し、プログラムの境界(
NodeRuntime.runMainまたはManagedRuntime)でのみエフェクトを実行します - 使用する前にAPI が存在することを確認します。https://tim-smart.github.io/effect-io-ai/ またはソースドキュメントを参照してください
スターター関数セット
まずは次の約20個の関数から始めてください(公式推奨セットです)。
エフェクトの作成: Effect.succeed、Effect.fail、Effect.sync、Effect.tryPromise
合成: Effect.gen(v4では Effect.fn も)、Effect.andThen、Effect.map、Effect.tap、Effect.all
実行: Effect.runPromise、NodeRuntime.runMain(エントリーポイントに推奨)
エラー処理: Effect.catchTag、Effect.catch(v4)/Effect.catchAll(v3)、Effect.orDie
リソース: Effect.acquireRelease、Effect.acquireUseRelease、Effect.scoped
依存関係: Effect.provide、Effect.provideService
主要モジュール: Effect、Schema、Layer、Option、Result(v4)/Either(v3)、Array、Match
DI(v4): Context.Service、Context.Reference、Layer.effect、Effect.fn("name")
DI(v3): Context.Tag、Context.Reference
インポートパターン
常に "effect" からバレルインポートしてください。
import { Context, Effect, Schema, Layer, Option, Stream } from "effect"
関連パッケージは、パッケージ名からインポートしてください。v3とv4ではここが異なります。
// v4 (recommended) - platform transports still separate, but HttpApi / observability
// moved under effect/unstable/*
import { NodeRuntime } from "@effect/platform-node"
import { FetchHttpClient } from "effect/unstable/http"
import { HttpApi, HttpApiEndpoint, HttpApiGroup, HttpApiBuilder, HttpApiScalar } from "effect/unstable/httpapi"
import { OtlpLogger, OtlpSerialization, OtlpTracer } from "effect/unstable/observability"
// v3 (stable) companion packages
import { NodeRuntime } from "@effect/platform-node"
import { HttpClient } from "@effect/platform"
import { NodeSdk } from "@effect/opentelemetry"
バンドラーでツリーシェイキングが必要な場合を除き、深いモジュールのインポート(effect/Effect)は避けてください。
出力基準
- すべてのコード例にインポートを示します
- 複数ステップのロジックには
Effect.gen(命令型)を優先し、変換にはパイプラインを使います - v4では、名前付き関数に裸の
Effect.genではなくEffect.fn("name")を使います。スパン/スタックフレームが不要な内部ヘルパーにはEffect.fnUntracedを使います - ライブラリコード内では
Effect.runPromise/Effect.runSyncを呼び出しません。プログラムの境界でのみ呼び出します - CLI/サーバーのエントリーポイントには
NodeRuntime.runMainを使います(SIGINTを適切に処理します) - Effect以外のフレームワーク(Hono、Expressなど)にEffectを統合する場合は
ManagedRuntimeを使います - ジェネレーター内でエラーを発生させる場合は、必ず
return yield*を使います(TSが制御フローを理解できるようにします) - ポイントフリー/タシットな使い方は避けます。
Effect.map(fn)ではなくEffect.map((x) => fn(x))と書きます(ジェネリクスが消去されるため) - 依存関係グラフ(サービス、レイヤー、タグ)を明示します
- 設計上の判断に役立つ場合は、
Effect<A, E, R>の形を示します
エージェント品質チェックリスト
Effectのコードを出力する前に、次の点を確認してください。
- すべてのAPIが存在する(tim-smartのAPIリストまたはソースドキュメントで確認)
-
"effect"からインポートしている(@effect/schema、@effect/ioなどではない) - バージョンがユーザーのコードベースと一致している(v3とv4の構文)
- 想定されるエラーは
Eで型付けされ、想定外の失敗は欠陥として扱われる -
run*はライブラリコード内ではなく、プログラムの境界でのみ呼び出される -
acquireReleaseで開いたリソースはEffect.scopedでラップされている - 実行前にレイヤーが提供されている(不足する
Rの要件がない) - ジェネレーターの本体で
yield*を使っている(*なしのyieldではない) - ジェネレーター内でエラーを発生させる場合に
return yield*パターンを使っている