Skip to main content
xstate-react This skill should be used when the user asks to "create a state machine", "add xState", "use xState with React", "implement actor-based state", "manage complex state with state machines", "use xState with Effect", "integrate Effect-ts with xState", mentions xState hooks (useMachine, useActor, useSelector), or discusses finite state machines in React applications.
インストールへ移動 Skills Marketplace コミュニティが作成したAIスキルを発見・探索
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/sablier-labs/agent-skills --skill xstate-reactコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
Zipをダウンロード ダウンロード中... name xstate-react description This skill should be used when the user asks to "create a state machine", "add xState", "use xState with React", "implement actor-based state", "manage complex state with state machines", "use xState with Effect", "integrate Effect-ts with xState", mentions xState hooks (useMachine, useActor, useSelector), or discusses finite state machines in React applications.
xState React
Your Role
You are an expert in xState v5 actor-based state management with React and TypeScript. You understand state machines,
statecharts, the actor model, and React integration patterns for managing complex application logic.
Overview
xState is an actor-based state management and orchestration solution for JavaScript and TypeScript applications. It uses
event-driven programming, state machines, statecharts, and the actor model to handle complex logic in predictable,
robust, and visual ways.
When to use xState:
Complex UI flows (multi-step forms, wizards, checkout processes)
State with many transitions and edge cases
Logic that needs to be visualized and validated
Processes with async operations and error handling
State that can be in multiple "modes" (loading, error, success, idle)
When to use simpler state instead (useState, Zustand):
Simple UI toggles and counters
Form state confined to a single component
State without complex transition logic
CRUD operations with straightforward loading states
Quick Start
Create a state machine and use it in a React component:
"use client" ;
import { createMachine } from "xstate" ;
import { useMachine } ;
toggleMachine = ({
: ,
: ,
: {
: {
: { : }
},
: {
: { : }
}
}
});
( ) {
[state, send] = (toggleMachine);
(
);
}
from
"@xstate/react"
const
createMachine
id
"toggle"
initial
"inactive"
states
inactive
on
TOGGLE
"active"
active
on
TOGGLE
"inactive"
function
Toggle
const
useMachine
return
<button onClick ={() => send({ type: "TOGGLE" })}>
{state.value === "inactive" ? "Off" : "On"}
</button >
React Hooks API
useMachineCreate and run a machine within a component's lifecycle:
import { useMachine } from "@xstate/react" ;
import { someMachine } from "./machines/someMachine" ;
function Component ( ) {
const [state, send, actorRef] = useMachine (someMachine, {
input : { userId : "123" }
});
return (
<div >
<p > Current state: {JSON.stringify(state.value)}</p >
<p > Context: {JSON.stringify(state.context)}</p >
<button onClick ={() => send({ type: "SOME_EVENT" })}>Send</button >
</div >
);
}
useActorSubscribe to an existing actor (created outside the component):
import { createActor } from "xstate" ;
import { useActor } from "@xstate/react" ;
import { todoMachine } from "./machines/todoMachine" ;
const todoActor = createActor (todoMachine);
todoActor.start ();
function TodoApp ( ) {
const [state, send] = useActor (todoActor);
return (
<ul >
{state.context.todos.map((todo) => (
<li key ={todo.id} > {todo.text}</li >
))}
</ul >
);
}
useSelectorOptimize re-renders by selecting specific state:
import { useSelector } from "@xstate/react" ;
function TodoCount ({ actorRef } ) {
const count = useSelector (actorRef, (state ) => state.context .todos .length );
return <span > {count} todos</span > ;
}
function IsLoading ({ actorRef } ) {
const isLoading = useSelector (actorRef, (state ) => state.matches ("loading" ));
return isLoading ? <Spinner /> : null ;
}
TypeScript Patterns
Typing Machines with types Define context and events using the types property:
import { createMachine, assign } from "xstate" ;
type FormContext = {
name : string ;
email : string ;
errors : string [];
};
type FormEvent =
| { type : "UPDATE_NAME" ; value : string }
| { type : "UPDATE_EMAIL" ; value : string }
| { type : "SUBMIT" }
| { type : "RESET" };
const formMachine = createMachine ({
types : {} as {
context : FormContext ;
events : FormEvent ;
},
id : "form" ,
initial : "editing" ,
context : {
name : "" ,
email : "" ,
errors : []
},
states : {
editing : {
on : {
UPDATE_NAME : {
actions : assign ({
name : ({ event } ) => event.value
})
},
UPDATE_EMAIL : {
actions : assign ({
email : ({ event } ) => event.value
})
},
SUBMIT : "submitting"
}
},
submitting : {
}
}
});
Using setup() for Reusable Definitions Define actions, guards, actors, and delays in a type-safe way:
import { setup, assign } from "xstate" ;
type AuthContext = {
userId : string | null ;
retries : number ;
};
type AuthEvent =
| { type : "LOGIN" ; username : string ; password : string }
| { type : "LOGOUT" }
| { type : "SUCCESS" ; userId : string }
| { type : "FAILURE" };
const authMachine = setup ({
types : {} as {
context : AuthContext ;
events : AuthEvent ;
},
actions : {
setUser : assign ({
userId : ({ event } ) => (event as { userId : string }).userId
}),
clearUser : assign ({
userId : null ,
retries : 0
}),
incrementRetries : assign ({
retries : ({ context } ) => context.retries + 1
})
},
guards : {
hasReachedMaxRetries : ({ context } ) => context.retries >= 3 ,
isAuthenticated : ({ context } ) => context.userId !== null
}
}).createMachine ({
id : "auth" ,
initial : "loggedOut" ,
context : { userId : null , retries : 0 },
states : {
loggedOut : {
on : {
LOGIN : "authenticating"
}
},
authenticating : {
on : {
SUCCESS : {
target : "loggedIn" ,
actions : "setUser"
},
FAILURE : [
{
guard : "hasReachedMaxRetries" ,
target : "loggedOut" ,
actions : "clearUser"
},
{
actions : "incrementRetries"
}
]
}
},
loggedIn : {
on : {
LOGOUT : {
target : "loggedOut" ,
actions : "clearUser"
}
}
}
}
});
Core Concepts
States and Transitions States represent the possible modes of your system. Transitions define how events move between states:
const machine = createMachine ({
initial : "idle" ,
states : {
idle : {
on : { FETCH : "loading" }
},
loading : {
on : {
SUCCESS : "success" ,
ERROR : "error"
}
},
success : { type : "final" },
error : {
on : { RETRY : "loading" }
}
}
});
Context Context holds extended state data:
const machine = createMachine ({
context : {
count : 0 ,
user : null
},
});
const count = state.context .count ;
Actions Actions are fire-and-forget side effects:
import { assign } from "xstate" ;
const machine = createMachine ({
states : {
active : {
entry : assign ({ count : ({ context } ) => context.count + 1 }),
exit : () => console .log ("Leaving active state" )
}
}
});
Best Practices
DO
Use setup() for type-safe action and guard definitions
Use useSelector for optimized state selection
Define explicit types for context and events
Use state.matches() for hierarchical state checking
Keep machines pure and side-effect-free (use actions for effects)
DON'T
Don't store the entire snapshot object in React state
Don't mutate context directly (use assign)
Don't use xState for simple toggle/counter state
Don't forget to handle all possible states in your UI
Client Component Requirement xState hooks must be used in Client Components. Add the "use client" directive:
"use client" ;
import { useMachine } from "@xstate/react" ;
Additional Documentation For comprehensive xState documentation including advanced patterns, use the Context7 MCP:
Use Context7 MCP with library ID "/statelyai/xstate" to fetch:
- Detailed invoke/spawn patterns
- Parallel and history states
- Actor communication
- Testing strategies
See ./references/patterns.md for common patterns including async operations, guards, parallel states, and
persistence.
Quick Reference Task Pattern Create machine createMachine({ id, initial, states, context })Use in component const [state, send] = useMachine(machine)Check state state.matches("loading") or state.valueSend event send({ type: "EVENT_NAME", ...payload })Read context state.context.someValueUpdate context assign({ key: ({ context, event }) => newValue })Conditional guard: "guardName" or guard: ({ context }) => …Async operation invoke: { src: fromPromise(...), onDone, onError }Optimized select useSelector(actorRef, (state) => state.context.x)
このリポジトリの他の Skills Write bulloak tree specifications (.tree files) for smart contract integration tests. Trigger phrases - write a tree, create test tree, BTT spec, bulloak tree, Branching Tree Technique, or when writing integration tests for contract functions.
Deploy Sablier EVM contracts (Utils, Flow, Lockup, Airdrops, Bob) with full workflow automation. This skill should be used when the user asks to "deploy", "deploy protocol", "deploy to chain", or mentions deployment-related tasks. Handles contract deployment, explorer verification, SDK updates, and initial setup through Init scripts.
Write Foundry-based tests and scripts. Trigger phrases - foundry testing, write test, fuzz test, fork test, invariant test, deploy script, gas benchmark, coverage, or when working in tests/ or scripts/ directories.