Effect v4 Beta: February–May Recap
Effect v4 Beta launched February 18, 2026. Since then, the team has been shipping at a relentless pace inside the effect-smol repository.
If you’ve been following the weekly This Week In Effect summaries, you’ve seen each piece land individually. This post pulls it all together: what v4 set out to change, what has landed since launch, and where the beta has been moving over the past few months.
Effect v4 Beta is the most ambitious release we’ve made so far, with three major goals:
- a rewritten runtime
- smaller bundles
- unified package system
The core fiber runtime was rewritten from scratch with lower memory overhead, faster execution, and simpler internals. Many core modules were also rebuilt with bundle size in mind; for example, a minimal program using Effect, Stream, and Schema dropped from roughly 70 kB in v3 to about 20 kB in v4.
Effect v4 Beta also introduced unified versioning across the ecosystem. Instead of coordinating separate versions across Effect, @effect/platform, @effect/sql, @effect/rpc, and other packages, the v4 ecosystem now ships together under one version number. Many previously separate packages have also been consolidated into the core effect package, while platform-specific or provider-specific integrations remain separate.
Another important piece of the Effect v4 Beta is unstable modules. New functionality can now ship under effect/unstable/*, making it easier to experiment with new APIs inside the main package without committing to long-term stability too early.
Schema has been one of the most heavily worked areas of the beta. The changes span ergonomics, architecture, correctness, and DX.
-
API consolidation and renaming.
makeUnsafewas renamed back tomakefor consistency.ExtendableClasswas merged intoClass.Schema.Codec.ToAssertswas removed;Schema.assertsnow works with a directasserts(schema, input)call.SchemaParser.makeUnsafebecameSchemaParser.make. -
New constructors and utilities. Added
Schema.makeOption/SchemaParser.makeOptionfor constructing schema values wrapped inOption. AddedSchema.asClassto turn any schema into a class with static method support. AddedSchema.annotateEncodedfor annotating the encoded side of a schema. AddedSchema.resolveAnnotationsKey. AddedSchema.DurationFromStringfor parsing duration strings. AddedConfig.literalsas a convenience constructor forSchema.Literals. Added several missing*FromStringschemas:StringFromBase64,StringFromBase64Url,StringFromHex,StringFromUriComponent. -
Context-aware defaults. Schema decoding defaults can now require services, enabling context-aware default values. Defaults can also fail with
SchemaError. The mapping for schema defaults was switched to eager for more predictable behavior. -
Class improvements. Class constructors now accept
voidwhen all fields are optional. A compile-timeMissingSelfGenericerror has been added for Class APIs.ErrorClass/TaggedErrorClasstoString now matches native Error output. -
Schema property processing. Schema properties and elements can now be processed concurrently.
-
JSON Schema output. Same-type literal branches are collapsed into a single enum array.
compactEnumsnow supports multi-value enum branches. Added a JSON Schema custom annotation passthrough option for advanced use cases. -
Type ergonomics.
Structutility return types (e.g.,pick) now preserve the simplified shape instead of exposing rawPick<T, K>.~rebuild.outwas renamed toRebuild.withDecodingDefaultTypeKey/withDecodingDefaultTypewere added.FilterOutputwas expanded to support multiple failures and fullIssuesat paths. Reintroduced.valueonSchema.ArrayandSchema.NonEmptyArrayfor consistency with other collection wrappers (Chunk,HashSet, etc.). -
Bug fixes. Fixed
catch*combinators erasing unhandled error types. Fixed arbitrary constraints for exclusiveBigInt,Date, and integer number bounds. -
Model.Generatedrenamed toModel.GeneratedByDbfor clarity on which fields are generated by the database versus the application.
The IndexedDb module was merged in early April, bringing first-class browser persistence to Effect applications.
The module has been expanded significantly since landing:
- Streaming and offset support for IDB queries
- Compound index improvements and encoded types for IDB queries
- A
.reverse()method on IDB selects - A
rebuildAPI for IDB databases - An improved transaction API with customizable durability
.reactiveon IndexedDB.firstqueries for reactivity- Defaults for reactivity keys
Model.Classusable directly as IndexedDB schemas- Cached base IDB query builders for better performance
Cause.NoSuchElementErrorused for IDB.firstqueries (aligning with the broader Effect error model)- Fixed IDB entries transaction
- Fixed bulk writes in indexed DB transactions
-
HttpApi improvements. Added a code generation module (
HttpApi.gen). ReworkedHttpApiClientsourlBuilderuses schemas and client-shaped APIs. Renamed thewithResponseoption toresponseMode. AddeddisableCodecsoption toHttpApiEndpointconstructors. Fixed security middleware cache reuse. Allowed middleware to accept error arrays and fixed theHttpApi.Anyconstraint. MadeHttpApischema errors defects unless explicitly transformed. Added support for common string literals inHttpApiSchema.status. Included middleware errors inAtomHttpApiqueries and mutations. Fixed empty body decoding inHttpApiBuilder. FixedHttpApiBuildervoid responses incorrectly producing a non-empty body. -
HttpApi security. Added
HttpApiSecurity.httpfor passing custom HTTP authentication schemes, and added custom HTTP security scheme generation in the OpenAPI output. This enables authentication scenarios beyond the standard bearer/basic patterns. -
HttpApiTest. A new
HttpApiTestmodule was added for testingHttpApihandlers without a running server, with support for overriding group base URLs. -
HTTP client and server. Added a static file server. Added
expireCookieAPIs for HTTP cookies. AddedHeaders.removeManycombinator. ImprovedHttpClient.withRateLimiterwith automatic delay fromretry-afterheaders. Added support forform-urlencodedin the OpenAPI generator’s HTTP client format. -
Bug fixes. Fixed
httpschemaBodyJsonparseOptionsannotation. Returned a404for MCP HTTP requests with no session header. Removed the HTTP server log span counter. FixedRpcServerHTTP finalizer request IDs.
-
New capabilities. Added support for deferred responses in RPC. Added
RpcGroup.omit. Added arequireoption toAtomRpc.queryto make atoms serializable. AddedRpc.customfor defining custom RPC handlers with full control over the request/response lifecycle. AddedRpcWorkerProtocol service key (bug fix). AddedrpcConnectionHooks. -
Bug fixes. Fixed the entity proxy RPC handler context. Fixed
RpcServerHTTP finalizer request IDs. FixedRpcWorkerProtocol service key.
-
OpenAI. Added support for custom model/request properties in
openai-compat. Forwarded reasoning config. Fixed the OpenAI MCP tool integration. Restored OpenAI reasoning types. Updated the OpenAI schema strategy. Added OpenAI reasoning support. WidenedOpenAIFile.expires_atandstatus_detailsto acceptnull. Made strict mode configurable for tool definitions. Handled missingoutputarrays in OpenAI responses. Improved WebSocket error status reporting. -
Streaming. Fixed missing finish parts in
LanguageModelstreaming. Fixed tool output persistence in streamed chat history. -
Other providers. Fixed OpenRouter client HTTP referer header name. Fixed in-memory/in_memory prompt cache enum values for Amazon Bedrock.
Key fixes and improvements during the beta:
- Fixed workflow failures being squashed by suspension interrupts
- Isolated workflow suspension in
DurableDeferred.into - Fixed
Latch.release - Fixed parent pointer forwarding when spawning a child with
discard: true - The
DurableQueuemodule was also ported from v3 to v4, bringing persistent queue semantics to the beta.
-
New packages. Added
@effect/sql-pglitefor PGlite-backed SQL, expanding the SQL adapters available for lightweight and in-browser use cases. -
New APIs. Added
Sql.uniquefor queries that must return exactly one row. AddedKeyValueStore.layerSql. AddedmakeMsgPackfor configurablemsgpackroptions. Added support for.mtsand.mjsSQL migration files. -
PostgreSQL. Added a dedicated PG connection for
LISTEN. Switched topg_notifyinstead of rawNOTIFYinPgClient. Cleaned upsql-pgconstructors and layers. Guarded transaction acquire failures inPgClient.fromPool. -
Other fixes. Returned resolvers directly from
SqlModel.makeResolvers. Disabled SQL traces forEventLogandRunnerStorage. Fixed SQLfindAll/findNonEmptyrequest input typing.
-
New APIs. Added
Effect.abortSignalfor exposing the current fiber’s abort signal. AddedSocket.makefor low-level socket construction. Added theEffectablemodule for defining custom effect-like types. AddedEffect.acquireDisposablefor integrating with the TC39 Explicit Resource Management proposal (usingkeyword). PortedEffect.firstSuccessOffrom v3. Added aCryptoservice to@effect/platform, exposing a cross-platform cryptography API. AddedLayer.suspendconstructor. -
Type inference fixes. Used
NoInferinLayerconstructors to prevent type erasure. Fixed cache constructor inference by moving thelookupoption. Fixed type inference forEffect.retrywhen thetimesoption is provided. FixedStream.toQueuetypes. MadeUnify.unifywork with theLayermodule. -
Bug fixes. Fixed
Effect.forkScopedScope requirements. Fixed SIGINT listener not being removed until fiber exit. FixedTestClocklayer Scope requirement. FixedTestClocknanoseconds flooring beforeBigIntconversion. FixedformatJsoncircular reference handling. Fixed fiber lifetime metric start hook lifecycle. FixedSchedule.fixedimmediate catch-up for long-running iterations. FixedRequestResolverper-request instance leak (pendingBatches). Fixed logger string formatter quoting. FixedAtomRefnotify listener resubscribe, ensuring listeners correctly reattach after notification cycles. Clarified thatData.$is(tag)only checks the_tagfield. Emitted minimal docs in generated barrels to reduce bundle overhead.
-
New APIs. Added
Stream.broadcastNfor broadcasting to N downstream consumers. AddedSchedule.tapfor side-effecting on schedule steps. AddedStream.timeoutOrElse. AddedStreamservice accessors. -
Bug fixes. Fixed
Channel.decodeTextto correctly handle UTF-8 chunk boundaries. FixedStream.groupedWithinpartial batch flushing. FixedEffect.repeatto use the effect return value when using options. Optimized binary array generation from streams to reduce unnecessary copying.
-
New APIs. Added
Command.withHiddento hide subcommands from help output. Added a hidden flag primitive. Used a predicate forArgument.variadicvalidation. Made parent flag inheritance explicit viaCommand.withSharedFlags. Added default value support to integer and filePrompttypes, making CLI prompts more ergonomic when a sensible default exists. -
Bug fixes. Fixed unstable CLI boolean flags. Underlined active labels in CLI multi-select prompts. Fixed an issue with exported CLI completion types. Fixed
--log-level=valuefrom swallowing the next argument. Fixed global flag handling in mixed CLI contexts. UsedAnsi.blackBrightforWeakspans so--helpis readable on dark terminals. Replaced all hyphens in shell completion command names.
One of the most impactful changes during the beta: ServiceMap was renamed back to Context, realigning with v3 naming conventions. References were re-exported from effect/References. ServiceMap.Key was made covariant.
EventLog identity now string-encodes to base64.
Added availableShardGroups to ShardingConfig to prevent advisory lock conflicts. Added Kubernetes support for nullable lastTransitionTime values. Cleaned up ShardId.
-
JSDoc and documentation. Standardized JSDoc example imports across the entire codebase. Normalized category tags. Added a
standard-jsdocESLint rule that validates JSDoc links and is now enabled across the library. Vetted@sincetags between v3 and v4. Improved example titles and generated indexes. FixedStructsymbol links to preserve “Go to Definition” (F12) navigation in VSCode. Clarified filter annotation messages in Schema docs. Added a docs section on customizing schema error responses inHttpApi. Cleaned upAGENTS.md. Continued the JSDoc quality push with improvements acrossEffectcore APIs, corrected misleading API docs, and added a newSchedulecookbook. -
Removals. Removed
Effect.Yieldable, continuing the v4 API surface cleanup. RemovedSchema.Codec.ToAsserts. Removed a duplicatedstringifyCircularutility. Removed rulesync and cleanup patterns. Renameddtslintdirectories totypetest. -
Migration tooling. Previous API names are being added to migration maps for smoother upgrading. Two migration guides are available: the v3 to v4 Migration Guide and the Schema v4 Migration Guide.
Effect v4 is still in beta, so breaking changes may occur.
The launch set the foundation: a rewritten runtime, smaller bundles, unified versioning, a consolidated core package, and a path for experimental APIs.
Since then, the work has been about carrying that foundation across the ecosystem: porting modules, refining APIs, smoothing migrations, improving docs, and tightening the developer experience.
Thank you to everyone testing Effect v4 beta, reporting issues, trying migrations, and following along with the weekly updates.
In the meantime: install the beta, build something real, and share what works, what breaks, and what feels off. That feedback is what will shape the final Effect v4.
npm install effect@betapnpm add effect@betayarn add effect@betabun add effect@betaHappy Effecting. 🚀