Effect

repository·main·Indexed 9 days ago

https://github.com/Effect-TS/effect

A library for building robust, maintainable, type-safe, and production-grade applications in TypeScript. It provides core abstractions for managing side effects, concurrency, and error handling, alongside tools for dependency injection (Context, Layer), structured concurrency (Fiber), asynchronous data processing (Stream), and type-safe schema validation (Schema). Requires TypeScript 5.9 or newer.

Tokens
302.4K
Snippets
701
Records
1.2K
Agent score
96%

What's inside Effect

  1. Overview of Effect core modules

    main

    The effect package provides several core modules for building robust applications:

    • Effect: The core abstraction for managing side effects, concurrency, and error handling.
    • Context: A lightweight dependency injection mechanism for passing services through computations.
    • Layer: A system for managing dependencies and modular resource allocation.
    • Fiber: Lightweight virtual threads with resource-safe cancellation.
    • Stream: An abstraction for asynchronous, event-driven data processing.
    • Schedule: A module for defining composable retry and repeat policies.
    • Scope: Manages the lifecycle of resources (acquisition and release).
    • Schema: A library for defining, validating, and transforming structured data with type-safe encoding/decoding.

    In v4, additional functionality like http, rpc, sql, and ai is available under the effect/unstable/* namespaces.

  2. Overview of Effect packages

    main

    Effect is a monorepo containing the core effect package and various integration packages for platforms, databases, AI, and UI frameworks.

    Note: All v4 packages are published under the beta tag on npm.

    Core and Platform Packages

    • effect: The core library.
    • @effect/platform-browser: Browser services.
    • @effect/platform-bun: Bun services.
    • @effect/platform-deno: Deno services.
    • @effect/platform-node: Node.js services.
    • @effect/platform-node-shared: Shared services for Node.js-compatible runtimes.

    SQL Clients

    Effect provides specialized SQL clients for various databases:

    • @effect/sql-clickhouse: ClickHouse
    • @effect/sql-d1: Cloudflare D1
    • @effect/sql-libsql: libSQL
    • @effect/sql-mssql: Microsoft SQL Server
    • @effect/sql-mysql2: MySQL
    • @effect/sql-pg: PostgreSQL
    • @effect/sql-pglite: PGlite
    • @effect/sql-sqlite-bun: SQLite via bun:sqlite
    • @effect/sql-sqlite-do: Cloudflare Durable Objects SQLite
    • @effect/sql-sqlite-node: SQLite via node:sqlite
    • @effect/sql-sqlite-react-native: SQLite in React Native
    • @effect/sql-sqlite-wasm: SQLite via WebAssembly

    AI Modules

    Providers for the Effect AI modules:

    • @effect/ai-anthropic: Anthropic
    • @effect/ai-openai: OpenAI
    • @effect/ai-openai-compat: OpenAI-compatible APIs
    • @effect/ai-openrouter: OpenRouter

    UI Framework Bindings (Effect Atom)

    • @effect/atom-react: React
    • @effect/atom-solid: SolidJS
    • @effect/atom-vue: Vue

    Tools and Integrations

    • @effect/opentelemetry: OpenTelemetry integration
    • @effect/vitest: Vitest testing helpers
    • @effect/docgen: Documentation generator
    • @effect/doctest: Runs JSDoc examples as Vitest tests
    • @effect/openapi-generator: Generates code from OpenAPI specifications
  3. Overview of @effect/vitest features

    main

    The @effect/vitest package provides an enhanced it function that extends standard Vitest functionality with support for Effect-specific testing needs. The main entry point is import { it } from "@effect/vitest".

    Key features include:

    • it.effect: Runs a scoped test with test services like TestClock and TestConsole.
    • it.live: Runs a scoped test using the live Effect environment (e.g., real system clock, real console).
    • it.layer: Shares a Layer between multiple tests.
    • it.prop: Runs property tests using Effect Schema values or FastCheck arbitraries.
    • it.flakyTest: Retries an Effect that might fail until it succeeds or hits a timeout.
    import { it } from "@effect/vitest"
  4. Working with AI modules in Effect

    main

    Effect's AI modules offer a provider-agnostic interface for interacting with various language models. This abstraction allows you to switch between different AI providers without changing your core business logic. Key capabilities include:

    • Text Generation: Generating raw text responses from a model.
    • Structured Decoding: Using Schema to decode model responses into typed, structured objects.
    • Streaming: Handling partial responses via streaming interfaces.
  5. Use Effect Type Performance to measure TypeScript diagnostics

    main

    The typeperf harness measures deterministic TypeScript diagnostics (instantiations, materialized types, and symbols) for specific fixtures. It is used as a regression gate to ensure that type-level optimizations do not negatively impact performance.

    Each suite has a shared baseline. The cost of a fixture is calculated as the delta between the fixture's metric and the suite's baseline metric:

    metric delta = fixture metric - suite baseline metric.

    Threshold files store the maximum allowed deltas for instantiations and types. Symbol deltas are informational and do not affect command status.

  6. What is Effect Schema and how to use it

    main

    Effect Schema is a TypeScript-first library used for defining data shapes, validating unknown input, and transforming values. It operates on two primary directions:

    • Decoding: Converting unknown external data (like API responses or config files) into typed, validated values.
    • Encoding: Converting typed values back into serializable formats (like JSON or FormData).

    Key use cases include defining types that provide both TypeScript types and runtime validators, validating input with clear error messages, and transforming values between domain types and serialization formats.

  7. Migrate FiberRef to Context.Reference in v4

    main

    In v4, FiberRef has been unified with Context.Reference. Fiber-local values and services now share the same mechanism.

    Key Changes:

    • Type Replacement: Use Context.Reference instead of FiberRef.
    • Type Guards: Use Context.isReference instead of FiberRef.FiberRefTypeId.
    • Accessing Context: Instead of FiberRef.currentContext, use Effect.context to read services and Effect.provideContext to override them.
    • Built-in References: Many built-in FiberRefs (like currentLogLevel, currentLoggers, currentTracerEnabled) are now Context.Reference values. You can access or provide them using Effect.provideService.
    • Concurrency: Inherited concurrency via FiberRef.currentConcurrency was removed. Pass concurrency explicitly to v4 combinators that support it.
    • Request Batching: The FiberRef.currentRequestCache and related batching settings were removed. Use RequestResolver.withCache to wrap a RequestResolver with an explicit cache.
  8. How @example tags work

    main

    The @example JSDoc tag allows you to provide usage examples for your source code.

    Key features:

    • Type Checking: All examples are automatically type-checked using tsc to ensure they are valid.
    • Execution: Examples are run using tsx.
    • Testing: You can use the Node.js assert module within your examples to perform on-the-fly testing of the code snippets.
  9. Two ways to run a Config

    main

    There are two primary patterns for executing configuration lookups:

    1. Yield in Effect.gen: This is the standard way. It automatically uses the ConfigProvider currently available in the service map (via Layers or provideService).
    2. Call .parse(provider) directly: This is useful for testing or when you want to use a specific provider instance regardless of the current environment context. The .parse method accepts only the provider.
    // 1. Yielding in a generator
    const program = Effect.gen(function*() {
      const host = yield* Config.string("HOST")
    })
    
    // 2. Direct parsing with a specific provider
    const host = Config.string("HOST")
    const result = Effect.runSync(host.parse(provider))