| name | xstate-inspection |
| description | Covers XState v5 Inspect API and developer tools.
Use when debugging actor systems, inspecting state transitions, integrating Stately Inspector, or observing actor lifecycle events and microsteps.
|
XState v5 Inspection and DevTools
Inspect API
Attach an inspector to observe everything in an actor system:
import { createActor } from 'xstate';
const actor = createActor(machine, {
inspect: (inspectionEvent) => {
console.log(inspectionEvent);
},
});
actor.start();
The inspector receives events for every actor in the system (root + all invoked/spawned children).
Inspection Event Types
@xstate.actor — Actor Created
{
type: '@xstate.actor',
actorRef: ,
rootId: 'x:0',
}
Emitted when any actor in the system is created.
@xstate.event — Event Sent
{
type: '@xstate.event',
actorRef: ,
rootId: 'x:0',
event: { type: 'someEvent', data: 'hello' },
sourceRef: ,
}
Emitted when an event is sent to any actor. sourceRef is undefined for externally sent events.
@xstate.snapshot — State Updated
{
type: '@xstate.snapshot',
actorRef: ,
rootId: 'x:0',
snapshot: {
status: 'active',
context: { count: 31 },
},
event: { type: 'increment' },
}
Emitted when any actor's snapshot changes.
@xstate.microstep — Transition Details
{
type: '@xstate.microstep',
value: 'c',
event: { type: 'EV' },
transitions: [
{ eventType: 'EV', target: ['(machine).b'] },
{ eventType: '', target: ['(machine).c'] },
],
}
Shows each individual state transition including intermediate steps through always transitions. Empty eventType indicates eventless transitions.
Stately Inspector
Visual debugging tool for XState actors:
import { createBrowserInspector } from '@statelyai/inspect';
import { createActor } from 'xstate';
const inspector = createBrowserInspector({
});
const actor = createActor(machine, {
inspect: inspector,
});
actor.start();
Install: npm i @statelyai/inspect
Inspecting Stores
@xstate/store also supports the Inspect API:
import { createStore } from '@xstate/store';
const store = createStore({ });
store.inspect((inspectionEvent) => {
console.log(inspectionEvent);
});
store.inspect(inspector);
The store inspector receives the initial snapshot immediately (store is auto-started).
Practical Patterns
Debug Logger
const actor = createActor(machine, {
inspect: (event) => {
switch (event.type) {
case '@xstate.event':
console.log(
'[EVENT]',
event.event.type,
event.sourceRef ? 'from ' + event.sourceRef.id : '(external)',
);
break;
case '@xstate.snapshot':
console.log('[STATE]', event.snapshot.value);
break;
case '@xstate.actor':
console.log('[ACTOR]', event.actorRef.id, 'created');
break;
}
},
});
Event Recorder (for Event Sourcing)
const events: any[] = [];
const actor = createActor(machine, {
inspect: (inspEvent) => {
if (inspEvent.type === '@xstate.event' && inspEvent.actorRef === actor) {
events.push(inspEvent.event);
}
},
});
actor.start();
Filter by Actor
const actor = createActor(machine, {
inspect: (event) => {
if (event.type === '@xstate.snapshot') {
if (event.actorRef === actor) {
console.log('Root state:', event.snapshot.value);
}
}
},
});
Conditional Inspector (dev only)
const actor = createActor(machine, {
inspect: import.meta.env.DEV
? (event) => console.log(event)
: undefined,
});