Installation
Install
Section titled “Install”@effect-server-utils/cqrs and @effect-server-utils/authz are independent — install either or both.
@effect-server-utils/unit-of-work is optional and sits on top of the CQRS package: it supplies the
atomicity boundary a write-side use case declares, and gives subscribeAfterCommit a real commit to
wait for. Without it the event bus still works, running those handlers at the end of each dispatch.
pnpm add @effect-server-utils/cqrs effectpnpm add @effect-server-utils/authz effect
# optional, on top of cqrspnpm add @effect-server-utils/unit-of-work @effect-server-utils/cqrs effectnpm install @effect-server-utils/cqrs effectnpm install @effect-server-utils/authz effect
# optional, on top of cqrsnpm install @effect-server-utils/unit-of-work @effect-server-utils/cqrs effectyarn add @effect-server-utils/cqrs effectyarn add @effect-server-utils/authz effect
# optional, on top of cqrsyarn add @effect-server-utils/unit-of-work @effect-server-utils/cqrs effectThe Effect peer dependency
Section titled “The Effect peer dependency”effect is declared as an exact peer dependency on the beta these packages are built against:
"peerDependencies": { "effect": "4.0.0-beta.94"}Effect 4 is still in beta and its pre-release versions are not compatible with one another. Pinning
exactly is what keeps a mismatched effect in your lockfile from surfacing as a type error deep
inside a schema signature. When you move to a newer beta, expect to move every package with it.
@effect-server-utils/unit-of-work pins @effect-server-utils/cqrs the same way, and for the same
reason: the two are coupled through the DeferralSink contract, so they are released together.
TypeScript
Section titled “TypeScript”Every package ships ESM and CJS builds with declarations for each, and uses conditional exports. That
means moduleResolution has to be one that reads exports — "NodeNext", "Node16", or
"Bundler". The classic "Node" resolution will not find the types.
{ "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext", "target": "ES2022", "strict": true, "exactOptionalPropertyTypes": true, "noUncheckedIndexedAccess": true }}strict is not optional in practice: these packages lean on discriminated unions and conditional types
whose whole purpose is to make a wrong wiring fail to compile, and most of that evaporates without it.
Subpath imports
Section titled “Subpath imports”Every top-level module is also reachable on its own subpath, which is useful when you want one symbol without pulling the barrel:
import { Command } from "@effect-server-utils/cqrs";// orimport * as Command from "@effect-server-utils/cqrs/command";Two subpaths are deliberately not in their barrel:
import { checkSerializable } from "@effect-server-utils/cqrs/testing";import { PassThroughUnitOfWork } from "@effect-server-utils/unit-of-work/testing";The CQRS helpers derive sample values with a property-testing runtime; the unit-of-work ones are in-memory stand-ins for a datastore. Reached through a barrel either would ride into a consumer’s production bundle for something that only ever runs in a test, so each lives behind its own entry point. See Testing.
Next steps
Section titled “Next steps”- CQRS overview — messages, buses, and how an application is composed.
- Unit of work — the atomicity boundary, the driver you supply, and what it adds to the event bus.
- AuthZ overview — the config seam and the one call at the boundary.