Effect 4 RC: A TypeScript toolkit that bundles errors, DI, and concurrency into one pipeline
Build production-ready applications in TypeScript. Effect Effect is a library for building reliable, maintainable, type-safe, and production grade applications in TypeScript.
At a glance
- What is it?
- Effect is a TypeScript library that packages typed errors, dependency injection, structured concurrency, scheduling, tracing, and schema validation into a single runtime. The 4.0 release candidate is available now, but only for teams ready to commit to its strict typing and its own way of doing things.
- Who is it for?
- Adopt Effect 4 if you are building a large TypeScript service that needs typed errors, dependency injection, and structured concurrency without stitching together separate libraries, and if you can enforce TypeScript strict mode and use TypeScript 5.9 or newer. Do not adopt it if you prefer incremental adoption, because Effect's model infects your types and your team must learn its vocabulary.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 14, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What Effect actually bundles
The README's phrase "production grade" appears twice, which signals ambition but also a warning: this is not a toy. The library expects you to adopt its idioms wholesale. There is no mention of a gradual adoption path. You either write Effect code or you do not.
The architecture: a runtime, not a utility belt
Effect's core mechanism is a single Effect type that represents a computation with a typed success value, a typed error, and a typed context for dependencies. The README describes this indirectly by naming the features: typed errors mean the compiler tracks what can fail; dependency injection means the context is explicit; structured concurrency means child fibers are tied to their parent. These are not separate modules bolted together. They are facets of the same runtime. When you compose effects, the runtime handles error propagation, interruption, and resource cleanup according to the structure you built. The documentation states that v4 is a release candidate on the main branch, so the architecture is still settling. The package list shows a monorepo with a core package and dozens of integrations, from SQL clients to AI providers. That breadth suggests the core is stable enough to build on, but the rc tag means breaking changes can still arrive.
Getting started: strict mode and the rc tag
Installation is one command: npm install effect@rc. The @rc tag is explicit; the README warns that v4 is a release candidate and the main branch contains v4 development. Requirements are strict: TypeScript 5.9 or newer, with TypeScript 7 recommended for best performance and compatibility with Effect's TypeScript tooling. The strict flag must be enabled in tsconfig.json. Node.js 18 or newer is the general minimum, but some integration packages demand more. For example, @effect/sql-sqlite-node requires Node.js 22.16 or newer. That means a project on Node 18 can use core Effect but may not be able to use every SQL client. The README does not give a minimal code example, so you cannot see the syntax from the README alone. You would need to visit effect.website for the API reference and guides. The absence of a quickstart snippet in the README is a minor friction point for a library this opinionated.
The package matrix: from SQL to AI
The monorepo publishes the core effect package plus integrations. The table lists platform packages for browser, Bun, Deno, and Node, and a large set of SQL clients: ClickHouse, D1, libSQL, MSSQL, MySQL, PostgreSQL, PGlite, SQLite variants, and React Native SQLite. There are also AI providers for Anthropic, OpenAI, OpenRouter, and an OpenAI-compatible adapter. This is a wide surface. The value is consistency: the same Effect abstractions for errors and concurrency apply whether you are querying Postgres or calling an LLM. The risk is that each integration is a separate package with its own release cadence and runtime requirements. The release list shows @effect/vitest and @effect/sql-sqlite-wasm publishing on the same date as the core, which suggests coordinated releases, but the README does not state how often integrations update. If you use an exotic SQL target like D1, you depend on that package's maintenance pace.
Where Effect 4 is the wrong tool
Effect's biggest limitation is its all-or-nothing nature. Because errors and dependencies are encoded in the types, every function that touches an Effect must be an Effect, or you must explicitly run it at the boundary. That is a boundary you cannot hide. For a small script or a microservice with one endpoint, the ceremony of typed errors and structured concurrency outweighs the benefit. The README also states that TypeScript 7 is recommended, not required. If your team is on TypeScript 5.9 and cannot upgrade, you lose the performance and tooling compatibility that the recommendation implies. Another failure mode: the rc tag. The main branch is under active development, and the latest release is 4.0.0-rc.112. That version number alone says the API can change between release candidates. If you adopt now, you must be prepared to track breaking changes. The strict flag requirement is also a hard gate: any codebase with loose type-checking cannot use Effect without a migration.
The alternative: composing separate libraries
The realistic alternative is to keep using standard TypeScript with dedicated libraries for each concern. For typed errors, you might use a Result type from a library like fp-ts, or just throw and catch. For dependency injection, you could use a container like Awilix or a manual factory pattern. For concurrency, you have Promise.all, worker threads, or a library like p-limit. For schema validation, you have Zod or io-ts. The difference in approach is fundamental. Effect replaces all of these with one coherent runtime, so error handling, DI, and concurrency share the same interruption and cleanup semantics. Separate libraries do not share semantics. A thrown error from a validation library does not automatically cancel a concurrent task. With Effect, the runtime knows the structure of your computation and can interrupt child fibers when a parent fails. That is the core trade-off: unified semantics versus modular flexibility. If you already have a stack that works, switching to Effect means rewriting your error handling and dependency wiring, not just adding a library.
Maintenance and upgrade cost
The README states that v4 is a release candidate, and all v4 packages are published under the rc tag on npm. That is a clear signal about stability. The v3 source code lives on a separate branch, and issues and pull requests meant for v3 should target that branch. That means the project maintains two major versions in parallel, which is a maintenance burden on the project, but it gives v3 users a place to file bugs. For adopters, the upgrade cost from v3 to v4 is not documented in the README. There is no migration guide mentioned. The license is MIT, which imposes no copyleft obligations, so you can use it in commercial products without releasing your source. The monorepo structure with many packages means you may need to update several packages together; the release list shows the core and integrations publishing on the same day, which suggests a coordinated release process, but you still have to verify that your chosen packages are compatible with your runtime. The README explicitly calls out Node.js version requirements per package, so check that before upgrading.
Editorial conclusion
Adopt Effect 4 if you are building a large TypeScript service that needs typed errors, dependency injection, and structured concurrency without stitching together separate libraries, and if you can enforce TypeScript strict mode and use TypeScript 5.9 or newer. Do not adopt it if you prefer incremental adoption, because Effect's model infects your types and your team must learn its vocabulary. Before committing, verify that all your runtime dependencies support your Node version, since some integration packages like @effect/sql-sqlite-node require Node.js 22.16 or newer, and check that the rc tag is stable enough for your release cycle. The v4 branch is still a release candidate, so pin your version and track the changelog before production.
Community notes