Skip to content
Skillv1.0.0

xstate

Model complex UI logic with XState state machines. Use when a user asks to manage complex multi-step flows, model stateful UI (wizards, forms, auth), prevent impossible states, or implement finite sta

by terminalskills(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from terminalskills/skills (skills/xstate/SKILL.md). Install upstream with npx skills add terminalskills/skills --skill xstate. Copyright stays with the author (Apache-2.0).

XState

Overview

XState models application logic as state machines. Instead of managing boolean flags (isLoading, isError, isSuccess), you define states and transitions explicitly — making impossible states impossible. Ideal for complex flows: checkout, onboarding, authentication, multi-step forms.

Instructions

Step 1: Define a Machine

// machines/authMachine.ts — Authentication state machine
import { setup, assign, fromPromise } from 'xstate'

export const authMachine = setup({
  types: {
    context: {} as {
      user: { id: string; name: string; email: string } | null
      error: string | null
      retries: number
    },
    events: {} as
      | { type: 'LOGIN'; email: string; password: string }
      | { type: 'LOGOUT' }
      | { type: 'RETRY' },
  },
  actors: {
    loginUser: fromPromise(async ({ input }: { input: { email: string; password: string } }) => {
      const res = await fetch('/api/auth/login', {
        method: 'POST',
        body: JSON.stringify(input),
      })
      if (!res.ok) throw new Error('Invalid credentials')
      return res.json()
    }),
  },
}).createMachine({
  id: 'auth',
  initial: 'idle',
  context: { user: null, error: null, retries: 0 },

  states: {
    idle: {
      on: { LOGIN: 'authenticating' },
    },

    authenticating: {
      invoke: {
        src: 'loginUser',
        input: ({ event }) => ({ email: event.email, password: event.password }),
        onDone: {
          target: 'authenticated',
          actions: assign({ user: ({ event }) => event.output, error: null }),
        },
        onError: {
          target: 'error',
          actions: assign({
            error: ({ event }) => event.error.message,
            retries: ({ context }) => context.retries + 1,
          }),
        },
      },
    },

    authenticated: {
      on: { LOGOUT: { target: 'idle', actions: assign({ user: null }) } },
    },

    error: {
      on: {
        RETRY: { target: 'authenticating', guard: ({ context }) => context.retries < 3 },
        LOGIN: 'authenticating',
      },
    },
  },
})

Step 2: Use in React

// components/LoginPage.tsx — XState in React
import { useMachine } from '@xstate/react'
import { authMachine } from '../machines/authMachine'

export function LoginPage() {
  const [state, send] = useMachine(authMachine)

  if (state.matches('authenticated')) {
    return <div>Welcome, {state.context.user.name}!</div>
  }

  return (
    <form onSubmit={(e) => {
      e.preventDefault()
      const form = new FormData(e.currentTarget)
      send({
        type: 'LOGIN',
        email: form.get('email') as string,
        password: form.get('password') as string,
      })
    }}>
      <input name="email" type="email" required />
      <input name="password" type="password" required />

      {state.matches('error') && (
        <p className="error">{state.context.error}</p>
      )}

      <button disabled={state.matches('authenticating')}>
        {state.matches('authenticating') ? 'Signing in...' : 'Sign In'}
      </button>

      {state.matches('error') && state.context.retries < 3 && (
        <button type="button" onClick={() => send({ type: 'RETRY' })}>
          Retry ({3 - state.context.retries} left)
        </button>
      )}
    </form>
  )
}

Guidelines

  • Use XState for complex flows (multi-step forms, checkout, real-time connections). Overkill for simple toggle state.
  • State machines prevent impossible states — you can't be "loading" and "error" simultaneously.
  • XState Visualizer (stately.ai/viz) renders your machine as a diagram — great for documentation.
  • For simple state: Zustand or Jotai. For complex stateful logic: XState.

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/terminalskills-skills-xstate/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

terminalskills-skills-xstate.ocm.jsonjson
{
  "ocm": "1",
  "id": "terminalskills-skills-xstate",
  "kind": "skill",
  "name": "xstate",
  "description": "Model complex UI logic with XState state machines. Use when a user asks to manage complex multi-step flows, model stateful UI (wizards, forms, auth), prevent impossible states, or implement finite state machines in JavaScript.",
  "publisher": "terminalskills",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "coding"
    ],
    "tags": [
      "skill-md",
      "xstate",
      "state-machine",
      "statechart",
      "react",
      "logic",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Model complex UI logic with XState state machines. Use when a user asks to manage complex multi-step flows, model stateful UI (wizards, forms, auth), prevent impossible states, or implement finite state machines in JavaScript."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/terminalskills/skills",
      "path": "skills/xstate/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/terminalskills/skills/blob/HEAD/skills/xstate/SKILL.md",
      "key": "terminalskills/skills/skills/xstate/SKILL.md"
    },
    "compatibility": "React, Vue, Svelte, vanilla JS",
    "license": "Apache-2.0"
  },
  "instructions": "# XState\n\n## Overview\n\nXState models application logic as state machines. Instead of managing boolean flags (`isLoading`, `isError`, `isSuccess`), you define states and transitions explicitly — making impossible states impossible. Ideal for complex flows: checkout, onboarding, authentication, multi-step forms.\n\n## Instructions\n\n### Step 1: Define a Machine\n\n```typescript\n// machines/authMachine.ts — Authentication state machine\nimport { setup, assign, fromPromise } from 'xstate'\n\nexport const authMachine = setup({\n  types: {\n    context: {} as {\n      user: { id: string; name: string; email: s",
  "cost": {
    "context_tokens": 930
  }
}

Fetch it by URL: GET /api/v1/registry/terminalskills-skills-xstate/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.