react-component-generator — Claude Code skill: generate React
A skill that generates React components in TypeScript with props, hooks and accessibility. Useful when building new UI elements or refactoring old ones.
npx skills add OneWave-AI/claude-skills --skill react-component-generator -a claude-codeWhat react-component-generator does
The skill gives the agent a fixed order of work for a React component: decide whether it is a client or server component, define the props interface in TypeScript, implement it, then add accessibility attributes. Three templates ship with it — a client component, a server component, and a form built on React Hook Form with zod validation.
The client template walks through a button with style variants, sizes and a loading state. The server one renders a user list from a database query with a limit prop. The form template parses a zod schema and wires field errors to the inputs through aria-invalid and aria-describedby. A checklist covers semantic HTML, aria-label on icon-only buttons, roles, keyboard navigation and aria-busy for loading.
Installation runs through npx skills add with a platform flag, and the skill file lands at a path like ~/.claude/skills/react-component-generator/SKILL.md. The form examples lean on react-hook-form, @hookform/resolvers and zod — if those packages are not in your project, you will have to rewrite them. Worth checking your dependencies before the agent starts pasting code.
What it helps with
- generate a button with style variants and a loading state
- write a server component that lists users from a database
- build a login form with field validation
- tie form errors to inputs with aria attributes
- run an accessibility checklist while refactoring a component
Example prompts for the agent
- Create a client Button component with primary, secondary and ghost variants
- Write a server UserList component with a limit prop
- Build a login form with React Hook Form and zod validation
How to install react-component-generator
1Skills CLI (Vercel)
npx skills add OneWave-AI/claude-skills --skill react-component-generator -a claude-code2Manually: put the files in place
~/.claude/skills/react-component-generator/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/react-component-generator/
1Skills CLI (Vercel)
npx skills add OneWave-AI/claude-skills --skill react-component-generator -a codex2Manually: put the files in place
.agents/skills/react-component-generator/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add OneWave-AI/claude-skills --skill react-component-generator -a cursor2Manually: put the files in place
.cursor/skills/react-component-generator/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install OneWave-AI/claude-skills react-component-generator2Manually: put the files in place
.github/skills/react-component-generator/SKILL.md1Skills CLI (Vercel)
npx skills add OneWave-AI/claude-skills --skill react-component-generator -a gemini-cli2Platform CLI
gemini skills install https://github.com/OneWave-AI/claude-skills --path react-component-generatorManually: put the files in place
.devin/skills/react-component-generator/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add OneWave-AI/claude-skills --skill react-component-generator -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about react-component-generator
How do I install react-component-generator in Claude?
Run npx skills add OneWave-AI/claude-skills --skill react-component-generator -a claude-code. The skill file ends up at ~/.claude/skills/react-component-generator/SKILL.md.
What does react-component-generator do?
It guides the agent through writing React components in TypeScript: picking the component type, defining props, adding hooks and accessibility attributes. Templates cover client components, server components and forms.
What does the skill need to work?
The form template relies on react-hook-form, @hookform/resolvers and zod. Without those packages in your project, you will need to adapt the examples.
Source text
SKILL.md · MIT
---
name: react-component-generator
description: Generate React components with TypeScript, proper props, hooks, and accessibility. Use when creating new React components, UI elements, or refactoring existing components.
---
# React Component Generator
## Instructions
When creating React components:
1. **Determine component type**: Client or Server component
2. **Define props interface** with TypeScript
3. **Implement with best practices**
4. **Add accessibility attributes**
## Templates
### Client Component
```tsx
'use client';
import { useState, useCallback } from 'react';
import { cn } from '@/lib/utils';
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary' | 'ghost';
size?: 'sm' | 'md' | 'lg';
isLoading?: boolean;
children: React.ReactNode;
}
export function Button({
variant = 'primary',
size = 'md',
isLoading = false,
children,
className,
disabled,
...props
}: ButtonProps) {
const baseStyles = 'inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2';
const variants = {
primary: 'bg-blue-600 text-white hover:bg-blue-700',
secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300',
ghost: 'hover:bg-gray-100',
};
const sizes = {
sm: 'h-8 px-3 text-sm',
md: 'h-10 px-4',
lg: 'h-12 px-6 text-lg',
};
return (
<button
className={cn(baseStyles, variants[variant], sizes[size], className)}
disabled={disabled || isLoading}
aria-busy={isLoading}
{...props}
>
{isLoading ? <span className="animate-spin mr-2">⏳</span> : null}
{children}
</button>
);
}
```
### Server Component
```tsx
import { db } from '@/lib/db';
interface UserListProps {
limit?: number;
}
export async function UserList({ limit = 10 }: UserListProps) {
const users = await db.user.findMany({ take: limit });
if (users.length === 0) {
return <p className="text-gray-500">No users found.</p>;
}
return (
<ul role="list" className="divide-y">
{users.map((user) => (
<li key={user.id} className="py-4">
<span>{user.name}</span>
</li>
))}
</ul>
);
}
```
### Form Component with React Hook Form
```tsx
'use client';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
const schema = z.object({
email: z.string().email('Invalid email'),
password: z.string().min(8, 'Min 8 characters'),
});
type FormData = z.infer<typeof schema>;
export function LoginForm({ onSubmit }: { onSubmit: (data: FormData) => void }) {
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm<FormData>({
resolver: zodResolver(schema),
});
return (
<form onSubmit={handleSubmit(onSubmit)} noValidate>
<div>
<label htmlFor="email">Email</label>
<input
id="email"
type="email"
aria-invalid={!!errors.email}
aria-describedby={errors.email ? 'email-error' : undefined}
{...register('email')}
/>
{errors.email && (
<p id="email-error" role="alert">{errors.email.message}</p>
)}
</div>
<button type="submit" disabled={isSubmitting}>
{isSubmitting ? 'Loading...' : 'Submit'}
</button>
</form>
);
}
```
## Accessibility Checklist
- [ ] Use semantic HTML elements
- [ ] Add `aria-label` for icon-only buttons
- [ ] Include `role` attributes where needed
- [ ] Ensure keyboard navigation works
- [ ] Add `aria-invalid` and `aria-describedby` for form errors
- [ ] Use `aria-busy` for loading states
© OneWave-AI · MIT · OneWave-AI/claude-skills