Effect-TS는 무료 API를 제공한다: 프로덕션 앱을 위한 TypeScript의 누락된 표준 라이브러리
발행: (2026년 3월 29일 오후 11:09 GMT+9)
3 분 소요
원문: Dev.to
Source: Dev.to
Overview
Effect는 프로덕션 애플리케이션을 위한 표준 라이브러리를 제공하는 TypeScript 라이브러리입니다. 주요 기능은 다음과 같습니다:
- 타입이 지정된 오류 (어떤 오류가 발생할 수 있는지 정확히 알 수 있음)
- 의존성 주입 (컨테이너가 필요 없음)
- 구조화된 동시성 (fibers, 세마포어)
- 백오프가 포함된 재시도 정책
- 스키마 검증 (Zod와 비슷하지만 통합되어 있음)
- 스트림 (반응형 데이터 처리)
- 내장 트레이싱 및 메트릭스
TypeScript에는 타입이 지정된 오류, 의존성 주입, 재시도, 레이트 리밋, 구조화된 동시성을 다루는 표준 방법이 없습니다. Effect는 이러한 빈틈을 조합 가능하고 타입‑안전한 API로 메워줍니다.
Installation
npm install effectBasic 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.