Stately
PackagesXState Store

@xstate/store-angular

The @xstate/store-angular package provides Angular bindings for XState Store. It includes utilities for subscribing to store state as Angular signals.

This package re-exports all of @xstate/store, so you only need to install @xstate/store-angular.

Installation

npm install @xstate/store-angular
pnpm install @xstate/store-angular
yarn add @xstate/store-angular

Quick start

import { Component } from '@angular/core';
import { createStore, injectStore } from '@xstate/store-angular';

const store = createStore({
  context: { count: 0 },
  on: {
    inc: (context, event: { by?: number }) => ({
      count: context.count + (event.by ?? 1),
    }),
  },
});

@Component({
  selector: 'app-counter',
  standalone: true,
  template: `
    <div>
      <p>Count: {{ count() }}</p>
      <button (click)="store.trigger.inc()">+1</button>
      <button (click)="store.trigger.inc({ by: 5 })">+5</button>
    </div>
  `,
})
export class CounterComponent {
  store = store;
  count = injectStore(store, (state) => state.context.count);
}

API

injectStore(store, selector?, compare?)

Creates an Angular signal that subscribes to a store and returns a selected value.

import { Component } from '@angular/core';
import { injectStore } from '@xstate/store-angular';

@Component({
  selector: 'app-counter',
  template: `<div>Count: {{ count() }}</div>`,
})
export class CounterComponent {
  // Select specific value
  count = injectStore(store, (state) => state.context.count);

  // With custom comparison function
  user = injectStore(
    store,
    (state) => state.context.user,
    (prev, next) => prev.id === next.id
  );

  // Without selector (returns full snapshot)
  snapshot = injectStore(store);
}

Parameters:

  • store - The store to subscribe to
  • selector - Optional function to select a value from the store snapshot. If not provided, returns the full snapshot.
  • compare - Optional comparison function (defaults to strict equality ===)

Returns: A readonly Angular signal containing the selected value

Remember to call the signal as a function (e.g., count()) in your template to access its value. This is how Angular's signal-based reactivity works.

Full documentation

For complete XState Store documentation including context, transitions, effects, atoms, and more, see the XState Store docs.

On this page