react-web
Modern React 19+ development with Server Components, Actions, hooks, TypeScript integration, and performance optimization. Use when building React web applications, implementing Server Components, using Actions for form handling, working with new hooks (use, useActionState, useOptimistic, useFormStatus), setting up React projects with Vite or Next.js, or optimizing React performance.
When & Why to Use This Skill
This Claude skill facilitates modern React 19+ development, enabling developers to build high-performance web applications using Server Components, Actions, and the latest hooks. It streamlines the implementation of TypeScript-integrated projects, optimizes rendering patterns, and ensures best practices for Next.js and Vite environments.
Use Cases
- Migrating legacy React applications to React 19 to leverage Server Components and reduce client-side JavaScript overhead.
- Implementing complex form handling and server-side mutations using React Actions and the useActionState hook for cleaner code.
- Building highly responsive user interfaces with the useOptimistic hook to provide instant feedback during background data processing.
- Architecting scalable web projects with TypeScript integration, focusing on performance optimization and efficient component hierarchies.
- Utilizing the use() hook for streamlined data fetching and context management within functional components.
| name | react-web |
|---|---|
| description | Modern React 19+ development with Server Components, Actions, hooks, TypeScript integration, and performance optimization. Use when building React web applications, implementing Server Components, using Actions for form handling, working with new hooks (use, useActionState, useOptimistic, useFormStatus), setting up React projects with Vite or Next.js, or optimizing React performance. |
React Web Development (React 19+)
Build modern, performant React applications using React 19+ features.
Core Patterns
Function Components with TypeScript
interface ButtonProps {
variant?: 'primary' | 'secondary';
children: React.ReactNode;
onClick?: () => void;
}
export function Button({ variant = 'primary', children, onClick }: ButtonProps) {
return (
<button className={`btn btn-${variant}`} onClick={onClick}>
{children}
</button>
);
}
Server Components (Default in React 19)
Server Components render on the server, reducing client JavaScript:
// app/posts/page.tsx - Server Component (default)
async function PostList() {
const posts = await db.posts.findMany();
return (
<ul>
{posts.map(post => <li key={post.id}>{post.title}</li>)}
</ul>
);
}
Client Components
Mark interactive components with 'use client':
'use client';
import { useState } from 'react';
export function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}
React 19 Features
Actions & useActionState
Replace manual form handling with Actions:
'use client';
import { useActionState } from 'react';
async function submitForm(prev: State, formData: FormData) {
'use server';
const name = formData.get('name');
await db.users.create({ name });
return { success: true };
}
function Form() {
const [state, action, pending] = useActionState(submitForm, { success: false });
return (
<form action={action}>
<input name="name" />
<button disabled={pending}>{pending ? 'Saving...' : 'Save'}</button>
</form>
);
}
use() Hook for Promises & Context
import { use } from 'react';
function UserProfile({ userPromise }) {
const user = use(userPromise); // Suspends until resolved
return <div>{user.name}</div>;
}
function ThemeButton() {
const theme = use(ThemeContext); // Read context conditionally
return <button style={{ color: theme.primary }}>Click</button>;
}
useOptimistic for Instant UI Updates
'use client';
import { useOptimistic } from 'react';
function TodoList({ todos, addTodo }) {
const [optimisticTodos, addOptimisticTodo] = useOptimistic(
todos,
(state, newTodo) => [...state, { ...newTodo, pending: true }]
);
async function handleAdd(formData: FormData) {
const text = formData.get('text');
addOptimisticTodo({ text, id: Date.now() });
await addTodo(text);
}
return (
<form action={handleAdd}>
<input name="text" />
<ul>
{optimisticTodos.map(todo => (
<li key={todo.id} style={{ opacity: todo.pending ? 0.5 : 1 }}>
{todo.text}
</li>
))}
</ul>
</form>
);
}
useFormStatus for Form State
'use client';
import { useFormStatus } from 'react-dom';
function SubmitButton() {
const { pending } = useFormStatus();
return <button disabled={pending}>{pending ? 'Submitting...' : 'Submit'}</button>;
}
Project Structure
src/
├── app/ # App Router (Next.js) or routes
├── components/
│ ├── ui/ # Reusable UI primitives
│ ├── features/ # Feature-specific components
│ └── layouts/ # Layout components
├── hooks/ # Custom hooks
├── lib/ # Utilities, API clients
├── types/ # TypeScript types
└── styles/ # Global styles, tokens
Custom Hooks Pattern
function useAsync<T>(asyncFn: () => Promise<T>, deps: unknown[]) {
const [state, setState] = useState<{
data: T | null;
loading: boolean;
error: Error | null;
}>({ data: null, loading: true, error: null });
useEffect(() => {
setState(s => ({ ...s, loading: true }));
asyncFn()
.then(data => setState({ data, loading: false, error: null }))
.catch(error => setState({ data: null, loading: false, error }));
}, deps);
return state;
}
Performance Guidelines
- Let React Compiler optimize - React 19's compiler auto-memoizes; avoid manual useMemo/useCallback unless profiling shows need
- Use Server Components - Default to server rendering, add 'use client' only for interactivity
- Lazy load routes - Use
React.lazy()and Suspense for code splitting - Avoid prop drilling - Use Context or composition patterns
Related Skills
- Atomic Design: Component hierarchy patterns → See
references/atomic-integration.md - CSS Tokens: Styling with design tokens → See
references/styling-patterns.md - Storybook: Component documentation → See
references/storybook-setup.md