Effect-TS는 무료 API를 제공한다: 프로덕션 앱을 위한 TypeScript의 누락된 표준 라이브러리
발행: (2026년 3월 29일 PM 11:09 GMT+9)
3 분 소요
원문: Dev.to
Source: Dev.to
Overview
Effect는 프로덕션 애플리케이션을 위한 표준 라이브러리를 제공하는 TypeScript 라이브러리입니다. 주요 기능은 다음과 같습니다:
- 타입이 지정된 오류 (어떤 오류가 발생할 수 있는지 정확히 알 수 있음)
- 의존성 주입 (컨테이너가 필요 없음)
- 구조화된 동시성 (fibers, 세마포어)
- 백오프가 포함된 재시도 정책
- 스키마 검증 (Zod와 비슷하지만 통합되어 있음)
- 스트림 (반응형 데이터 처리)
- 내장 트레이싱 및 메트릭스
TypeScript에는 타입이 지정된 오류, 의존성 주입, 재시도, 레이트 리밋, 구조화된 동시성을 다루는 표준 방법이 없습니다. Effect는 이러한 빈틈을 조합 가능하고 타입‑안전한 API로 메워줍니다.
Installation
npm install effect
Basic Usage
import { Effect, Console } from "effect";
const program = Effect.gen(function* () {
yield* Console.log("Hello from Effect!");
const result = yield* Effect.succeed(42);
yield* Console.log(`Result: ${result}`);
});
Effect.runPromise(program);
Typed Errors
import { Effect, Data } from "effect";
class NotFoundError extends Data.TaggedError("NotFoundError") {}
class DatabaseError extends Data.TaggedError("DatabaseError") {}
const findUser = (id: string): Effect.Effect =>
Effect.gen(function* () {
const user = yield* queryDatabase(id);
if (!user) {
return yield* new NotFoundError({ id });
}
return user;
});
// Handle specific errors
const program = findUser("123").pipe(
Effect.catchTag("NotFoundError", (e) =>
Effect.succeed({ name: "Default", id: e.id })
),
Effect.catchTag("DatabaseError", (e) =>
Effect.fail(new Error(`DB failed: ${e.cause}`))
),
);
Dependency Injection with Context & Layers
import { Effect, Context, Layer } from "effect";
class Database extends Context.Tag("Database") Effect.Effect }
>() {}
class Logger extends Context.Tag("Logger") Effect.Effect }
>() {}
const findUsers = Effect.gen(function* () {
const db = yield* Database;
const logger = yield* Logger;
yield* logger.log("Fetching users...");
return yield* db.query("SELECT * FROM users");
});
// Provide implementations
const DatabaseLive = Layer.succeed(Database, {
query: (sql) => Effect.succeed([{ id: 1, name: "Alice" }]),
});
const LoggerLive = Layer.succeed(Logger, {
log: (msg) => Effect.sync(() => console.log(msg)),
});
const MainLive = Layer.merge(DatabaseLive, LoggerLive);
Effect.runPromise(
findUsers.pipe(Effect.provide(MainLive))
);
Retries, Scheduling, and Concurrency
import { Effect, Schedule } from "effect";
const fetchData = Effect.tryPromise(() =>
fetch("https://api.example.com/data").then((r) => r.json())
);
// Retry with exponential backoff (up to 5 attempts)
const reliable = fetchData.pipe(
Effect.retry(
Schedule.exponential("1 second").pipe(
Schedule.compose(Schedule.recurs(5))
)
),
);
Running Tasks Concurrently
const tasks = [fetchUser(1), fetchUser(2), fetchUser(3)];
// Run all concurrently (max 3 at a time)
const results = yield* Effect.all(tasks, { concurrency: 3 });
Limiting Concurrency with a Semaphore
// Create a semaphore that allows up to 5 concurrent permits
const semaphore = yield* Effect.makeSemaphore(5);
// Wrap each task to acquire a permit before execution
const limited = tasks.map((task) => semaphore.withPermits(1)(task));
const results2 = yield* Effect.all(limited);
Resources
- GitHub: https://github.com/Effect-TS/effect
- Documentation: https://effect-ts.github.io/effect/
Feel free to explore the library for building robust, production‑grade TypeScript applications.