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 a caret peer dependency on the first Effect 4 release these packages support:
"peerDependencies": { "effect": "^4.0.2"}Any later 4.x satisfies it, so the packages use the one copy of effect your app already installs. Two
copies are what to avoid: a schema or service tag from one does not match the other, and the mismatch
surfaces as a type error deep inside a signature or a missing service at runtime. The test suite runs
against effect 4.0.5.
@effect-server-utils/unit-of-work declares @effect-server-utils/cqrs as a caret peer on the version
it was released with. The two are coupled through the DeferralSink contract, and while they are
pre-1.0 betas a caret only admits later betas of the same line, so they still move 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.