| name | react-component-dev |
| description | Build reusable, accessible React components with predictable APIs and ref forwarding. Use when creating or refactoring components or defining component APIs, favoring composition over configuration and slots/children over many boolean props. Not needed for style-only or content-only edits that do not change a component API. |
React Component Development — Skill
Name: react-component-dev
Purpose: Build reusable, accessible React components with predictable APIs and ref forwarding.
Use this skill when creating or refactoring components.
Applies when: Building new components, refactoring UI components, or defining component APIs.
Do not use when: Only editing styles or content in existing components without API changes.
Rules
- Composition over configuration: Prefer
children/slots over many boolean props.
- Forward refs: If a component renders a DOM element, use
forwardRef.
- Accessibility: Use semantic HTML first; add ARIA only when needed.
- Predictable props: Follow controlled/uncontrolled conventions.
- Small and testable: Extract complex behavior into hooks.
Workflow
- Define the component’s responsibility and minimal usage.
- Choose the API shape (controlled vs uncontrolled as needed).
- Implement with semantic HTML and accessibility defaults.
- Add
forwardRef for DOM-rendering components.
- Extract complex behavior into hooks if needed.
Checklists
Implementation checklist
Review checklist
Minimal examples
forwardRef pattern
import * as React from "react";
type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
variant?: "default" | "ghost";
};
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ variant = "default", className, ...props }, ref) => {
return (
<button
ref={ref}
className={[
variant === "ghost" ? "bg-transparent" : "bg-black text-white",
className,
]
.filter(Boolean)
.join(" ")}
{...props}
/>
);
},
);
Button.displayName = "Button";
Compound component
export function Card({ children }: { children: React.ReactNode }) {
return <div className="rounded-lg border p-4">{children}</div>;
}
export function CardHeader({ children }: { children: React.ReactNode }) {
return <div className="mb-2 font-semibold">{children}</div>;
}
export function CardBody({ children }: { children: React.ReactNode }) {
return <div>{children}</div>;
}
Common mistakes / pitfalls
- Missing
forwardRef on input-like components
- Using
div for buttons/links
- Overloading components with boolean props
- Shipping components without a minimal usage example