Agent skill
xstate
Use this skill when working with XState v5 - a state management and orchestration library using state machines, statecharts, and the actor model for complex logic in JavaScript/TypeScript applications.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/development/xstate
SKILL.md
XState v5 Skill
Comprehensive assistance with XState v5 development, generated from official Stately.ai documentation.
IMPORTANT: XState v5 ONLY
This skill covers XState v5 exclusively. DO NOT use XState v4 APIs, documentation, or examples.
- Always verify documentation URLs contain "xstate" (current docs), not "xstate-v4"
- When researching, explicitly search for "XState v5" to avoid v4 results
- XState v5 uses
setup()and requires TypeScript 5.0+ - if you see older patterns, it's v4- If migrating from v4, consult the v5 migration guide but implement using v5 APIs only
When to Use This Skill
This skill should be triggered when:
- State machine design: Creating or modeling application logic with state machines/statecharts
- Actor systems: Implementing the actor model for orchestration and communication
- XState v5 implementation: Writing code using XState v5 APIs (
createMachine,createActor,setup) - TypeScript typing: Configuring strong types for state machines with XState v5
- Actor types: Working with promise, callback, observable, or transition actors
- Debugging state machines: Troubleshooting state transitions, actions, guards, or actor behavior
- Migration to v5: Understanding v5 API changes when upgrading from v4 (output will use v5 APIs only)
- Integration: Connecting XState with React, Vue, Svelte, or other frameworks
Key Concepts
State Machines & Actors
- State machine: A mathematical model of computation that can be in exactly one state at a time
- Actor model: A computational model where actors are independent entities that communicate by sending messages
- Statechart: Enhanced state machine with hierarchy, parallelism, and orthogonality
- XState v5: Requires TypeScript 5.0+, uses
setup()function for type-safe machines
Actor Types in XState
- State machine actors: Logic represented by finite state machines
- Promise actors: Actors that represent a single promise
- Callback actors: Logic defined by callback functions that can send events
- Observable actors: Actors that represent observable streams (e.g., RxJS)
- Transition actors: Simple reducer-like actors (similar to Redux reducers)
Quick Reference
1. Simple Counter Machine (Beginner)
Basic state machine with context and actions:
import { createMachine, assign, createActor } from 'xstate';
const countMachine = createMachine({
context: {
count: 0,
},
on: {
INC: {
actions: assign({
count: ({ context }) => context.count + 1,
}),
},
DEC: {
actions: assign({
count: ({ context }) => context.count - 1,
}),
},
SET: {
actions: assign({
count: ({ event }) => event.value,
}),
},
},
});
const countActor = createActor(countMachine).start();
countActor.subscribe((state) => {
console.log(state.context.count);
});
countActor.send({ type: 'INC' }); // logs 1
countActor.send({ type: 'DEC' }); // logs 0
2. Toggle Machine with States (Beginner)
Machine with multiple states and transitions:
import { setup, createActor, assign } from 'xstate';
const machine = setup({
/* ... */
}).createMachine({
id: 'toggle',
initial: 'active',
context: { count: 0 },
states: {
active: {
entry: assign({
count: ({ context }) => context.count + 1,
}),
on: {
toggle: { target: 'inactive' },
},
},
inactive: {
on: {
toggle: { target: 'active' },
},
},
},
});
const actor = createActor(machine);
actor.subscribe((snapshot) => {
console.log(snapshot.value);
});
actor.start(); // logs 'active' with context { count: 1 }
actor.send({ type: 'toggle' }); // transitions to 'inactive'
3. Type-Safe Machine with setup() (Intermediate)
Using setup() for strong TypeScript typing:
import { setup } from 'xstate';
const feedbackMachine = setup({
types: {
context: {} as { feedback: string },
events: {} as
| { type: 'feedback.good' }
| { type: 'feedback.bad' },
},
actions: {
logTelemetry: () => {
// Implement telemetry logging
},
},
}).createMachine({
// Machine config with full type inference
initial: 'idle',
context: { feedback: '' },
states: {
idle: {
on: {
'feedback.good': {
actions: 'logTelemetry',
target: 'success'
},
'feedback.bad': {
actions: 'logTelemetry',
target: 'failure'
}
}
},
success: {},
failure: {}
}
});
4. Callback Actor for Event Listeners (Intermediate)
Using callback actors to interface with external systems:
import { createActor, fromCallback, sendTo, setup } from 'xstate';
const resizeLogic = fromCallback(({ sendBack, receive }) => {
const resizeHandler = (event) => {
sendBack(event);
};
window.addEventListener('resize', resizeHandler);
const removeListener = () => {
window.removeEventListener('resize', resizeHandler);
};
receive((event) => {
if (event.type === 'stopListening') {
console.log('Stopping listening');
removeListener();
}
});
// Cleanup function
return () => {
console.log('Cleaning up');
removeListener();
};
});
const machine = setup({
actors: { resizeLogic }
}).createMachine({
invoke: {
src: 'resizeLogic',
},
});
5. Callback Actor with Input (Intermediate)
Passing input to callback actors:
import { fromCallback, createActor, setup, type EventObject } from 'xstate';
const resizeLogic = fromCallback<EventObject, { defaultSize: number }>(
({
sendBack,
receive,
input, // Typed as { defaultSize: number }
}) => {
console.log(input.defaultSize); // 100
// Use input.defaultSize in your logic
return () => {
// Cleanup
};
}
);
const machine = setup({
actors: {
resizeLogic,
},
}).createMachine({
invoke: {
src: 'resizeLogic',
input: {
defaultSize: 100,
},
},
});
6. Observable Actor with RxJS (Advanced)
Creating observable actors for stream processing:
import { fromObservable, createActor } from 'xstate';
import { interval } from 'rxjs';
const intervalLogic = fromObservable(({ input }) =>
interval(input.interval)
);
const intervalActor = createActor(intervalLogic, {
input: { interval: 10_000 },
});
intervalActor.subscribe((snapshot) => {
console.log(snapshot.context);
});
intervalActor.start();
// logs 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...
// every 10 seconds
7. Inspection API for Debugging (Advanced)
Using the Inspect API to observe state transitions:
const actor = createActor(machine, {
inspect: (inspectionEvent) => {
// type: '@xstate.actor' - when actor is created
// type: '@xstate.snapshot' - when state updates
// type: '@xstate.event' - when event is sent
// type: '@xstate.microstep' - for each transition step
console.log(inspectionEvent);
},
});
actor.start();
8. TypeScript Configuration
Required TypeScript setup for XState v5:
{
"compilerOptions": {
"strictNullChecks": true,
"skipLibCheck": true
}
}
9. Installation Commands
# npm
npm install xstate
# pnpm
pnpm install xstate
# yarn
yarn add xstate
# TypeScript (required: v5.0+)
npm install typescript@latest --save-dev
Reference Files
This skill includes comprehensive documentation in references/:
- state.md - Complete documentation covering:
- Observable actors and RxJS integration
- TypeScript setup and type safety
- Installation and getting started
- Callback actors for event handling
- Cheatsheet with syntax examples
- Inspection API for debugging
- State machine actors and capabilities
- Actor input/output patterns
Use the reference file to access:
- Detailed API documentation with complete examples
- TypeScript type helpers (
ActorRefFrom,SnapshotFrom,EventFrom) - Event assertion patterns for type safety
- Complete inspection event schemas
- Actor system architecture patterns
Working with This Skill
For Beginners
Start here:
- Review the "Simple Counter Machine" example above
- Understand the basic concepts: states, events, transitions, context
- Learn the core APIs:
createMachine,createActor,assign - Check the cheatsheet section in
references/state.md
Key learning path:
- States and transitions (toggle machine example)
- Context and actions (counter machine example)
- Event handling with
send() - Subscribing to state changes
For Intermediate Users
Focus areas:
- Type safety with the
setup()function - Actor invocation and communication patterns
- Callback actors for external system integration
- Input/output patterns for actor data flow
Common tasks:
- Creating reusable actor logic
- Implementing guards and actions
- Passing typed input to actors
- Managing actor lifecycle (cleanup)
For Advanced Users
Advanced topics:
- Observable actors with RxJS integration
- Actor system orchestration (parent-child relationships)
- Inspection API for comprehensive debugging
- Microstep analysis for complex transitions
- Custom actor logic creators
Integration patterns:
- Framework integration (React, Vue, Svelte)
- Backend state orchestration
- Event-driven architecture
- Testing state machines
Navigation Tips
- Need type safety? → See "Type-Safe Machine with setup()" example and TypeScript section
- External events? → Check callback actor examples
- Debugging issues? → Use Inspection API example and review inspection events
- Stream data? → See Observable actor with RxJS
- Quick syntax lookup? → Reference the cheatsheet examples in
state.md
TypeScript Support
XState v5 requires TypeScript 5.0 or higher. Key features:
setup()function: Strongly types machines, context, events, and actions.typesproperty: Alternative typing method in machine config- Type helpers:
ActorRefFrom<T>,SnapshotFrom<T>,EventFrom<T> assertEvent(): Type assertion helper for narrowing event types- Dynamic parameters: Preferred over direct event access for type safety
Common Patterns
Actor Communication
// Send events between actors
sendTo('childActor', { type: 'message' })
// Receive events in callback actor
receive((event) => {
if (event.type === 'message') {
// Handle message
}
})
Cleanup & Lifecycle
// Return cleanup function from callback actor
return () => {
// Cleanup resources
removeEventListeners();
clearTimers();
};
Type-Safe Event Handling
// Use assertEvent for type narrowing
import { assertEvent } from 'xstate';
actions: {
handleEvent: ({ event }) => {
assertEvent(event, 'specificEventType');
// TypeScript now knows event.type is 'specificEventType'
console.log(event.specificProperty);
}
}
Resources
Official Links
- Documentation: https://stately.ai/docs/xstate (v5 docs - avoid /xstate-v4/ URLs)
- Stately Studio: Visual editor and debugging tool for state machines
- VS Code Extension: XState extension for visual editing and autocomplete
scripts/
Add helper scripts here for common automation tasks.
assets/
Add templates, boilerplate, or example projects here.
Notes
- This skill covers XState v5 specifically (requires TypeScript 5.0+)
- All actors in XState are observable
- The
setup()function is the recommended way to create type-safe machines - Typegen is not yet available for v5; use
setup()or.typesinstead - Use the Inspection API for comprehensive debugging
- Reference files contain links to original documentation
Updating
To refresh this skill with updated documentation:
- Re-run the scraper with the same configuration
- The skill will be rebuilt with the latest information
Didn't find tool you were looking for?