Skip to main content
skill Claude Code CX Codex Cursor GitHub Copilot

state-machine — Claude Code skill: component states

Builds a throwaway page for every reachable state of one component, using mock data and a switcher. Use it when visual work needs isolated states without changing the component.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add jakubkrehel/skills --skill state-machine -a claude-code
Open on GitHub

What state-machine does

The skill takes one component and renders every branch it can already reach, including loading, empty data, errors, roles, permissions, flags, and limits. Mock data feeds each view, while the switcher changes the __state URL parameter. This is deliberately strict: a state the code cannot reach is left out.

The scratch route imports the real component and inherits the app’s existing layout, fonts, styles, and providers. Data should enter where the component normally receives it: props, a seeded query cache, a mock provider, or project request mocks. In Next projects with server and client boundaries, the page needs "use client" or fixtures can disappear.

It loads every view in an available browser to check that mock data appears instead of live data or a blank region. When the work is over, the page folder and any approved seam can be removed in one action, followed by a codebase search for route and fixture names.

What it helps with

  • render loading, error, and empty component states
  • switch between account roles and access levels
  • inspect a long list with scrolling or pagination
  • keep mock data separate from live requests
  • remove the scratch route and its fixtures

Example prompts for the agent

  • Create a state page for the audit log table.
  • Render every reachable billing card state with mock data and a switcher.
  • Build a scratch route for the network panel without editing the component.

How to install state-machine

1Skills CLI (Vercel)

npx skills add jakubkrehel/skills --skill state-machine -a claude-code

2Manually: put the files in place

~/.claude/skills/state-machine/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/state-machine/

From the same set13

The whole set →
better-ui jakubkrehel This skill sets concrete rules for surface details, icons, shadows, and motion. Use it to polish an interface after its underlying interactions work. Claude Code CX Codex Cursor +1 38,900installs better-typography jakubkrehel Reviews interface typography and applies fixes through the project’s styling system. Use it to check text hierarchy, wrapping, truncation and punctuation. Claude Code CX Codex Cursor +1 33,800installs better-colors jakubkrehel Audits color systems, generates ramps, and maps semantic tokens to roles. Use it when hardcoded hex values pile up or text contrast needs verifiable measurement. Claude Code CX Codex Cursor +1 32,200installs better-layout jakubkrehel A skill that sets grouping, alignment, reading order and responsive structure, then stress-tests the result by resizing, translating and mirroring it for RTL. Claude Code CX Codex Cursor +1 30,400installs better-interface jakubkrehel Runs a cross-discipline interface review covering accessibility, layout, copy, typography, color, and UI polish into one ranked report. Claude Code CX Codex Cursor +1 29,700installs better-accessibility jakubkrehel Reviews an interface against WCAG 2.2 and fixes issues in the project’s styling system. Use it to check keyboard navigation and screen-reader behavior. Claude Code CX Codex Cursor +1 29,200installs better-writing jakubkrehel Writes and reviews UI copy, from button labels to errors and empty states. It keeps product vocabulary consistent and guides users to the next step. Claude Code CX Codex Cursor +1 28,700installs interface-review jakubkrehel Audits pull requests, branches, and uncommitted edits for layout, UI, accessibility, and typography regressions. Keeps focus on what changed rather than pre-existing debt. Claude Code CX Codex Cursor +1 18,100installs

Similar

appllama-app-design-skill Appllama (appllama.io) Skill for building native iOS and Android screens with Expo and React Native. Designs with Apple HIG fidelity, semantic colors, Reanimated motion, proper navigation semantics, and simulator-verified iteration. Claude Code CX Codex Cursor +1 4,700installs browser-extension-builder sickn33 Guides the architecture and implementation of Manifest V3 browser extensions for Chrome and Firefox. Useful when structuring content scripts, popups, and service workers. Claude Code CX Codex Cursor +1 2,000installs scroll-experience sickn33 This skill guides an agent through scroll animations, parallax scenes, and interactive web narratives. Use it when scrolling should reveal part of a page’s story. Claude Code CX Codex Cursor +1 2,000installs shopify-development sickn33 Skill for building Shopify apps, extensions and themes using GraphQL Admin API, Shopify CLI, Polaris UI, and Liquid. Routes tasks to the right track: app, extension, theme or combination. Claude Code CX Codex Cursor +1 1,900installs shopify-expert https://github.com/Jeffallan Skill for building Shopify themes, apps, and headless storefronts via Storefront API. Useful when you need to assemble a Liquid theme, custom checkout, or Hydrogen storefront. Claude Code CX Codex Cursor +1 5,000installs browser-harness browser-use Controls a real browser via Chrome DevTools Protocol: clicking, typing, navigation, logged-in sessions, JS-rendered and bot-protected pages. Use curl for plain HTTP requests. Claude Code CX Codex Cursor +1 793installs frontend-design official anthropics This skill guides intentional visual design for new interfaces and redesigns. Use it when a generic generated UI is not enough. Claude Code Claude.ai 1,025,790installs design-taste-frontend Leonxlnx This skill directs the design of public pages and work screens, then checks the result in a browser through screenshots. Use it when an interface feels generic or unfinished. Claude Code CX Codex Cursor +1 673,100installs

Questions about state-machine

How do I install state-machine in Claude Code?

Run npx skills add jakubkrehel/skills --skill state-machine -a claude-code, then run npx skills add jakubkrehel/skills --skill state-machine -a claude-code again. The skill file is at ~/.claude/skills/state-machine/SKILL.md.

What does state-machine do?

It builds a temporary page using the project’s real component, mock data, and a state switcher. It works from branches that already exist in the code.

Why check every state after a visual change?

A fix for one view can break another. The skill calls for switching through and reviewing every state again after each visual change.

Source text

SKILL.md · MIT
---
name: state-machine
description: Renders every state of a component you choose on a throwaway page, with mock data and a switcher, so you can work on each state.
disable-model-invocation: true
---

# State machine

This skill takes one component and renders it on a throwaway page in every state it can be in. Mock data feeds each state, a switcher flips between them and the page is deleted in one step when you are done.

It is a workbench, not a review. The page stays up while the user works on the visuals, one state on screen and every other a keypress away. Stacking hostile scenarios on one page for a single look is `break`, exploring alternative designs is `variant` and reviewing finished work is `interface-review`.

## 1. Scope one component

One component per run: the audit log table, the network panel, the billing card. "The settings page" spans several, so list them and ask which one.

Restate it in one sentence: what the component shows, where it renders in production and where its data comes from.

## 2. Find the states in the code

The states are the branches the component already has. Read it and its data hooks for every one:

| Kind | States |
| --- | --- |
| Data | Loading, empty, error, one item, a typical set, a set long enough to scroll or paginate, some requests resolved and others pending, stale data refetching |
| Account | Plan tier, role and permission checks, an owner versus a member |
| Feature | Flags, trials, limits reached, a disabled or locked feature |

A state the code cannot reach is not a state. Do not add a branch to render one. Where the design shows a state the code lacks, list it as missing and leave it out.

Write the set down before building, one line each, named the way the product talks about it: `empty`, `enterprise`, `member-no-access`. Group them under headings in the product's words, by what changes. Use `Data` and `Account` or narrower ones such as `Connection` or `Access`. The switcher shows these groups. Say which kinds you dropped and why in one line. Combine kinds only where the code branches on the combination, such as `member-empty`, never as a cross product.

## 3. Build the throwaway page

A scratch route inside the app holds the real component, imported from the project and untouched. The route inherits the app's layout, fonts, global styles and providers for free.

Where the framework splits server from client components, the page is client code, `"use client"` in Next. Otherwise fixture data can silently vanish crossing that boundary, and the page renders empty.

Render one instance in a container as wide as the component is in production. The container, the fixtures and the switcher are everything the page adds, with no fonts, styles or themes of its own. Keep the page, its fixtures and its switcher in one folder, such as `/states/audit-log`, so removal is one delete.

## 4. Feed each state at the data boundary

Supply the data where the component receives it, from the page, without editing the component. In order of preference:

1. Props, where the component takes its data as props.
2. The app's own data seam: a seeded query cache, a mock provider or the project's request mocks.

A fixture threaded through props five levels down tests a path production never takes. Where the only way in is editing the component, say so and ask before adding a seam.

Make the data look like the product. Real-shaped names, timestamps, amounts and the item counts users actually have. Three rows of "Test item" make every state look fine.

Loading and pending states hold still. Keep them pending until the switcher moves, rather than resolving after a timeout.

## 5. Add the switcher

A grouped list beside the component flips the `__state` search param, so every state is a link. Where there is no room beside the component, it moves above it as a select with the same groups. The double underscore keeps it clear of any param the app's layout reads. [switcher.md](switcher.md) holds the spec.

## 6. Confirm every state renders, then hand over

Load the page once in a browser already at hand and flip through every state. The component shows the mock data, not the real data and not a blank region. Mock data that never appears is the common failure here. Live sync, a cache that refetches over the seed or a server boundary dropping the fixture all cause it. Fix the plumbing before handing over.

With no browser at hand, say so and hand the URL over for the user to check.

Then hand over the URL, the state list and the switcher keys. Stop there. Changing how a state looks is the user's next request, not part of this one.

## Re-check every state after each change

After a visual change, flip through every state again, since a fix for one state often breaks another.

## Remove it in one step, on the user's word

Delete the page folder and any seam the user approved. Then search the codebase for the route and fixture names, and check that the diff touches nothing else of the setup.

## Before you finish

| Mistake | Fix |
| --- | --- |
| The component edited to accept fixtures | Feed data from the page through props or the app's data seam; ask before adding a seam |
| A rebuilt lookalike component on the page | Import the real component from the project |
| The page restyles or re-themes the component | The app's layout, fonts and tokens as they are |
| Fixtures passed as props deep in the tree | Supply the data where the component receives it |
| A branch added to the component to show a state | Leave out states the code cannot reach, and list missing ones |
| "Item 1", "Test user", three rows | Product-shaped data in real quantities |
| Loading resolves after a timeout | Hold it until the switcher moves |
| Handed over without loading each state | Load every state; a blank or real-data state means broken plumbing |
| Switcher styled with the project's tokens | Keep it visibly outside the design system |
| One long row of tabs, one per state | A grouped list beside the component that scrolls on its own; a select above it where the list does not fit |
| Visuals changed unasked | Hand over and wait |
| Page deleted in the same turn it was built | Remove it only on the user's word |
| Route or fixture names left behind | Search for both after removal |

© jakubkrehel · MIT · jakubkrehel/skills

See also

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor