Skip to content
CAI
Software that uses CAICheck a score

nestjs/cqrs

65.7

Adequate · 20 September 2026

2.1k

lines of production code

TypeScript

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a CQRS (Command Query Responsibility Segregation) library for NestJS that manages command, query, and event buses with strong TypeScript typing. It provides infrastructure for handling domain events through aggregate roots, sagas, and async context propagation, while offering default pub/sub implementations and comprehensive error handling. The library is designed to integrate seamlessly with NestJS dependency injection and request-scoped providers.

How it got here

2017 — CQRS module rewrite and ESM migration

8 changes.

The project underwent a major infrastructure overhaul to support ESM and modern tooling, including a migration to Vitest and updated TypeScript configuration. The core CQRS module was completely rewritten to integrate with NestJS v2, introducing new buses, typed interfaces, and async context support while refining exception handling.

2018–2022 — CQRS module implementation

5 changes.

This period focused on building the core infrastructure for a Command Query Responsibility Segregation (CQRS) module, introducing new interfaces, decorators, and operators for commands, queries, and events. It also established default pub/sub implementations for consistent message handling and added Husky hooks to enforce code quality and commit standards.

2023–2025 — Aggregate root and async context support

5 changes.

This period focused on enhancing domain modeling capabilities by introducing the AggregateRoot mixin and storage for automatic event publishing. It also established robust async context propagation and strongly typed command/query results to improve type safety and state management across asynchronous boundaries. Comprehensive end-to-end and unit tests were added to validate these new CQRS patterns, handler lifecycles, and error handling mechanisms.

Features

Add ofType operator for filtering events by instance type

A new \ofType\ operator has been added to the operators module, allowing users to filter event streams based on their runtime instance type using \instanceof\. This operator accepts one or more class types implementing \IEvent\ and returns a stream that only emits events matching those types. It includes robust TypeScript type inference, ensuring that the output stream's type is correctly narrowed to the union of the provided classes, supporting both similar and disparate unions with proper type guards.

src/operators · high confidence

Added Husky commit and pre-commit hooks

The project now includes Husky configuration files to enforce code quality standards during development. A pre-commit hook runs \lint-staged\ via npx to lint staged files before each commit, and a commit-msg hook runs \commitlint\ to validate commit message format. These changes ensure consistent linting and conventional commit practices are applied automatically.

.husky · high confidence

Aggregate root storage for automatic event publishing integration

A new AggregateRootStorage class has been added to manage a registry of aggregate root types. This component allows the application to automatically inject publish and publishAll methods onto aggregate root prototypes, linking them to the central EventBus for seamless event dispatching.

src/storages · high confidence

Introduction of strongly typed command/query results and async context propagation

This change introduces new base classes for Commands and Queries in src/classes that utilize a specific symbol to enable strongly typed extraction of result types via utility types (CommandResult and QueryResult). Additionally, a new AsyncContext mechanism in src/scopes allows asynchronous context to be attached to and merged between command, query, or event objects, leveraging NestJS's ContextIdFactory to maintain context across asynchronous boundaries.

src/classes, src/scopes · high confidence

New CQRS decorators for commands, queries, events, and sagas

The \src/decorators\ module now provides a complete set of decorators (\@CommandHandler\, \@QueryHandler\, \@EventsHandler\, \@Saga\, and \@Publishable\) to define CQRS components. These decorators use \reflect-metadata\ to register handlers against specific command, query, or event types, supporting optional NestJS \InjectableOptions\ for dependency injection configuration. The \@Saga\ decorator specifically registers property keys as saga handlers, while \@Publishable\ merges event publishing capabilities into decorated classes via \AggregateRootStorage\.

src/decorators · high confidence

New WithAggregateRoot mixin for domain event handling

A new TypeScript mixin, WithAggregateRoot, is introduced in src/mixins to provide aggregate root functionality for NestJS-based domain models. This mixin enables classes to manage internal events, support auto-commit modes, and handle event application with optional history loading and handler invocation. It is exported via src/mixins/index.ts for use in other parts of the application.

src/mixins · high confidence

New default pub/sub implementations for commands, queries, and unhandled exceptions

The library now ships with dedicated default implementations for publishing commands, queries, and unhandled exceptions, in addition to the existing event pub/sub. Users can now leverage DefaultCommandPubSub, DefaultQueryPubSub, and DefaultUnhandledExceptionPubSub to handle their respective message types via RxJS subjects, providing a consistent pattern for all CQRS operations and error handling within the helpers directory.

src/helpers · high confidence

New query bus and handler interfaces for the CQRS module

The \src/interfaces/queries\ directory now exposes a set of new TypeScript interfaces that define the contract for the Command Query Responsibility Segregation (CQRS) implementation. Specifically, \IQueryBus\ defines the methods for executing queries with support for async context, \IQueryHandler\ provides a strongly typed interface for handling queries, and \IQueryPublisher\ outlines the contract for publishing queries. Additional interfaces such as \IQuery\, \IQueryResult\, and \QueryMetadata\ establish the foundational types for query definitions and metadata. These changes formalize the query execution flow within the CQRS module, enabling more robust type safety and context management for query handlers.

src/interfaces/queries · high confidence

Behavioural changes

Command bus and handlers now support typed results and async context

The command bus interface now exposes overloaded execute methods that accept an optional AsyncContext and return a typed Promise\<R\>, allowing command handlers to specify their return types explicitly. Command handlers have been refactored from a callback-based signature to a Promise-based one, with generic type parameters that infer the result type from the command class. Additionally, new interfaces for command metadata and command publishing have been introduced to support these capabilities.

src/interfaces/commands · high confidence

Event bus interfaces expanded to support context and batch publishing

The event bus interfaces in \src/interfaces/events\ have been significantly expanded to support more granular control over event publishing. The \IEventBus\ interface now accepts optional \dispatcherContext\ and \asyncContext\ parameters for both single (\publish\) and batch (\publishAll\) operations, allowing handlers to access specific execution contexts. Additionally, new interfaces \EventIdProvider\ and \MessageSource\ have been introduced to support custom event ID strategies and event bridging, while \IEventPublisher\ and \IEventHandler\ have been updated with improved generics and documentation to reflect these capabilities.

src/interfaces/events · high confidence

Major CQRS module rewrite with NestJS v2 integration and new capabilities

The CQRS module has been completely rewritten to integrate with NestJS v2, migrating from the legacy 'nest.js' package to standard '@nestjs/common' and '@nestjs/core' decorators (e.g., @Injectable, @Module). This update introduces a new QueryBus for handling queries alongside the existing CommandBus, adds an UnhandledExceptionBus to capture and publish errors from commands and events, and supports dynamic configuration via forRootAsync with useValue, useFactory, useClass, and useExisting options. The AggregateRoot now leverages mixins for context merging, and the EventBus and CommandBus now support custom publishers and async context propagation for better integration with Nest's request-scoped providers.

src · high confidence

ObservableBus refactored to use RxJS 6+ and exposes subject via getter

The ObservableBus utility has been updated to align with RxJS 6+ module structure, replacing deprecated import paths (e.g., 'rxjs/Subject') with the unified 'rxjs' entry point and removing the custom 'ofType' operator in favor of standard RxJS filtering. Additionally, the internal subject is now stored in a private field (\_subject$) and exposed to consumers via a public getter, allowing direct access to the underlying subject stream while maintaining encapsulation.

src/utils · high confidence

Project infrastructure overhaul and ESM migration

The repository has been restructured to support modern development workflows and module standards. TypeScript configuration has been updated to use the 'nodenext' module resolution and ES2021 target, facilitating an ESM migration, while the build output directory is now explicitly ignored from version control. The testing framework has shifted to Vitest, evidenced by new configuration files for unit and end-to-end tests, and linting/formatter tools have been standardized with Prettier and Commitlint. Additionally, the project documentation has been refreshed to reflect the official NestJS branding, and an MIT license file has been added to clarify usage rights.

(repo-wide) · high confidence

Refined exception messages and expanded exception coverage

The exception classes in the CQRS module have been updated to provide more specific, actionable error messages to users. The CommandHandlerNotFoundException and QueryHandlerNotFoundException now include the specific command or query name that was not found, rather than a generic message. Additionally, new exception classes have been introduced for invalid command, event, and query handlers, as well as for unsupported saga scopes, ensuring that users receive clear guidance on how to correctly annotate their handlers or configure their sagas. The InvalidSagaException message was also clarified to specify that sagas should return an Observable stream.

src/exceptions · high confidence

Reworked CQRS interfaces with new publishers and async configuration support

The public interface surface has been significantly expanded and restructured. New interfaces for command, query, and event publishers (ICommandPublisher, IQueryPublisher, IEventPublisher) and an unhandled exception publisher have been introduced, replacing the previous event-bus-centric model. The module configuration now supports async options (CqrsModuleAsyncOptions) with useFactory, useClass, useValue, and useExisting patterns, allowing for dynamic configuration. Additionally, the IAggregateRoot interface now includes methods for publishing events and managing uncommitted state, while the old EventObservable interface has been removed in favor of direct RxJS Observable usage in sagas and handlers.

src/interfaces · high confidence

Test coverage

Added end-to-end tests for core command/query flows and async context; Expanded test suite for CQRS patterns and async context.

Dependencies

Routine dependency updates across development tooling

This release updates a wide range of development dependencies, including the NestJS framework, TypeScript, ESLint, Prettier, Jest, and various type definitions. These changes keep the project's tooling and build environment current with upstream releases.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.

Score

  • CAI 69 → 66 (-3.6)
  • Rubric changed (rubric-2026.08.17 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 89 → 92 (+3.3)
  • Architecture 73 → 79 (+6.4)
  • Maturity 58 → 55 (-2.7)
  • Readiness 77 → 65 (-11.7)
  • Security 96 → 91 (-5.3)

Resolved (9)

  • Coverage not included — suite not readable by the collector
  • Dependency hygiene not measured — no supported dependency manifest was read
  • High CVE: [GHSA redacted] (package-lock.json)
  • High CVE: [GHSA redacted] (package-lock.json)
  • Medium CVE: [GHSA redacted] (package-lock.json)
  • Medium CVE: [GHSA redacted] (package-lock.json)
  • No exposed public API
  • Off-boarding risk: anonymized user #1
  • Test reliability not included

New (13)

  • Coverage not measured — JavaScript/TypeScript suite
  • Dependency hygiene PARTLY measured — npm pinning read, dependency currency not (the committed lockfile resolved no direct production dependency)
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no licence statement (README.md)
  • Documentation: no usage examples (README.md)
  • High CVE: [GHSA redacted] (package-lock.json)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • Inverted test pyramid
  • No assertions: should infer return types of disparate unions (src/operators/of-type.spec.ts)
  • No assertions: should infer return types of similar unions unions (src/operators/of-type.spec.ts)
  • Packages are published outside CI

Changes since last survey

  • 48 commits — 48 feature/other, 0 fixes

By area

  • (root) — 42 commits
  • (repo) — 4 commits
  • .circleci/config.yml — 2 commits

Notable commits

  • change: Merge pull request #2262 from nestjs/chore/esm-migration
  • change: Merge pull request #2284 from nestjs/renovate/cimg-node-24.x
  • change: Merge pull request #2323 from nestjs/renovate/typescript-7.x
  • change: Merge pull request #2350 from nestjs/renovate/cimg-node-24.x
  • change: chore(): release v12.0.0
  • change: chore(deps): update commitlint monorepo to v21.2.2 (#2343)
  • change: chore(deps): update commitlint monorepo to v21.2.3 (#2368)
  • change: chore(deps): update dependency @types/node to v24.13.4 (#2356)
  • change: chore(deps): update dependency @types/node to v24.13.5 (#2363)
  • change: chore(deps): update dependency @types/node to v24.13.6 (#2367)
  • change: chore(deps): update dependency lint-staged to v17.1.1 (#2331)
  • change: chore(deps): update dependency lint-staged to v17.2.0 (#2332)
  • change: chore(deps): update dependency lint-staged to v17.3.0 (#2336)
  • change: chore(deps): update dependency lint-staged to v17.4.1 (#2351)
  • change: chore(deps): update dependency lint-staged to v17.5.0 (#2354)
  • change: chore(deps): update dependency lint-staged to v17.5.1 (#2357)
  • change: chore(deps): update dependency oxlint to v1.75.0 (#2330)
  • change: chore(deps): update dependency oxlint to v1.76.0 (#2334)
  • change: chore(deps): update dependency oxlint to v1.77.0 (#2338)
  • change: chore(deps): update dependency oxlint to v1.78.0 (#2342)
  • …and 28 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

nestjs/cqrs was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 20 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 768c1f7a49a1194da0cf7394ff8fc995149b5e5c — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-28e75b8e3254.