
React Dev
Type-safe React 18–19 components, hooks, events, and router wiring while you build the UI.
Overview
React-dev is an agent skill for the Build phase that guides type-safe React 18–19 components, hooks, events, and router integration in TypeScript.
Install
npx skills add https://github.com/softaworks/agent-toolkit --skill react-devWhat is this skill?
- React 19 patterns: ref as a normal prop (forwardRef migration), useActionState for forms
- Type-safe hooks, refs, forms, and generic components for confident refactors
- Server Components and use() called out alongside classic client patterns
- TanStack Router and React Router integration guidance
- Explicit scope: React + TypeScript only—not vanilla JS React or non-React TS
Adoption & trust: 3.6k installs on skills.sh; 2k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are building React in TypeScript but event types, generics, React 19 ref/forms APIs, or router typing keep slipping into unsafe or outdated patterns.
Who is it for?
Indie builders adding or migrating a TypeScript React app with React Router or TanStack Router and React 19 APIs.
Skip if: Teams on vanilla JavaScript React, non-React TypeScript services, or backend-only agents with no UI layer.
When should I use this skill?
Building typed React components; React TypeScript, React 19, Server Components, TanStack Router, or React Router mentioned; typing hooks, events, or forms.
What do I get? / Deliverables
After the skill runs, new and updated components follow consistent TypeScript patterns for React 19 features, hooks, and routing so refactors stay type-checked.
- Typed React components, hooks, and event handlers
- Router-integrated modules aligned with React 18–19 patterns
Recommended Skills
Journey fit
Frontend implementation is where typed components, refs-as-props, and form Actions land in a solo builder’s codebase. Covers component typing, generic components, event handlers, and TanStack Router / React Router integration—the core frontend build lane.
How it compares
Pattern cookbook for React+TS in the agent—not a component library generator or a generic TypeScript style guide.
Common Questions / FAQ
Who is react-dev for?
Solo and indie builders using Claude Code, Cursor, or Codex to implement or migrate React UIs with TypeScript, especially React 18–19 and modern routers.
When should I use react-dev?
During Build (frontend) when you type components and hooks, wire forms with Actions/useActionState, adopt ref-as-prop, integrate TanStack Router or React Router, or mention Server Components and use().
Is react-dev safe to install?
It is procedural frontend guidance only. Review the Security Audits panel on this Prism page before installing any skill from the repo.
SKILL.md
READMESKILL.md - React Dev
# React TypeScript Type-safe React = compile-time guarantees = confident refactoring. <when_to_use> - Building typed React components - Implementing generic components - Typing event handlers, forms, refs - Using React 19 features (Actions, Server Components, use()) - Router integration (TanStack Router, React Router) - Custom hooks with proper typing NOT for: non-React TypeScript, vanilla JS React </when_to_use> <react_19_changes> React 19 breaking changes require migration. Key patterns: **ref as prop** - forwardRef deprecated: ```typescript // React 19 - ref as regular prop type ButtonProps = { ref?: React.Ref<HTMLButtonElement>; } & React.ComponentPropsWithoutRef<'button'>; function Button({ ref, children, ...props }: ButtonProps) { return <button ref={ref} {...props}>{children}</button>; } ``` **useActionState** - replaces useFormState: ```typescript import { useActionState } from 'react'; type FormState = { errors?: string[]; success?: boolean }; function Form() { const [state, formAction, isPending] = useActionState(submitAction, {}); return <form action={formAction}>...</form>; } ``` **use()** - unwraps promises/context: ```typescript function UserProfile({ userPromise }: { userPromise: Promise<User> }) { const user = use(userPromise); // Suspends until resolved return <div>{user.name}</div>; } ``` See [react-19-patterns.md](references/react-19-patterns.md) for useOptimistic, useTransition, migration checklist. </react_19_changes> <component_patterns> **Props** - extend native elements: ```typescript type ButtonProps = { variant: 'primary' | 'secondary'; } & React.ComponentPropsWithoutRef<'button'>; function Button({ variant, children, ...props }: ButtonProps) { return <button className={variant} {...props}>{children}</button>; } ``` **Children typing**: ```typescript type Props = { children: React.ReactNode; // Anything renderable icon: React.ReactElement; // Single element render: (data: T) => React.ReactNode; // Render prop }; ``` **Discriminated unions** for variant props: ```typescript type ButtonProps = | { variant: 'link'; href: string } | { variant: 'button'; onClick: () => void }; function Button(props: ButtonProps) { if (props.variant === 'link') { return <a href={props.href}>Link</a>; } return <button onClick={props.onClick}>Button</button>; } ``` </component_patterns> <event_handlers> Use specific event types for accurate target typing: ```typescript // Mouse function handleClick(e: React.MouseEvent<HTMLButtonElement>) { e.currentTarget.disabled = true; } // Form function handleSubmit(e: React.FormEvent<HTMLFormElement>) { e.preventDefault(); const formData = new FormData(e.currentTarget); } // Input function handleChange(e: React.ChangeEvent<HTMLInputElement>) { console.log(e.target.value); } // Keyboard function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) { if (e.key === 'Enter') e.currentTarget.blur(); } ``` See [event-handlers.md](references/event-handlers.md) for focus, drag, clipboard, touch, wheel events. </event_handlers> <hooks_typing> **useState** - explicit for unions/null: ```typescript const [user, setUser] = useState<User | null>(null); const [status, setStatus] = useState<'idle' | 'loading'>('idle'); ``` **useRef** - null for DOM, value for mutable: ```typescript const inputRef = useRef<HTMLInputElement>(null); // DOM - use ?. const countRef = useRef<number>(0); // Mutable - direct access ``` **useReducer** - discriminated unions for actions: ```typescript type Action = | { type: 'increm