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
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: aaronbassett-aaronbassett-marketplace-react-components3description: React Component Skill4---56# React Component Skill78## Quick Start910### Creating Components11121. **Automated Scaffolding**:13 Use the `scaffold-component.mjs` script to quickly generate the boilerplate for a new feature component:1415 ```bash16 node .claude/skills/react-component/scripts/scaffold-component.mjs <featureName> <ComponentName>17 ```1819 - `<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._22232. Read [principles.md](references/principles.md) for core philosophy243. Read [patterns.md](references/patterns.md) for container/presenter pattern254. Read [project-structure.md](references/project-structure.md) for file placement2627### Reviewing Components28291. Read [code-review.md](references/code-review.md) for review checklist302. Cross-reference with [patterns.md](references/patterns.md) and [security.md](references/security.md)3132---3334## Component Creation Workflow3536### Step 1: Determine Component Type3738| 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 |4344### Step 2: Choose Location4546```47# Shared UI primitive48src/components/ui/<ComponentName>.tsx4950# Feature-specific51src/features/<feature>/components/<Name>Container.tsx52src/features/<feature>/components/<Name>View.tsx53```5455### Step 3: Implement Pattern5657**Container + Presenter pair:**5859```tsx60// Container: handles data61export function FeatureContainer() {62 const { data, error, isLoading } = useFeatureQuery()6364 if (isLoading) return <FeatureView state="loading" />65 if (error) return <FeatureView state="error" message={error.message} />66 if (!data) return <FeatureView state="empty" />6768 return <FeatureView state="ready" data={data} />69}7071// Presenter: handles UI72export function FeatureView({ state, data, message }: FeatureViewProps) {73 // Pure rendering based on props74}75```7677### Step 4: Add Storybook7879Create stories for all four states: loading, error, empty, ready.8081```tsx82// FeatureView.stories.tsx83export 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```8889For 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).9091### Step 5: Verify9293- Zero TypeScript errors (strict mode)94- Zero linter warnings95- Follows [naming conventions](references/naming.md)96- Uses only [approved packages](references/packages.md)9798---99100## Key Rules101102### TypeScript103104- Strict mode required105- Props interface named `<Component>Props`106- Explicit return types on exported functions107108### Styling109110- Tailwind v4 only (no `tailwind.config.js`)111- Use `cn()` utility for conditional classes112- Responsive: `sm`, `md`, `lg`, `xl` minimum113114### State115116- Remote data: TanStack Query117- Local UI: useState/useReducer118- Shared: prop drilling → Context → Zustand (last resort)119120### Forms121122- React Hook Form + Zod123- Schema in `forms/<schema>.ts`124- Hook in `forms/use-<form>-form.ts`125126### Testing127128- Vitest + React Testing Library + MSW129- Test behavior, not internals130- No testing Tailwind classes131132---133134## Reference Files135136| 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 |151152---153154## External Resources155156- [usehooks](https://github.com/uidotdev/usehooks) - Check before writing custom hooks157- [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 components159- [shadcn/ui](https://ui.shadcn.com/) - Pre-built Radix + Tailwind components160161---162> Converted and distributed by [TomeVault](https://tomevault.io/claim/aaronbassett) — claim your Tome and manage your conversions.163<!-- tomevault:4.0:skill_md:2026-04-13 -->