react-dev
This skill should be used when building React components with TypeScript, typing hooks, handling events, or when React TypeScript, React 19, Server Components are mentioned. Covers type-safe patterns for React 18-19 including generic components, proper event typing, and routing integration (TanStack Router, React Router).
React TypeScript Development Skill
Purpose
The react-dev skill provides comprehensive TypeScript patterns and best practices for building type-safe React applications. It serves as a complete reference for modern React development with TypeScript, covering React 18-19 features, including Server Components, type-safe routing, and proper event handling.
This skill exists to eliminate TypeScript guesswork in React development by providing compile-time guarantees, confident refactoring, and production-ready patterns that catch bugs before runtime.
When to Use
Activate this skill when working on:
- Building typed React components - Creating new components with proper TypeScript types
- Implementing generic components - Tables, lists, modals, form fields that work with any data type
- Typing event handlers and forms - Mouse events, form submissions, input changes, keyboard events
- Using React 19 features - Actions, Server Components,
use()hook,useActionState - Router integration - TanStack Router or React Router v7 with type safety
- Custom hooks with proper typing - Creating reusable hooks with correct return types
- Migrating to React 19 - Understanding breaking changes and new patterns
Trigger phrases:
- "Build a typed React component"
- "Type this event handler"
- "Create a generic Table/List/Modal"
- "Use React 19 Server Components"
- "Type-safe routing with TanStack/React Router"
- "How do I type this hook?"
- "React TypeScript best practices"
Not for:
- Non-React TypeScript projects
- Vanilla JavaScript React (without TypeScript)
- React Native-specific patterns
How It Works
The skill provides progressive disclosure of React TypeScript knowledge:
- Core patterns loaded immediately - Component props, event handlers, hooks typing
- Advanced patterns referenced on-demand - Generic components, Server Components, routing
- Reference files for deep dives - Detailed examples and edge cases only loaded when needed
- React 19 migration guidance - Breaking changes and new APIs clearly marked
The skill is structured around:
- Quick reference sections - Common patterns you can copy immediately
- Detailed reference files - In-depth examples and explanations
- Rules and anti-patterns - What to always do and what to never do
- Version-specific guidance - React 18 vs React 19 differences highlighted
Key Features
1. React 19 Breaking Changes
Covers all major breaking changes in React 19:
- ref as prop - No more
forwardRef, refs are regular props now - useActionState - Replaces deprecated
useFormState - use() hook - Unwraps promises and context in components
- Migration patterns - Step-by-step guides for updating existing code
2. Component Patterns
Type-safe patterns for common component scenarios:
- Props typing - Extending native HTML elements with
ComponentPropsWithoutRef - Children typing -
ReactNode,ReactElement, render props - Discriminated unions - Type-safe variant props (e.g., button vs link)
- Generic components - Reusable components that infer types from data
3. Event Handler Typing
Specific event types for accurate TypeScript inference:
- Mouse events (
MouseEvent<HTMLButtonElement>) - Form events (
FormEvent<HTMLFormElement>) - Input changes (
ChangeEvent<HTMLInputElement>) - Keyboard events (
KeyboardEvent<HTMLInputElement>) - Focus, drag, clipboard, touch, wheel events (in reference docs)
4. Hooks Typing
Proper TypeScript patterns for all React hooks:
useState- Explicit types for unions and nullable valuesuseRef- DOM refs (null) vs mutable refs (direct access)useReducer- Discriminated union actionsuseContext- Null guard patterns- Custom hooks - Tuple returns with
as const
5. Server Components (React 19)
Modern patterns for Server Components and Server Actions:
- Async components with direct data fetching
- Server Actions with
'use server'directive - Client components consuming Server Actions
- Promise handoff with
use()hook - Parallel fetching and streaming
6. Type-Safe Routing
Comprehensive routing patterns for both major routers:
- TanStack Router - Compile-time type safety with Zod validation
- React Router v7 - Auto-generated types with Framework Mode
- Type-safe params, search params, loaders, actions
7. Generic Components
Reusable components that work with any data type:
- Tables with type-safe columns
- Lists with constrained generics
- Modals, selects, form fields
- Render props and keyof patterns
Prerequisites
- React 18 or 19 - Patterns are optimized for modern React
- TypeScript 5.0+ - Uses latest TypeScript features
- Router (optional) - TanStack Router or React Router v7 for routing patterns
- Zod (optional) - For TanStack Router search param validation
Usage Examples
Example 1: Type-Safe Button Component
type ButtonProps = {
variant: 'primary' | 'secondary';
} & React.ComponentPropsWithoutRef<'button'>;
function Button({ variant, children, ...props }: ButtonProps) {
return (
<button
className={variant}
{...props}
>
{children}
</button>
);
}
// Usage
<Button variant="primary" onClick={(e) => console.log(e.currentTarget.disabled)}>
Click me
</Button>
Example 2: Generic Table Component
type Column<T> = {
key: keyof T;
header: string;
render?: (value: T[keyof T], item: T) => React.ReactNode;
};
type TableProps<T> = {
data: T[];
columns: Column<T>[];
keyExtractor: (item: T) => string | number;
};
function Table<T>({ data, columns, keyExtractor }: TableProps<T>) {
return (
<table>
<thead>
<tr>{columns.map(col => <th key={String(col.key)}>{col.header}</th>)}</tr>
</thead>
<tbody>
{data.map(item => (
<tr key={keyExtractor(item)}>
{columns.map(col => (
<td key={String(col.key)}>
{col.render ? col.render(item[col.key], item) : String(item[col.key])}
</td>
))}
</tr>
))}
</tbody>
</table>
);
}
// Usage - types are inferred!
type User = { id: number; name: string; email: string };
const users: User[] = [...];
<Table
data={users}
columns={[
{ key: 'name', header: 'Name' },
{ key: 'email', header: 'Email' }
]}
keyExtractor={user => user.id}
/>
Example 3: React 19 Server Action with Form
// actions/user.ts
'use server';
export async function updateUser(userId: string, formData: FormData) {
const name = formData.get('name') as string;
await db.user.update({
where: { id: userId },
data: { name }
});
revalidatePath(`/users/${userId}`);
return { success: true };
}
// UserForm.tsx
'use client';
import { useActionState } from 'react';
import { updateUser } from '@/actions/user';
function UserForm({ userId }: { userId: string }) {
const [state, formAction, isPending] = useActionState(
(prev, formData) => updateUser(userId, formData),
{}
);
return (
<form action={formAction}>
<input name="name" />
<button disabled={isPending}>
{isPending ? 'Saving...' : 'Save'}
</button>
{state.success && <p>Saved!</p>}
</form>
);
}
Example 4: Type-Safe Event Handlers
function Form() {
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
console.log(Object.fromEntries(formData));
};
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
console.log(e.target.value); // Typed correctly!
};
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
e.currentTarget.blur(); // currentTarget is typed as HTMLInputElement
}
};
return (
<form onSubmit={handleSubmit}>
<input
onChange={handleChange}
onKeyDown={handleKeyDown}
/>
</form>
);
}
Example 5: Custom Hook with Proper Typing
function useToggle(initial = false) {
const [value, setValue] = useState(initial);
const toggle = () => setValue(v => !v);
return [value, toggle] as const; // Tuple type preserved!
}
// Usage
const [isOpen, toggleOpen] = useToggle(false);
// isOpen is boolean, toggleOpen is () => void
Example 6: TanStack Router Type-Safe Route
import { createRoute } from '@tanstack/react-router';
import { z } from 'zod';
const userRoute = createRoute({
path: '/users/$userId',
component: UserPage,
loader: async ({ params }) => ({
user: await fetchUser(params.userId)
}),
validateSearch: z.object({
tab: z.enum(['profile', 'settings']).optional(),
page: z.number().int().positive().default(1),
}),
});
function UserPage() {
// All fully typed from the route definition!
const { user } = useLoaderData({ from: userRoute.id });
const { tab, page } = useSearch({ from: userRoute.id });
const { userId } = useParams({ from: userRoute.id });
return <div>{user.name} - {tab} - Page {page}</div>;
}
Output
The skill provides:
- Code examples - Copy-paste ready TypeScript code
- Type definitions - Exact types to use for your scenarios
- Pattern explanations - Why patterns work and when to use them
- Migration guides - Step-by-step updates for React 19
- Reference links - Pointers to detailed documentation when needed
Best Practices
Always Do
✅ Use specific event types - MouseEvent<HTMLButtonElement> not React.MouseEvent
✅ Explicit useState for unions/null - useState<User | null>(null)
✅ Extend native elements - ComponentPropsWithoutRef<'button'>
✅ Discriminated unions for variants - Type-safe props based on variant
✅ as const for tuple returns - Preserve tuple types in custom hooks
✅ ref as prop in React 19 - No forwardRef needed
✅ useActionState for forms - Not deprecated useFormState
✅ Type-safe routing patterns - Use provided router patterns
Never Do
❌ Use any for event handlers - Defeats TypeScript's purpose
❌ Use JSX.Element for children - Use ReactNode instead
❌ Use forwardRef in React 19+ - It's deprecated
❌ Use useFormState - Deprecated in React 19
❌ Forget null handling for DOM refs - Always use ref?.current
❌ Mix Server/Client in same file - Will cause hydration errors
❌ Await promises before use() - Defeats streaming/Suspense
Progressive Enhancement
- Start simple - Basic component props and event handlers
- Add constraints - Discriminated unions, generic constraints
- Leverage inference - Let TypeScript infer types from usage
- Reference docs when stuck - Deep dive into specific patterns
Reference File Organization
The skill includes detailed reference files:
- hooks.md -
useState,useRef,useReducer,useContext, custom hooks - event-handlers.md - All event types, generic handlers, edge cases
- react-19-patterns.md -
useActionState,use(),useOptimistic, migration - generic-components.md - Table, Select, List, Modal, FormField patterns
- server-components.md - Async components, Server Actions, streaming
- tanstack-router.md - TanStack Router typed routes, search params, navigation
- react-router.md - React Router v7 loaders, actions, type generation
These files are loaded on-demand to keep context efficient. The skill will reference them when deeper knowledge is needed.
Context Efficiency
This skill follows progressive disclosure principles:
- Core patterns in SKILL.md - Most common use cases immediately available
- Reference files on-demand - Deep dives only when needed
- Script-free design - Pure knowledge, no executable scripts needed
- Single-level references - Direct links, no nested includes
This keeps the skill's context footprint minimal while providing comprehensive coverage when needed.
Version Compatibility
- React 18 - All patterns work, ignore React 19-specific sections
- React 19 - Full support including Server Components,
use(),useActionState - TypeScript 5.0+ - Recommended for best type inference
- TanStack Router - Any version supporting
createRoute - React Router v7+ - Framework Mode for auto-generated types
Getting Started
- Install the skill in Claude Code or add to claude.ai project knowledge
- Mention React TypeScript in your conversation or request
- Reference specific patterns - "How do I type this event handler?"
- Let Claude suggest patterns - Describe what you're building
- Explore reference docs - Ask for deep dives when needed
Related Skills
- typescript-patterns - General TypeScript patterns beyond React
- frontend-testing - Testing typed React components
- component-library - Building design systems with TypeScript
Version: 1.0.0 Last Updated: 2026-01-20 Maintained by: Softaworks Agent Skills