プログラミング ソフトウェア 公開日 2026.05.15 更新日 2026.05.15

Effect-TS とは何か?TypeScript の関数型エコシステムとエラー・依存・並行を型で扱う設計

Effect-TS は `成功 / 失敗 / 必要な依存』 を型で表現する `Effect 型』 を中心に据えた TypeScript の関数型エコシステムです。エラーハンドリング・依存注入・スキーマ検証・リトライ / スケジュール・並行・Stream まで1つの基盤でカバーします。Scala ZIO の思想を TS に移植した形で、AI 時代の堅牢な TS バックエンドで注目されています。

先に要点

  • Effect-TS は `成功 / 失敗 / 必要な依存』 を型で同時に表す ` Effect<Success, Error, Requirements>』 という中核型を持つ TypeScript関数型エコシステム
  • 提供範囲は広い: ` 型付きエラーハンドリング』 `Schema(Zod 競合)』 `Context / DI(依存注入)』 `Retry / Schedule』 `並行 / Fiber』 `Stream』 `Layer によるアプリ構築』 など。`1つのエコシステムで堅牢な TS バックエンド』 を組める。
  • 思想は Scala の ZIO をベース。`例外を投げる代わりに型でエラーを表す』 `依存は型レベルで表す』 という関数型バックエンドの設計を TS に移植した形。
  • 本命の使い所は ` 堅牢性が重要な TS バックエンド / 複雑な非同期パイプライン / AI ワークフロー。学習コストは大きいが、`チーム全体で型と信頼性を引き上げたい』 案件で大きな価値を出す。

Effect-TS ってよく聞くけど、結局何をするライブラリ? Promise / async-await でいいんじゃないの? 関数型ってまた難しい話?』 ── 2023 年あたりから TypeScript の関数型コミュニティで急速に存在感を増した Effect-TS は、TS バックエンドの新しい標準』 を目指す野心的なプロジェクトです。

ざっくり言うと、Effect-TS成功・失敗・依存をすべて型で表現する Effect 型を中核に、TS で堅牢なバックエンドを書くためのエコシステム』</strong> です。Promise だと失敗の型が伝わらない』 関数の依存を引数で渡し続けるのが辛い』 リトライ / タイムアウト / 並行性を毎回手で書きたくない』 ── こうした TS バックエンド開発の悩みを、体系的に解決する ことを目指しています。

この記事では、2026 年 5 月時点の Effect-TS v3 系をベースに、仕組み・なぜ生まれたか・基本コード・採用判断軸 を整理します。 仕様は活発に変化しているので、最終確認は 公式 を見るのが安全です。

なぜ Effect-TS が生まれたか

`普通の Promise / async-await で何が困るのか』 が分かると、Effect の動機が見えます。

①エラーの型が消える

`Promise<User>』 は `成功した場合 User を返す』 を示すが、失敗時に何が起きるかは型に表れない。`どんなエラーが投げられるか』 を呼び出し側が知る術がない。

② try / catch だらけ

` catch でエラーを潰す or 投げ直す』 が散らばる。`どこでエラーが処理されているか』 が見えにくくなる。

③ 依存注入の手書き

` 関数が DB / API / Logger を必要とするとき、引数で受け取る』 のがチームで揃わず、`ファクトリ / シングルトン / グローバル変数』 が混在する。

④ リトライ / タイムアウトの手書き

` 失敗したら3回までリトライ、間隔は指数バックオフ』 のような典型処理を、案件ごとに書き直す。`本質的に同じコードが10箇所に散らばる』 状態。

Effect は これらすべてをEffect 型』 のエコシステムで体系的に扱う』 ことを目指したライブラリです。

Effect 型の中核

Effect の世界で最も大事な型が ` Effect<Success, Error, Requirements>』 です。

import { Effect } from 'effect';

// User を取ってくる Effect(成功時 User、失敗時 UserNotFound、依存 Database)
const getUser = (id: string): Effect.Effect<User, UserNotFound, Database> =>
  Effect.gen(function* () {
    const db = yield* Database;
    const user = yield* db.find(id);
    return user;
  });

3 つの型パラメータ

`Success』 = 成功時の値、`Error』 = 失敗時のエラー、`Requirements』 = 実行に必要な依存。` 何が起きうるか』 が型で完全に表される

遅延評価

` Effect は値ではなく `これからやることの記述』』。`Effect.runPromise(effect)』 で初めて実行される。`Promise はすぐ動く / Effect は明示するまで動かない』 という違い。

`Effect.gen』

`yield*』 を使った Generator 構文で、`async/await のように Effect を書ける』。`pipe』 メソッドチェインより読みやすい。

合成

`Effect.flatMap』 `Effect.map』 `Effect.zip』 で、Effect どうしを安全に合成できる。`成功時の処理』 `失敗時の処理』 が分離されたまま記述できる。

`実行を遅延し、型で失敗と依存を表現する』 のが、Effect の体験を一言で表す部分です。

何が嬉しいか — 具体例

Promise』 と Effect』 で同じ処理を書き比べると、違いが見えます。

Promise 版

async function getUser(id: string): Promise<User> {
  const db = getDatabase(); // 依存はグローバル / 引数のどれかでうやむや
  try {
    return await db.find(id);
  } catch (err) {
    // どんなエラーが投げられるかは型に出ない
    throw new UserNotFound(id);
  }
}

// リトライしたい場合は手書き
async function getUserWithRetry(id: string): Promise<User> {
  for (let i = 0; i < 3; i++) {
    try { return await getUser(id); }
    catch (e) { if (i === 2) throw e; }
  }
  throw new Error('unreachable');
}

Effect 版

const getUser = (id: string) =>
  Effect.gen(function* () {
    const db = yield* Database; // 依存は型レベルで明示
    return yield* db.find(id);  // 失敗時の型も追える
  });

// リトライは標準機能
const getUserWithRetry = (id: string) =>
  getUser(id).pipe(Effect.retry({ times: 3 }));

依存が型に出る

` Database を必要とすること』 が呼び出し側に型として伝わる。`関数を呼んでみないと依存が分からない』 が消える。

エラーが型に出る

`UserNotFound』 を返しうることが明示される。`どこかで例外が投げられている』 ではなく `この処理は UserNotFound で失敗する可能性がある』 と読める。

標準のリトライ / スケジュール

`Effect.retry』 `Effect.timeout』 `Effect.race』 `Schedule.exponential』 などが標準提供。`毎回手書きしていた処理』 が宣言的に書ける。

合成可能

` Effect は値として渡せる』 ので、関数で受け取り、加工して返すことができる。`高階の処理(`withLogging』 `withTimeout』)』 を再利用しやすい。

`型と合成可能性で堅牢な TS バックエンドを書く』 のが Effect の中心的な価値です。

エコシステムの広がり

Effect-TS は ` Effect 型 + 周辺ライブラリ群』 でひとつのエコシステムを形成しています。

機能 中身 競合 / 関連
Effect 型 / Fiber 中心 API、並行・キャンセル制御も統合 Promise + RxJS
Schema 型と検証を一体化したスキーマ Zod / Valibot
Context / Layer 依存注入(DI)とアプリ構築 InversifyJS / 手書き DI
Stream 非同期ストリーム RxJS / async iterator
Schedule リトライ / 周期実行 p-retry / 手書きループ
STM ソフトウェアトランザクショナルメモリ (独自領域)
HTTP HTTP クライアント / サーバ node-fetch / Hono

`1つのライブラリで TS バックエンドの基本ピースを全部カバーする』 のが Effect のスケールです。

いつ Effect-TS を選ぶか

`Effect を入れる価値が出る案件』 を整理します。

向いている

① 中〜大規模 TS バックエンド、② 失敗の種類が多く `どのエラーが起きうるか』 を型で追いたい、③ 複雑な非同期パイプライン(リトライ・並行・タイムアウトが頻出)、④ AI ワークフロー / 外部 API 連携が多い、⑤ 関数型を学習する文化があるチーム。

慎重に

① 小規模スクリプト / MVP、② チームに関数型の経験が薄い、③ 学習コストをかけられない案件、④ シンプルな CRUD API

部分採用も可能

` 全部を Effect で書く』 のではなく、`重要な非同期パイプラインだけ Effect』 という部分採用ができる。tRPC の Procedure 内で Effect を使う、のような構成も。

Zod / Valibot との関係

` Schema(Effect の検証ライブラリ)』 は Zod と直接競合する。`Effect エコシステムに統一したい』 なら Schema、`独立した検証だけ欲しい』 なら Zod、という棲み分け。

`堅牢な TS バックエンドにコミットできるチーム』 で大きく光るタイプの道具です。

ハマりやすいポイント

便利な反面、現場で踏みやすい注意点も整理します。

①学習コスト

` Promise の感覚で Effect を書こうとすると混乱する』。` Effect は値、実行するには runPromise が必要』などのルールに慣れる時間が要る。`数週間〜1ヶ月』 を見ておくと安全。

② 型エラーの読みづらさ

` 高度な型推論』 を使う関係で、型エラーが長く読みにくいことがある。`型シグネチャを明示的に書く』 ことで分かりやすくなる場面が多い。

③ チームの導入合意

` 1人が Effect で書いて、他は Promise』 だと混在して辛い。`チーム全体で採用するか / しないか』 を最初に決める必要がある。

④ パフォーマンス

` 軽量な処理に Effect は重め』。`単純な Promise 呼び出し1個』 を Effect 化するメリットは薄い。`複雑なパイプライン』 ほど Effect が活きる構造。

`良いプログラムを書ける可能性を上げる代わりに、書く側の学習コストを払う』 のが Effect の特徴です。

AI 時代の Effect-TS

AI 連携の文脈で Effect-TS の役割を整理します。

AI ワークフローの型安全

` LLM 呼び出し → 検証 → 再試行 → タイムアウト処理 → 結果統合』 のような複雑なパイプラインで、Effect の `エラー / リトライ / 並行』 機能がそのまま使える。` AI 系コードの落とし穴を構造的に減らす』

Schema での構造化出力

` AI に Effect Schema に従った JSON を返させる』 ことで、`AI 出力の検証 + 型推論』 を1つの定義で完結。Zod と同じ思想で、Effect エコシステムに統一できる。

Stream で AI レスポンス

` ストリーミング応答を Effect Stream で扱う』 ことで、`遅延・キャンセル・タイムアウト』 を統一的に書ける。

堅牢性が前提のサービス

` AI を使った業務システム』 は外部 API の信頼性が低めなので、`リトライ / 並行 / フォールバック』 のデフォルトが整っていることが価値になる。

`AI 時代の信頼性の高い TS バックエンド』 を作りたいときに、Effect-TS の価値は高まっています。

Effect-TS に関するよくある質問

Q. Effect-TS と Zod、どちらを選ぶべきですか?

A. 検証だけなら Zod、エコシステム全体を Effect で統一するなら Effect Schema』</strong>。<a href="/articles/what-is-zod-typescript-validation">Zod</a> は単体で完結する手軽さ、Effect Schema はEffect 型と統合される強み』 がそれぞれの長所です。

Q. Effect-TS は本番運用に耐えますか?

A. 耐えます。Effect は Scala の ZIO の TS 版という長年の設計を継承しており、VercelShopify・Microsoft などの一部チームでも採用事例があります。`採用人口は React ほどではない』 ので、コミュニティが大きい React 系ライブラリほどの情報量は期待できない、と認識しておくのが安全です。

Q. Promise から Effect への移行は大変ですか?

A. 概念の学習が中心』</strong>です。書き換え自体はそこまで大変ではないですが、Effect の世界観』 を理解しないと正しく書けません。`小さなコードから順に書き換える』 段階移行が現実的です。

Q. fp-ts との関係は?

A. Effect-TS は fp-ts の後継的な存在』</strong>として位置づけられています。同じ作者陣の一部が関わっていて、fp-ts より統合的でモダンな API』 を提供しています。`新規プロジェクトは Effect』 が2026 年現在の標準的な選び方です。

Q. Node.js / Bun / Deno で動きますか?

A. はい、すべてのランタイムで動きます。Web 標準 API ベースのコードが多く、BunDenoCloudflare Workers などのエッジランタイムでも問題なく使えます。

Q. 学習にどのくらいかかりますか?

A. 基本概念で 1〜2 週間、実プロジェクトで使いこなすまで 1〜2 ヶ月』</strong>が現実的な感触です。Promise / async-await に慣れている人ほど、最初の戸惑い』 が大きい傾向。`公式チュートリアル + Effect.gen』 から始めて、徐々に Layer / Schema / Stream に広げると進めやすいです。

Q. Effect-TS を学ぶ最短ルートは?

A. ① 公式の Getting Started』 を1セット、② Effect.gen + yield*』 で簡単な処理、③ Effect.retry / Effect.timeout』 で典型処理、④ Context / Layer』 で DI、⑤ Schema』 で検証、の5ステップが王道です。まず Effect.gen を書いて、yield* に慣れる』 のが最初のハードルです。

参考リンク

あとで見返すならここで保存

読み終わったあとに残しておきたい記事は、お気に入りからまとめて辿れます。