Skip to content
CAI
Software that uses CAICheck a score

ngxs/store

52.1

Adequate · 21 September 2026

11.5k

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 the NGXS state management library for Angular, providing a centralized store for application state with support for both traditional NgModule and modern standalone component architectures. It offers a comprehensive ecosystem of plugins to synchronize state with forms, router navigation, local storage, WebSocket connections, and Hot Module Replacement, while also including developer tools for debugging and logging. The core engine features advanced capabilities such as Angular Signal integration, immutable state operators, and robust Server-Side Rendering (SSR) stability mechanisms.

How it got here

2018 — Angular 17 migration and plugin expansion

25 changes.

The project underwent a major architectural shift to support Angular 17+, introducing standalone APIs, Angular Signals, and SSR stability across the core store and all plugins. This period also saw the release of several new plugins, including devtools, form, websocket, and HMR support, alongside a comprehensive restructuring of the Nx monorepo build and testing infrastructure.

2019 — operator expansion and testing infrastructure

24 changes.

This period focused on expanding the store's capabilities with new state operators for array manipulation and conditional logic, alongside a new execution strategy system to decouple operations from zone.js. Significant effort was dedicated to strengthening the codebase through comprehensive unit and type-level tests for the store, HMR plugin, and various plugins, while also refactoring internal modules to improve stability and developer diagnostics.

2020–2024 — Standalone API migration and test expansion

18 changes.

This period focused on modernizing the Ngxs architecture by introducing a comprehensive standalone API for store initialization and plugin registration, replacing legacy NgModule patterns. Concurrently, the team significantly expanded test coverage across core store, plugins, and schematics to ensure stability and type safety for new features like strongly-typed selectors and storage migrations.

2025–2026 — storage sync and test expansion

5 changes.

The project introduced cross-tab state synchronization for the storage plugin, enabling automatic rehydration of persisted state across browser tabs via StorageEvent listeners. This period also focused heavily on expanding test coverage, adding unit tests for action handlers and execution strategies, and establishing end-to-end and integration tests for Angular 22 compatibility.

Features

Add HMR lifecycle action classes

The HMR plugin now exposes explicit action classes for its lifecycle events. \HmrInitAction\ and \HmrBeforeDestroyAction\ are introduced to handle the initialization and pre-destroy phases of Hot Module Replacement, carrying a \Partial\<NgxsHmrSnapshot\>\ payload to manage state restoration and cleanup.

packages/hmr-plugin/src/actions · high confidence

Add cross-tab state synchronization for NgXS storage plugin

The storage plugin now includes a new \withNgxsStorageSync\ feature that keeps the store in sync across browser tabs or windows sharing the same storage origin. When another tab modifies a persisted key, this tab automatically rehydrates the corresponding state slice from the updated value by listening to native \StorageEvent\ notifications. The implementation uses a shallow merge for the default state key to preserve local slices (such as lazy-loaded features) that may not exist in the other tab's snapshot, and it reports deserialization errors via the Angular \ErrorHandler\ rather than failing silently. This feature is currently experimental and only supports built-in \localStorage\ and \sessionStorage\ engines.

packages/storage-plugin/src/features · high confidence

Add standalone API for Ngxs store initialization

Introduces a new set of standalone functions (\provideStore\, \provideStates\, \withNgxsPlugin\, \withNgxsPreboot\) in \packages/store/src/standalone-features\ that allow configuring the Ngxs store using Angular's modern \EnvironmentProviders\ API. This provides a standalone alternative to the traditional \NgxsModule.forRoot\ and \NgxsModule.forFeature\ NgModule patterns, enabling store setup directly within \bootstrapApplication\ or route providers without requiring an NgModule.

packages/store/src/standalone-features · high confidence

Added keys-migration schematic for the Storage Plugin

The storage-plugin schematics now include a new \keys-migration\ schematic (alias \ngxs-keys-migration\) that automatically updates \NgxsStoragePluginModule.forRoot\ configurations. This tool migrates the deprecated \key\ property to the new \keys\ property, handling cases where \key\ is a string literal by wrapping it in an array, and adds a default \keys: '\*'\ if the property is missing or the \forRoot\ call is empty.

packages/storage-plugin/schematics · high confidence

Expose storage plugin internals via a private subpackage

The storage plugin now exposes its internal implementation details through a new \@ngxs/storage-plugin/internals\ subpackage. This includes the \StorageEngine\ interface, configuration options (such as \persistOnInit\ and \migrations\), and utility functions for handling storage keys and explicit engine factories. This change allows advanced users and custom implementations to access these internal types and tokens directly, facilitating the creation of custom storage engines that wrap the default behavior or leverage internal key extraction logic.

packages/storage-plugin/internals · high confidence

Initial release of @ngxs/devtools-plugin

This change introduces the \@ngxs/devtools-plugin\ package, providing a devtools integration for the NGXS state management library. The diff establishes the foundational project structure, including the public API entry point (\index.ts\), Angular package configuration (\ng-package.json\), and build/test targets within the Nx workspace. It also includes necessary configuration files for TypeScript (\tsconfig.\*.json\), Jest testing (\jest.config.js\), and a basic README, making the plugin available for consumers to inspect and debug their NGXS stores.

(repo-wide) · high confidence

Initial release of @ngxs/hmr-plugin package

The @ngxs/hmr-plugin package is introduced to provide Hot Module Replacement (HMR) support for NGXS state management. This new library includes the necessary build configuration (ng-packagr), test setup (Jest), and TypeScript configurations to integrate into the workspace, along with a public API entry point and documentation.

packages/hmr-plugin · high confidence

Introduce @Selector decorator for class-based state selectors

The \@Selector\ decorator is now available in \packages/store/src/decorators/selector\, allowing developers to define state selectors directly as class properties. This decorator wraps the underlying \createSelector\ logic to provide memoization and automatically handles dependencies on other selectors or state tokens passed as arguments. It includes strict TypeScript type definitions to ensure that the arguments passed to the selector match the return types of its dependencies, improving type safety and developer experience when building complex state logic within NgXS store classes.

packages/store/src/decorators/selector · high confidence

Introduce @ngxs/hmr-plugin for Hot Module Replacement

Adds the @ngxs/hmr-plugin package, providing a Hot Module Replacement (HMR) solution for NGXS state management. The plugin includes an \hmr()\ bootstrap function that manages module lifecycle, state persistence via \HmrStorage\, and state restoration using \StateContext\. It exposes utilities like \hmrIsReloaded()\ to detect HMR reloads, manages the preservation of DOM hosts during updates, and cleans up old Angular styles. The package also defines lifecycle interfaces (\NgxsHmrLifeCycle\) and options for configuring behavior such as auto-clearing logs and deferred state loading.

packages/hmr-plugin/src · high confidence

Introduce Ngxs Store schematics for code generation and project initialization

The \packages/store/schematics\ location now provides a complete set of Angular CLI schematics to scaffold Ngxs state management code. This includes an \ng-add\ schematic that automatically installs Ngxs packages and configures the application for either standalone (using \provideStore\) or NgModule-based architectures, as well as dedicated schematics to generate \store\, \state\, and \actions\ files. A \starter-kit\ schematic is also included to scaffold a complete example store structure with authentication and dashboard states. All generated code and tests are designed to adapt to the target application's architecture, using \provideStore\ for standalone apps and \NgxsModule.forRoot\ for traditional module-based apps.

packages/store/schematics · high confidence

Introduce NgxsFormPlugin for Angular form state synchronization

The form-plugin package is added, providing the NgxsFormDirective and NgxsFormPlugin to synchronize Angular FormGroup state (value, status, errors, dirty/pristine) with the Ngxs store. The directive supports configurable debouncing via the ngxsFormDebounce input, allows clearing form state on destroy via ngxsFormClearOnDestroy, and exposes a ResetForm action to programmatically reset forms. The plugin handles state updates for form values, status, errors, and dirty flags, and supports a propertyPath parameter in UpdateFormValue for nested updates. The module exports both a deprecated NgModule-based API (NgxsFormPluginModule) and a new standalone provider function (withNgxsFormPlugin).

packages/form-plugin/src · high confidence

Introduce WebSocket plugin for NGXS store integration

Adds a new WebSocket plugin that enables NGXS stores to manage WebSocket connections via actions. Users can now dispatch ConnectWebSocket, SendWebSocketMessage, and DisconnectWebSocket actions to control the connection lifecycle, while the plugin automatically dispatches WebSocketConnected, WebSocketDisconnected, and WebSocketMessageError actions to reflect connection state and handle errors. The plugin supports configurable options such as URL, protocol, binary type, reconnection attempts, and custom serializers/deserializers, and is available through both the legacy NgxsWebSocketPluginModule.forRoot() and the new standalone withNgxsWebSocketPlugin() provider function.

packages/websocket-plugin/src · high confidence

Introduces new state operators for array manipulation and conditional logic

The \packages/store/operators/src\ module now exports a comprehensive set of new state operators to simplify immutable state updates. Users can now use \append\ to add items to arrays, \insertItem\ to place items at specific indices, and \removeItem\/\removeItems\ to delete elements by index or predicate. Array transformations are supported via \updateItem\ and \updateItems\, which allow replacing or transforming elements while preserving referential equality for unchanged items. Additionally, \compose\ enables chaining multiple operators in a single atomic update, \iif\ allows conditional state changes based on a predicate or boolean, and \safePatch\ provides a null-safe alternative to \patch\ for uninitialized state slices.

packages/store/operators/src · high confidence

Introduction of ActionDirector for programmatic action registration

The store now includes an \ActionDirector\ service that allows actions to be attached to the state registry programmatically via an \attachAction\ method, which returns a \detach\ function for cleanup. This new capability is supported by the introduction of \ActionDef\ and \ActionType\ symbols in the actions module, which are re-exported from the internals package to define the structure of actions handled by the director.

packages/store/src/actions · high confidence

NGXS Store v4 introduces standalone APIs, Angular Signals support, and SSR stability features

The store has been refactored to support Angular's standalone architecture, deprecating the legacy \NgxsModule.forRoot\ and \forFeature\ methods in favor of new \provideStore()\ and \provideStates()\ functions. A new \selectSignal\ method allows components to access state as Angular Signals, while the \Actions\ stream now exposes detailed lifecycle context (Dispatched, Successful, Canceled, Errored) via \ActionContext\. To improve Server-Side Rendering (SSR) stability, a new \withNgxsPendingTasks\ feature tracks asynchronous actions to prevent premature app stabilization. Additionally, the store now includes a configurable \NgxsUnhandledErrorHandler\ for centralized error management and a \registerNgxsPlugin\ function for dynamic plugin registration.

packages/store/src · high confidence

New NgxsFeatureModule and NgxsRootModule for standalone feature initialization

Two new Angular modules, NgxsFeatureModule and NgxsRootModule, have been added to the store package. These modules serve as entry points to trigger the initialization of standalone features and the root store, respectively, by invoking their corresponding initializer functions from the standalone-features module during module construction.

packages/store/src/modules · high confidence

New RxJS operators for filtering Ngxs actions by status

The store now provides a suite of RxJS operators in \packages/store/src/operators/of-action.ts\ to filter actions based on their lifecycle status. Users can use \ofAction\ to catch all actions, \ofActionDispatched\ for immediate dispatch, \ofActionSuccessful\ for successful completions, \ofActionCanceled\ for cancellations, \ofActionErrored\ for errors, and \ofActionCompleted\ for any final state (success, cancel, or error). The \ofActionCompleted\ and \ofActionErrored\ operators return an \ActionCompletion\ object containing the action, result status, and any error details, enabling more precise handling of action outcomes. Additionally, a new \leaveNgxs\ operator is available to run subscriptions outside the Ngxs execution context.

packages/store/src/operators · high confidence

New build and publishing tooling for schematics and package distribution

The tools directory now includes new scripts to support the build and release process. \build-schematics.mjs\ compiles and packages Angular schematics, ensuring the schematics version matches the root package version. \publish-dev-builds.ts\ and \publish-tagged-builds.ts\ handle publishing development (short-sha) and tagged releases to npm, respectively. \set-metadata.ts\ copies metadata (version, repository, funding, etc.) from the root package.json to all built packages and updates their peer dependencies. \utils.ts\ provides shared utilities for executing commands, retrieving package information, and publishing packages with a retry mechanism.

tools · high confidence

New decorator implementations for Actions, Selectors, and State inheritance

The store decorators have been re-implemented to support advanced configuration and type safety. The @Action decorator now accepts an array of action types to handle multiple actions with a single handler and includes a runtime check to prevent its use on static methods. The @SelectorOptions decorator allows selector options to be applied at both the method and class levels. Additionally, the @State decorator now supports option inheritance, automatically merging options from parent state classes into child states.

packages/store/src/decorators · high confidence

New execution strategy system to decouple store operations from zone.js

The store now uses a pluggable execution strategy system to control how async operations interact with Angular's zone.js. By default, operations run outside the Angular zone to avoid unnecessary change detection, but observable behaviors (like \store.select\ or \actions.subscribe\) are brought back inside the zone. Applications that do not rely on zone.js for change detection can opt into the \NoopNgxsExecutionStrategy\ via the new \withNgxsNoopExecutionStrategy\ provider, which bypasses zone interactions entirely for better performance in standalone or non-zone environments.

packages/store/src/execution · high confidence

New interactive tutorial for building a Todo app with NGXS

Added a new interactive tutorial in the \tutorials/create-app\ location that guides users through creating a Todo application using the NGXS state management library for Angular. The tutorial is built on the Tutorial Kit and Astro, featuring step-by-step lessons on installing NGXS via schematics, defining actions and states, handling actions to fetch data, and creating selectors to query state in components. It includes starter code, solution files, and exercises to help users learn core NGXS concepts like Actions, State, and Selectors.

tutorials/create-app · high confidence

New strongly-typed selector utilities and improved selector behavior

This update introduces new selector utilities (\createModelSelector\, \createPickSelector\, \createPropertySelectors\) that provide strongly-typed access to store state, allowing developers to select multiple properties or create property-based proxies with better type inference. The core \createSelector\ function now supports improved type checking and metadata handling. Additionally, selector behavior has changed: \createPickSelector\ no longer throws errors when selecting from unregistered states (using optional chaining), and the system now defaults to not injecting container state unless explicitly configured via \injectContainerState\ options. These changes enhance type safety and reduce runtime errors in common scenarios.

packages/store/src/selectors · high confidence

New utility functions for dispatch, selection, and lazy loading

The store package now exports several new utility functions in its public API to simplify common patterns. Developers can use \dispatch\ to create action dispatchers that return an \AsyncReturnType\, enabling both observable subscriptions and async/await syntax for better control flow. The \select\ utility provides a concise way to create Angular signals from store selectors without manually injecting the store, while \createDispatchMap\ and \createSelectMap\ allow generating maps of these dispatchers and signals from action/selector definitions. Additionally, a \lazyProvider\ utility is introduced to support lazy-loading state providers at the route level, helping to reduce initial bundle size by deferring state registration until specific routes are activated.

packages/store/src/utils · high confidence

Router plugin restructured for standalone APIs and enhanced selectors

The router plugin has been refactored to support Angular's standalone provider model via the new \withNgxsRouterPlugin()\ function, while the legacy \NgxsRouterPluginModule\ is now deprecated. The public API now exposes a comprehensive set of tree-shakable selectors for accessing router data, including query params, fragments, params, data, and titles for both the primary and named outlets. Additionally, the plugin introduces a \RouterDataResolved\ action to capture state after route resolution and improves performance by avoiding redundant state updates when the router snapshot has not changed.

packages/router-plugin/src · high confidence

Behavioural changes

@Select decorator now requires explicit opt-in support

The @Select decorator no longer works automatically; it now requires explicit opt-in via \withNgxsSelectDecoratorSupport()\ in \provideStore(...)\ or \NgxsSelectDecoratorSupportModule.forRoot()\ alongside \NgxsModule.forRoot()\. This change addresses server-side rendering issues where the decorator previously pinned the state tree globally between requests, and ensures resources are properly cleaned up when the root module is destroyed. The decorator remains deprecated, and users are encouraged to migrate to \store.select()\, the functional \select()\, or \store.selectSignal()\.

packages/store/src/decorators/select · high confidence

Added explicit TypeScript type definitions and validation configuration for the store package

The store package now includes a dedicated \types\ directory containing explicit TypeScript declaration files (\index.d.ts\) and configuration files (\tsconfig.json\, \.eslintrc.js\) to enforce strict type checking. This setup configures the TypeScript compiler with strict null checks and specific path mappings to internal store modules, while integrating ESLint with the \eslint-plugin-expect-type\ plugin to validate public API typings, ensuring that the exported types remain accurate and stable for consumers.

packages/store/types · high confidence

Build process now copies LICENSE files to all package directories

The build system has been updated to automatically copy the root LICENSE file into each of the seven distribution packages (store, devtools-plugin, form-plugin, logger-plugin, router-plugin, storage-plugin, and websocket-plugin) during the build process. This ensures that licensing information is included in every published package artifact.

build · high confidence

Centralized error and warning messages for state configuration

The store now uses a dedicated configuration file to define all validation error messages and warnings. This centralizes user-facing feedback for issues such as invalid state names, missing decorators, mutual exclusivity of action options (\cancelUncompleted\ vs \ignoreUncompleted\), invalid initialization order, and unsupported patching operations, ensuring consistent and clear diagnostics when configuration errors occur.

packages/store/src/configs · high confidence

Deprecation of experimental pending tasks export

The \withExperimentalNgxsPendingTasks\ function in the \@ngxs/store/experimental\ package is now deprecated. It serves as a thin wrapper that simply delegates to the standard \withNgxsPendingTasks\ export in the main \@ngxs/store\ package, indicating that the feature is no longer experimental and should be imported from the primary package instead.

packages/store/experimental · high confidence

DevTools plugin now supports standalone APIs and Ivy compatibility

The devtools plugin has been refactored to support Angular's standalone APIs by introducing the \withNgxsReduxDevtoolsPlugin\ function, which allows configuration via \EnvironmentProviders\ alongside the deprecated \NgxsReduxDevtoolsPluginModule.forRoot\. This change also ensures Ivy compatibility by removing the module from imports and using generic \ModuleWithProviders\ types. Additionally, the plugin now correctly handles action errors by sending state updates even when exceptions are thrown, and it enables time-traveling for navigation actions by synchronizing the router state during state jumps.

packages/devtools-plugin/src · high confidence

Enforced commit message linting and staged file linting

The development workflow now automatically enforces coding standards before changes are committed. A new commit-msg hook runs commitlint to validate that commit messages follow the project's conventional commit format, while a pre-commit hook runs lint-staged to automatically lint only the files that are being staged for commit.

.husky · high confidence

Integration app migrated to Angular standalone components and SSR

The integration application has been updated to use Angular standalone components, replacing the previous module-based architecture. This change introduces support for both RxJS Observables and Angular Signals for state management via the NGXS store, allowing developers to verify compatibility with both patterns. Additionally, the app now supports Server-Side Rendering (SSR) using the new Angular SSR infrastructure, with dedicated browser and server application configurations and an Express-based Node server for handling requests.

integration · high confidence

Internal router plugin options and symbols extracted

The internal implementation details for the router plugin, specifically the \NgxsRouterPluginOptions\ interface, \NavigationActionTiming\ enum, and related injection tokens (\ɵUSER\_OPTIONS\, \ɵNGXS\_ROUTER\_PLUGIN\_OPTIONS\), have been moved into a new \internals\ package. This change isolates these symbols, likely to support better tree-shaking and internal module structure, while exposing them via a dedicated entry point for internal consumption.

packages/router-plugin/internals · medium confidence

Migrate E2E testing from Cypress to Playwright

The project's end-to-end test runner has been switched from Cypress to Playwright. This change is reflected in the new \playwright.config.ts\ configuration file and the removal of Cypress-specific setup, updating the testing infrastructure for integration tests.

(repo-wide) · high confidence

New plugin infrastructure and action type caching

The \packages/store/plugins/src\ module has been introduced, providing the core plugin system including the \NgxsPlugin\ interface, the \withNgxsPlugin\ registration method, and the \NGXS\_PLUGINS\ injection token (now deprecated in favor of the new API). This location also introduces \InitState\ and \UpdateState\ actions for internal state management. Additionally, performance optimizations are applied to action handling: \getActionTypeFromInstance\ now uses a \WeakMap\ to cache resolved action types per class, avoiding V8 megamorphic cache penalties, and \getValue\/\setValue\ skip expensive split/reduce operations for single-segment paths.

packages/store/plugins/src · high confidence

New standalone API for development warnings with deprecated NgModule support

The store now provides a standalone \withNgxsDevelopmentOptions()\ function to configure development features like unhandled action warnings, replacing the deprecated \NgxsDevelopmentModule.forRoot()\ API. This change introduces the \NgxsUnhandledActionsLogger\, which warns when actions are dispatched without handlers, while maintaining backward compatibility through the legacy NgModule-based provider.

packages/store/src/dev-features · high confidence

Refactored Logger Plugin with ActionLogger extraction and injection context support

The logger plugin implementation has been restructured to extract action logging logic into a dedicated \ActionLogger\ class, improving code organization and maintainability. A key behavioral change is that the user-provided \filter\ function is now executed within the Angular injection context, allowing users to inject services to determine whether an action should be logged. The plugin also introduces a \disabled\ option to easily turn off logging (useful for production) and ensures that action payloads are only printed if they contain defined properties. Additionally, the module exports a modern \withNgxsLoggerPlugin\ provider function alongside the deprecated \NgxsLoggerPluginModule.forRoot\ for Angular standalone compatibility.

packages/logger-plugin/src · high confidence

Refactored internal action dispatch and state management architecture

The internal store implementation has been restructured to improve performance, reliability, and developer experience. Action dispatching now uses a new \InternalDispatcher\ and \InternalActionHandlerFactory\ that support \ignoreUncompleted\ and \cancelUncompleted\ options, allowing for better control over concurrent actions and preventing race conditions. State updates are now strictly guarded against mutations after an action handler completes, with a warning logged in development mode if a handler attempts to modify state asynchronously. The system also introduces a dedicated unhandled error handler for RxJS errors, ensuring that errors in action handlers are properly reported via Angular's \ErrorHandler\ rather than being silently swallowed or crashing the application. Additionally, lifecycle hooks like \ngxsOnChanges\ and \ngxsAfterBootstrap\ are now managed by a \LifecycleStateManager\ that correctly handles injector destruction, preventing memory leaks and errors during teardown.

packages/store/src/internal · high confidence

Runtime warnings for undecorated or misconfigured state classes in development

The store now validates state classes at runtime in development mode to ensure they are properly decorated. It warns if a state class lacks an \@Injectable()\ or \@Service()\ decorator, and warns if a state uses \@Service()\ with the default \autoProvided: true\, which can cause synchronization issues with the NGXS instance. This helps developers catch configuration errors early before they lead to injection failures or unexpected behavior in production.

packages/store/src/ivy · high confidence

Storage plugin internals exposed and SSR safety improved

The storage plugin now exposes its internal engine tokens (LOCAL\_STORAGE\_ENGINE, SESSION\_STORAGE\_ENGINE) and key management logic through a new subpackage, allowing for more granular configuration of storage backends. This change significantly improves Server-Side Rendering (SSR) compatibility by adding robust guards that check for ngServerMode and the existence of localStorage/sessionStorage globals before accessing them, preventing crashes in Node.js or crawler environments. Additionally, the plugin now reports serialization, deserialization, and quota errors via the Angular ErrorHandler instead of failing silently, and supports factory functions for custom storage engines.

packages/storage-plugin/src · high confidence

Store internals restructured into a dedicated subpackage with new dev-mode warnings

The internal implementation of the store has been moved into a new \packages/store/internals\ subpackage, exposing core utilities like \ɵStateStream\, \ɵNgxsActionRegistry\, and custom RxJS subjects (\ɵOrderedSubject\). This change introduces a new development-mode feature that warns when multiple action classes declare the same action type, helping prevent silent handler collisions. Additionally, the internal state management now uses \DestroyRef\ to ensure the state stream completes and cleans up observers when the application destroys, preventing memory leaks in server-side rendered environments.

packages/store/internals/src · high confidence

Store package restructured for Angular 17+ and Nx workspace

The @ngxs/store package has been restructured to support modern Angular (17+) and the Nx monorepo build system. This includes migrating the build pipeline to use ng-packagr via Nx targets, updating test configuration to Jest, and adjusting TypeScript configurations for library and schematic compilation. The public API entry point (index.ts) now explicitly exports the plugin API alongside the main public API, ensuring plugin developers have access to necessary internal interfaces.

packages/store · high confidence

Fixes

Refactor HMR plugin internals to improve state persistence and error handling

The internal implementation of the HMR plugin has been restructured into dedicated modules (lifecycle, options, state context, and storage) to enhance reliability. This change introduces a default behavior for state restoration, ensuring the application state is correctly persisted and restored during hot module replacement. It also adds a specific error check that prevents the plugin from running in incompatible Angular Ivy JIT configurations, requiring AOT mode instead. Additionally, the state context now exposes an AbortSignal and uses a more robust event loop for state updates, improving stability during runtime updates.

packages/hmr-plugin/src/internal · high confidence

Test coverage

Add Angular 22 integration test application; Added Playwright end-to-end tests for list page and SSR; Added comprehensive test coverage for the storage plugin; Added regression tests for form plugin edge cases; Added regression tests for router-plugin navigation and state synchronization issues; Added regression tests for storage plugin state restoration and deserialization; Added regression tests for store edge cases and bug fixes; Added snapshot test for preboot stability behavior; Added test coverage for NgxsRouterPlugin behavior; Added test coverage for advanced selector utilities; Added test coverage for state operators; Added test helper components for Ngxs testing; Added test helper utilities for store unit testing; Added test helper utilities for the logger plugin; Added test suite for WebSocket plugin lifecycle and actions; Added test utilities for mocking Redux Devtools integration; Added tests for NgxsTestBed lifecycle and state restoration; Added tests for dynamic action handler attachment and detachment; Added tests for execution strategy zone behavior; Added tests for lazy provider, plugin registration, and state utility functions; Added tests for logger-plugin filter function injection context and payload filtering; Added type assertion utility for store tests; Added type tests for NgXS store operators and decorators; Added unit and integration tests for the form plugin; Added unit tests for Ngxs Devtools plugin configuration and behavior; Added unit tests for store internals and action handling; Added unit tests for the HMR plugin's state persistence and lifecycle hooks; Added unit tests for the NgxsLoggerPlugin; New internal testing utilities for NGXS integration tests.

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

Score

  • CAI 54 → 52 (-2.1)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 96 → 94 (-2.2)
  • Architecture 77 → 91 (+13.4)
  • Maturity 70 → 70 (-0.6)
  • Readiness 44 → 47 (+2.3)
  • Security 51 → 42 (-8.4)
  • Accessibility 66 → 66 (+0.0)

Resolved (59)

  • Change coupling clique: append.ts, compose.ts, iif.ts, insert-item.ts, patch.ts, update-item.ts (packages/store/operators/src/append.ts)
  • Coverage not included — suite not readable by the collector
  • Critical CVE: [GHSA redacted] (integrations/hello-world-ng22/yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (tutorials/create-app/yarn.lock)
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (integrations/hello-world-ng22/yarn.lock)
  • High CVE: [GHSA redacted] (integrations/hello-world-ng22/yarn.lock)
  • …and 39 more

New (276)

  • Change coupling: app.component.ts ↔ list.component.ts (integration/src/app/app.component.ts)
  • Coverage not measured — JavaScript/TypeScript suite
  • Critical CVE: [GHSA redacted] (integrations/hello-world-ng22/yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical vulnerability: [GHSA redacted] (tutorials/create-app/yarn.lock)
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no usage examples (docs/recipes/unit-testing.md)
  • Documentation: written for insiders (docs/style-guide.md)
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (tutorials/create-app/yarn.lock)
  • High CVE: [GHSA redacted] (tutorials/create-app/yarn.lock)
  • …and 256 more

Changes since last survey

  • 28 commits — 16 feature/other, 12 fixes

By area

  • packages/store — 18 commits
  • packages/storage-plugin — 4 commits
  • docs/concepts — 2 commits
  • docs/recipes — 2 commits
  • (root) — 1 commit
  • integrations/hello-world-ng22 — 1 commit

Notable commits

  • fix: fix(storage-plugin): guard against localStorage/sessionStorage being undefined (#2482)
  • fix: fix(storage-plugin): merge instead of replace on cross-tab sync with keys '*' (#2497)
  • fix: fix(storage-plugin): type STORAGE_ENGINE as nullable to match its runtime contract (#2481)
  • fix: fix(store): handle late subscribers correctly (#2508)
  • fix: fix(store): keep the injection context on the no-plugin dispatch fast path (#2505)
  • fix: fix(store): make array operators consistent on a missing slice (#2496)
  • fix: fix(store): sanitize keys in createPropertySelectors proxy (#2489)
  • fix: fix(store): scope the dispatch injection context to plugin functions (#2506)
  • fix: fix(store): stop connecting the @Select decorator automatically (#2510)
  • fix: fix(store): stop findFullParentPath crashing on a cyclic state graph (#2490)
  • fix: fix(store): use refCount shareReplay in the dispatch pipeline (#2491)
  • fix: fix(store): warn when a state uses @Service() without autoProvided: false (#2486)
  • change: chore(storage-plugin): remove batching feature, explain tab-sync in docs (#2483)
  • change: chore: update CHANGELOG.md (#2504)
  • change: docs(store): document withNgxsPendingTasks timeout option (#2495)
  • change: docs(store): explain action collector notifier lifecycles (#2488)
  • change: docs(store): explain batch dispatch cancel semantics (#2493)
  • change: docs(store): reword dispatcher comments and simplify the deferred-next test (#2509)
  • change: docs(store): update comments (#2507)
  • change: docs: fix typo acheive -> achieve (#2494)
  • …and 8 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

ngxs/store 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 21 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 ad229252c570d54b327b8e47e1b0c71fab78d34f — 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-b84573e22831.