Skip to content

Latest commit

 

History

History

effect

README.md

effect

Effect is a library for building robust, maintainable, type-safe, and production grade applications in TypeScript.

The effect package is the core of the framework. It provides primitives for managing side effects, errors, concurrency, resources, and structured data, alongside a rich standard library.

Effect 4.x is a long-term support (LTS) release, with at least three years of bug and security fixes. If you are upgrading from Effect 3.x, follow the migration guide.

Installation

npm install effect

Requirements

  • TypeScript 5.9 or newer. TypeScript 7 is recommended for the best performance and compatibility with Effect's TypeScript tooling.

  • Node.js 22.19 or newer when running Effect on Node.js.

  • Strict type-checking: the strict flag must be enabled in your tsconfig.json:

    {
      "compilerOptions": {
        "strict": true
      }
    }

Links

  • Website: documentation, guides, and news.
  • Reference: API documentation for this package.
  • Discord: ask questions, share what you're building, and talk to the core team.
  • Community: meetups and events, or bring Effect to your own.
  • Issues: bug reports and feature requests.

Let's talk

Whether your team is considering Effect, rolling it out, or already running it in production, we'd love to hear from you: what you're building, what works, and what you need from Effect next.

  • Talk to the maintainers. Introduce your team on Discord or email contact@effectful.co. We're happy to connect privately on Slack or Discord for feedback and help with adoption.
  • Production support. We're exploring how to better support teams running Effect in production. If your organization has specific support needs, let's discuss them.
  • Adoption help. Our adoption partners offer implementation, consulting, team extension, training, and commercial support.

Overview

The effect package is a collection of modules. Some of the core ones:

Module Description
Effect The core abstraction for managing side effects, concurrency, and error handling in a structured way.
Context A lightweight dependency injection mechanism that enables passing services through computations without direct references.
Layer A system for managing dependencies, allowing for modular and composable resource allocation.
Fiber Lightweight virtual threads with resource-safe cancellation capabilities, enabling many features in Effect.
Stream A powerful abstraction for handling asynchronous, event-driven data processing.
Schedule A module for defining retry and repeat policies with composable schedules.
Scope Manages the lifecycle of resources, ensuring proper acquisition and release.
Schema A powerful library for defining, validating, and transforming structured data with type-safe encoding and decoding.

In v4, functionality that previously lived in separate packages ships inside effect under the effect/* namespaces, including http, http-api, rpc, cluster, workflow, cli, ai, sql, and reactivity.

JOSE

effect/jose provides unstable APIs for algorithm-bound JWKs, compact JWS and JWE, schema-typed signed and encrypted JWTs, and local or remote JWKS resolution, built on effect/crypto. Signatures use HS256/384/512, RS256/384/512, PS256/384/512, ES256/384/512 (P-256/P-384/P-521), or EdDSA (Ed25519); encryption uses dir with A256GCM. Jwk also generates symmetric keys, computes JWK thumbprints and thumbprint URIs, and imports and exports SPKI and PKCS#8 keys in DER or PEM form.

Apply an application-specific limit to untrusted token lengths before verification, decryption, or unverified decoding. These APIs decode tokens in memory and do not impose a global token-size limit.

import { Effect, Layer, Schema } from "effect"
import { Mac, SecureRandom, Signature } from "effect/crypto"
import { Jwk, Jwt } from "effect/jose"

const Claims = Schema.Struct({ sub: Schema.String })

const program = Effect.gen(function*() {
  const pair = yield* Jwk.generateKeyPair({ algorithm: "ES256", kid: "signing-key" })
  const signingKey = yield* Jwk.importPrivate(pair.privateKey, "ES256")
  const verificationKey = yield* Jwk.importPublic(pair.publicKey, "ES256")
  const token = yield* Jwt.sign(Claims, { sub: "user_1" }, signingKey, { typ: "JWT" })
  return yield* Jwt.verify(Claims, token, verificationKey, { typ: "JWT" })
}).pipe(
  Effect.provide(
    Layer.mergeAll(Mac.layerWebCrypto, Signature.layerWebCrypto).pipe(Layer.provide(SecureRandom.layerWebCrypto))
  )
)

For encrypted JWTs, use Jwt.encrypt and Jwt.decrypt. Both Jwe.decrypt and Jwt.decrypt accept effectful key resolvers for key rotation; resolver headers are unauthenticated and must be used only to select a key.

See third-party notices for test attribution.