Back to Skills

lang-react

verified

Build React SPAs where components are declarative UI consuming external state (Zustand/XState/TanStack Query). Logic lives in stores, not components.

View on GitHub

Marketplace

codethread-plugins

codethread/claude-code-plugins

Plugin

langs

development-tools

Repository

codethread/claude-code-plugins

plugins/langs/skills/lang-react/SKILL.md

Last Verified

January 18, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/codethread/claude-code-plugins/blob/main/plugins/langs/skills/lang-react/SKILL.md -a claude-code --skill lang-react

Installation paths:

Claude
.claude/skills/lang-react/
Powered by add-skill CLI

Instructions

# React Expert

## Core Philosophy

Components consume external state, contain no logic:

- External hooks at top (Zustand, XState, TanStack Query)
- No useState/useReducer/useEffect for complex logic
- Inline actions unless repeated 2+ times
- Test stores/machines (unit tests), not components (E2E only)

## State Management Stack

| State Type            | Solution                     |
| --------------------- | ---------------------------- |
| **Remote (REST)**     | TanStack Query               |
| **Remote (GraphQL)**  | Apollo Client                |
| **Application state** | Zustand                      |
| **Complex machines**  | XState                       |
| **Local UI state**    | useState (rare, last resort) |

## Component Pattern

```typescript
// ✅ External hooks → Early returns → JSX
function UserProfile({ userId }: { userId: string }) {
  const { user, isLoading } = useUser(userId);
  const { updateProfile } = useUserActions();

  if (isLoading) return <Spinner />;

  return (
    <div>
      <h1>{user.name}</h1>
      <button onClick={() => updateProfile({ email: 'new@example.com' })}>
        Update
      </button>
    </div>
  );
}
```

## Testing: Stores, Not Components

| What            | Tool       | Why                       |
| --------------- | ---------- | ------------------------- |
| Zustand stores  | Vitest     | Test without React        |
| XState machines | Vitest     | Deterministic transitions |
| Critical flows  | Playwright | Real browser              |
| Components      | Never      | Logic should be in stores |

```typescript
// Test store directly
const { login } = useAuthStore.getState();
await login({ email: "test@example.com", password: "pass" });
expect(useAuthStore.getState().user).toBeDefined();
```

## Unique Patterns

### Prop Ordering: Simple → Complex

```tsx
<Table
  data={items}
  loading={isLoading}
  sortable
  onSort={handleSort}
  renderRow={(item) => <Row>{item.name}</Row>}
/>
```

### Inline Props for Type 

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
2912 chars