
React Patterns
Apply typed React component patterns—props, children composition, and lifted state—while building UI with your agent.
Overview
React Patterns is an agent skill for the Build phase that encodes type-safe props, children composition, and lifted-state patterns for React components.
Install
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill react-patternsWhat is this skill?
- Type-safe props with variants, sizes, disabled flags, and React.ReactNode children
- Card-style composition via children instead of prop drilling every slot
- Lifting state to a parent to coordinate sibling panels or tabs
- Concrete TypeScript examples for Button, Card, and Panel coordination patterns
Adoption & trust: 2.1k installs on skills.sh; 271 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your agent keeps generating one-off components with untyped props and sibling state that cannot stay synchronized.
Who is it for?
Solo builders implementing interactive UI who want consistent component APIs without pulling in a full component library doc dump.
Skip if: Next.js App Router routing, server components, or data-fetch architecture—use a Next.js-specific skill for that stack.
When should I use this skill?
Building or refactoring React UI that needs typed props, children slots, or shared state across sibling components.
What do I get? / Deliverables
You get copy-ready TypeScript patterns for buttons, cards, and parent-coordinated panels that you can extend across your feature tree.
- Typed component scaffolds following kit conventions
- Parent-child state coordination examples
Recommended Skills
Journey fit
How it compares
Lightweight pattern cheat sheet rather than a complete React course or UI kit generator.
Common Questions / FAQ
Who is react-patterns for?
Developers and vibe-coders building React UIs who want their agent to follow conventional props, children, and state-lifting structure.
When should I use react-patterns?
During Build frontend work when creating reusable buttons, layout cards, tab-like panels, or any siblings that share one piece of state.
Is react-patterns safe to install?
Check the Security Audits panel on this Prism page; the skill is documentation-only patterns with no declared tool permissions.
SKILL.md
READMESKILL.md - React Patterns
# React Component Patterns Patterns for component composition, props, state lifting, and common UI patterns. ## Props and Children Type-safe component props: ```typescript interface ButtonProps { variant?: 'primary' | 'secondary'; size?: 'sm' | 'md' | 'lg'; onClick?: () => void; children: React.ReactNode; disabled?: boolean; } function Button({ variant = 'primary', size = 'md', onClick, children, disabled = false }: ButtonProps) { return ( <button className={`btn btn-${variant} btn-${size}`} onClick={onClick} disabled={disabled} > {children} </button> ); } ``` Composition with children: ```typescript interface CardProps { children: React.ReactNode; className?: string; } function Card({ children, className = '' }: CardProps) { return ( <div className={`card ${className}`}> {children} </div> ); } ``` ## Lifting State Up Share state between sibling components by lifting to a common ancestor: ```typescript function Parent() { const [activeIndex, setActiveIndex] = useState(0); return ( <> <Panel isActive={activeIndex === 0} onShow={() => setActiveIndex(0)}> Panel 1 content </Panel> <Panel isActive={activeIndex === 1} onShow={() => setActiveIndex(1)}> Panel 2 content </Panel> </> ); } function Panel({ isActive, onShow, children }: { isActive: boolean; onShow: () => void; children: React.ReactNode; }) { return ( <div> <button onClick={onShow}>Show</button> {isActive && <div>{children}</div>} </div> ); } ``` ## Controlled Components Input with controlled state: ```typescript function ControlledForm() { const [name, setName] = useState(''); const [email, setEmail] = useState(''); const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); console.log({ name, email }); }; return ( <form onSubmit={handleSubmit}> <input value={name} onChange={e => setName(e.target.value)} /> <input type="email" value={email} onChange={e => setEmail(e.target.value)} /> <button type="submit">Submit</button> </form> ); } ``` ## Conditional Rendering ```typescript function Greeting({ isLoggedIn }: { isLoggedIn: boolean }) { return ( <div> {isLoggedIn ? <UserGreeting /> : <GuestGreeting />} </div> ); } // Short-circuit for optional elements function Notification({ message }: { message?: string }) { return <div>{message && <p className="notification">{message}</p>}</div>; } ``` ## Lists and Keys Always use stable IDs, not array indices: ```typescript function UserList({ users }: { users: User[] }) { return ( <ul> {users.map(user => ( <li key={user.id}>{user.name}</li> ))} </ul> ); } ``` ## Compound Components Pattern Group related components with shared context: ```typescript const MenuContext = createContext<{ isOpen: boolean; setIsOpen: (v: boolean) => void } | null>(null); function Menu({ children }: { children: React.ReactNode }) { const [isOpen, setIsOpen] = useState(false); return ( <MenuContext.Provider value={{ isOpen, setIsOpen }}> <div className="menu">{children}</div> </MenuContext.Provider> ); } function MenuButton({ children }: { children: React.ReactNode }) { const ctx = useContext(MenuContext)!; return <button onClick={() => ctx.setIsOpen(!ctx.isOpen)}>{children}</button>; } function MenuItems({ children }: { children: React.ReactNode }) { const { isOpen } = useContext(MenuContext)!; return isOpen ? <ul>{children}</ul> : null; } // Usage <Menu> <MenuButton>Open Menu</MenuButton> <MenuItems> <li>Item 1</li> <li>Item 2</li> </MenuItems> </Menu> ``` ## Render Props Pattern ```typescript function MouseTracker({ render }: { render: (pos: { x: number; y: number }) => React.ReactNode }) { const [position, setPosition] = useState({ x: 0, y: 0 }); return ( <div onMouseMove={e => setPosition({ x: e.cl