React Component Skill
Quick Start
Creating Components
Automated Scaffolding:
Use the scaffold-component.mjs script to quickly generate the boilerplate for a new feature component:
node .claude/skills/react-component/scripts/scaffold-component.mjs <featureName> <ComponentName>
<featureName> (camelCase): e.g., userProfile (creates src/features/userProfile/components/).
<ComponentName> (PascalCase): e.g., UserProfileCard (generates UserProfileCardContainer.tsx, UserProfileCardView.tsx, UserProfileCardView.stories.tsx).
Run this command from the root of your React project.
Read principles.md for core philosophy
Read patterns.md for container/presenter pattern
Read project-structure.md for file placement
Reviewing Components
- Read code-review.md for review checklist
- Cross-reference with patterns.md and security.md
Component Creation Workflow
Step 1: Determine Component Type
| Type |
Purpose |
Contains |
| Container |
Data fetching, state management |
Hooks, no complex markup |
| Presenter |
Pure UI rendering |
Props, no side effects |
| Hook |
Reusable logic |
No JSX |
Step 2: Choose Location
# Shared UI primitive
src/components/ui/<ComponentName>.tsx
# Feature-specific
src/features/<feature>/components/<Name>Container.tsx
src/features/<feature>/components/<Name>View.tsx
Step 3: Implement Pattern
Container + Presenter pair:
// Container: handles data
export function FeatureContainer() {
const { data, error, isLoading } = useFeatureQuery()
if (isLoading) return <FeatureView state="loading" />
if (error) return <FeatureView state="error" message={error.message} />
if (!data) return <FeatureView state="empty" />
return <FeatureView state="ready" data={data} />
}
// Presenter: handles UI
export function FeatureView({ state, data, message }: FeatureViewProps) {
// Pure rendering based on props
}
Step 4: Add Storybook
Create stories for all four states: loading, error, empty, ready.
// FeatureView.stories.tsx
export const Loading = { args: { state: 'loading' } }
export const Empty = { args: { state: 'empty' } }
export const Error = { args: { state: 'error', message: 'Something went wrong' } }
export const Ready = { args: { state: 'ready', data: mockData } }
For more on creating interactive stories with controls, documenting with MDX, and mocking API requests for container components, see the Advanced Storybook Guide.
Step 5: Verify
- Zero TypeScript errors (strict mode)
- Zero linter warnings
- Follows naming conventions
- Uses only approved packages
Key Rules
TypeScript
- Strict mode required
- Props interface named
<Component>Props
- Explicit return types on exported functions
Styling
- Tailwind v4 only (no
tailwind.config.js)
- Use
cn() utility for conditional classes
- Responsive:
sm, md, lg, xl minimum
State
- Remote data: TanStack Query
- Local UI: useState/useReducer
- Shared: prop drilling → Context → Zustand (last resort)
Forms
- React Hook Form + Zod
- Schema in
forms/<schema>.ts
- Hook in
forms/use-<form>-form.ts
Testing
- Vitest + React Testing Library + MSW
- Test behavior, not internals
- No testing Tailwind classes
Reference Files
| File |
When to Read |
| naming.md |
Variable, function, component naming |
| principles.md |
Core philosophy (KISS, YAGNI, UX-first) |
| patterns.md |
Container/presenter, composition |
| headless-components.md |
Headless pattern, Radix-style composition |
| project-structure.md |
File organization |
| state-and-styling.md |
State management, Tailwind, async UX |
| forms-and-testing.md |
RHF + Zod, Vitest + RTL |
| advanced-storybook.md |
Interactive stories, MDX, API mocking |
| error-handling.md |
Error boundaries, logging, reporting |
| security.md |
Web3 safety, logging |
| accessibility.md |
a11y best practices, testing |
| packages.md |
Approved dependencies |
| code-review.md |
Review checklist |
External Resources
1---2name: react-component-23description: Create and review React components following strict TypeScript patterns, container/presenter architecture, and composition-first design. Use when asked to: (1) Create a React component, (2) Review a React component, (3) Build UI features, (4) Implement forms, (5) Add data fetching with TanStack Query. Enforces KISS/YAGNI principles, headless component patterns, Tailwind v4 styling, and Web3 security best practices.4---5
6# React Component Skill
7
8## Quick Start
9
10### Creating Components
11
121. **Automated Scaffolding**:
13 Use the `scaffold-component.mjs` script to quickly generate the boilerplate for a new feature component:
14
15 ```bash
16 node .claude/skills/react-component/scripts/scaffold-component.mjs <featureName> <ComponentName>
17 ```
18
19 - `<featureName>` (camelCase): e.g., `userProfile` (creates `src/features/userProfile/components/`).
20 - `<ComponentName>` (PascalCase): e.g., `UserProfileCard` (generates `UserProfileCardContainer.tsx`, `UserProfileCardView.tsx`, `UserProfileCardView.stories.tsx`).
21 _Run this command from the root of your React project._
22
232. Read [principles.md](references/principles.md) for core philosophy
243. Read [patterns.md](references/patterns.md) for container/presenter pattern
254. Read [project-structure.md](references/project-structure.md) for file placement
26
27### Reviewing Components
28
291. Read [code-review.md](references/code-review.md) for review checklist
302. Cross-reference with [patterns.md](references/patterns.md) and [security.md](references/security.md)
31
32---
33
34## Component Creation Workflow
35
36### Step 1: Determine Component Type
37
38| Type | Purpose | Contains |
39| --------- | ------------------------------- | ------------------------ |
40| Container | Data fetching, state management | Hooks, no complex markup |
41| Presenter | Pure UI rendering | Props, no side effects |
42| Hook | Reusable logic | No JSX |
43
44### Step 2: Choose Location
45
46```
47# Shared UI primitive
48src/components/ui/<ComponentName>.tsx
49
50# Feature-specific
51src/features/<feature>/components/<Name>Container.tsx
52src/features/<feature>/components/<Name>View.tsx
53```
54
55### Step 3: Implement Pattern
56
57**Container + Presenter pair:**
58
59```tsx
60// Container: handles data
61export function FeatureContainer() {
62 const { data, error, isLoading } = useFeatureQuery()
63
64 if (isLoading) return <FeatureView state="loading" />
65 if (error) return <FeatureView state="error" message={error.message} />
66 if (!data) return <FeatureView state="empty" />
67
68 return <FeatureView state="ready" data={data} />
69}
70
71// Presenter: handles UI
72export function FeatureView({ state, data, message }: FeatureViewProps) {
73 // Pure rendering based on props
74}
75```
76
77### Step 4: Add Storybook
78
79Create stories for all four states: loading, error, empty, ready.
80
81```tsx
82// FeatureView.stories.tsx
83export const Loading = { args: { state: 'loading' } }
84export const Empty = { args: { state: 'empty' } }
85export const Error = { args: { state: 'error', message: 'Something went wrong' } }
86export const Ready = { args: { state: 'ready', data: mockData } }
87```
88
89For more on creating interactive stories with controls, documenting with MDX, and mocking API requests for container components, see the [Advanced Storybook Guide](references/advanced-storybook.md).
90
91### Step 5: Verify
92
93- Zero TypeScript errors (strict mode)
94- Zero linter warnings
95- Follows [naming conventions](references/naming.md)
96- Uses only [approved packages](references/packages.md)
97
98---
99
100## Key Rules
101
102### TypeScript
103
104- Strict mode required
105- Props interface named `<Component>Props`
106- Explicit return types on exported functions
107
108### Styling
109
110- Tailwind v4 only (no `tailwind.config.js`)
111- Use `cn()` utility for conditional classes
112- Responsive: `sm`, `md`, `lg`, `xl` minimum
113
114### State
115
116- Remote data: TanStack Query
117- Local UI: useState/useReducer
118- Shared: prop drilling → Context → Zustand (last resort)
119
120### Forms
121
122- React Hook Form + Zod
123- Schema in `forms/<schema>.ts`
124- Hook in `forms/use-<form>-form.ts`
125
126### Testing
127
128- Vitest + React Testing Library + MSW
129- Test behavior, not internals
130- No testing Tailwind classes
131
132---
133
134## Reference Files
135
136| File | When to Read |
137| ----------------------------------------------------------- | ----------------------------------------- |
138| [naming.md](references/naming.md) | Variable, function, component naming |
139| [principles.md](references/principles.md) | Core philosophy (KISS, YAGNI, UX-first) |
140| [patterns.md](references/patterns.md) | Container/presenter, composition |
141| [headless-components.md](references/headless-components.md) | Headless pattern, Radix-style composition |
142| [project-structure.md](references/project-structure.md) | File organization |
143| [state-and-styling.md](references/state-and-styling.md) | State management, Tailwind, async UX |
144| [forms-and-testing.md](references/forms-and-testing.md) | RHF + Zod, Vitest + RTL |
145| [advanced-storybook.md](references/advanced-storybook.md) | Interactive stories, MDX, API mocking |
146| [error-handling.md](references/error-handling.md) | Error boundaries, logging, reporting |
147| [security.md](references/security.md) | Web3 safety, logging |
148| [accessibility.md](references/accessibility.md) | a11y best practices, testing |
149| [packages.md](references/packages.md) | Approved dependencies |
150| [code-review.md](references/code-review.md) | Review checklist |
151
152---
153
154## External Resources
155
156- [usehooks](https://github.com/uidotdev/usehooks) - Check before writing custom hooks
157- [Radix UI Themes](https://www.radix-ui.com/themes/docs/overview/getting-started)
158- [Radix Primitives](https://www.radix-ui.com/primitives/docs/overview/introduction) - Unstyled, accessible components
159- [shadcn/ui](https://ui.shadcn.com/) - Pre-built Radix + Tailwind components