Build React SPAs where components are declarative UI consuming external state (Zustand/XState/TanStack Query). Logic lives in stores, not components.
View on GitHubcodethread/claude-code-plugins
langs
plugins/langs/skills/lang-react/SKILL.md
January 18, 2026
Select agents to install to:
npx add-skill https://github.com/codethread/claude-code-plugins/blob/main/plugins/langs/skills/lang-react/SKILL.md -a claude-code --skill lang-reactInstallation paths:
.claude/skills/lang-react/# 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