Help us improve
Share bugs, ideas, or general feedback.
From flow
Provides React code patterns for functional components, custom hooks, server/client components, form handling, and context. Useful when editing .tsx/.jsx files, components, hooks, or React upgrades.
npx claudepluginhub cofin/flow --plugin flowHow this skill is triggered — by the user, by Claude, or both
Slash command
/flow:reactThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
<workflow>
Builds React 18+/19 components, implements state management, debugs rendering, and migrates class components. Activates for Server Components, Suspense boundaries, and React 19 features.
Applies opinionated React 18+/19 conventions for components: hooks patterns, Server Components, Suspense boundaries, state management, performance memoization, use() hook, form actions.
Provides React 18/19 patterns for hooks discipline, server/client component boundaries, Suspense, error boundaries, form actions, data fetching, state management decisions, and accessible composition.
Share bugs, ideas, or general feedback.
import { useState, useEffect, useCallback } from 'react';
interface Props {
title: string;
items: Item[];
onSelect?: (item: Item) => void;
}
export function ItemList({ title, items, onSelect }: Props) {
const [selected, setSelected] = useState<Item | null>(null);
const handleSelect = useCallback((item: Item) => {
setSelected(item);
onSelect?.(item);
}, [onSelect]);
return (
<div>
<h2>{title}</h2>
<ul>
{items.map(item => (
<li key={item.id} onClick={() => handleSelect(item)}>
{item.name}
</li>
))}
</ul>
</div>
);
}
function useFetch<T>(url: string) {
const [data, setData] = useState<T | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
const controller = new AbortController();
fetch(url, { signal: controller.signal })
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.then(setData)
.catch(err => {
if (err.name !== 'AbortError') setError(err);
})
.finally(() => setLoading(false));
return () => controller.abort();
}, [url]);
return { data, loading, error };
}
// Server Components are framework-scoped (for example Next.js App Router)
// and are not a universal default in plain React + Vite projects.
async function UserProfile({ userId }: { userId: string }) {
const user = await fetchUser(userId);
return <div>{user.name}</div>;
}
// Client Component
'use client';
export function InteractiveButton({ onClick }: { onClick: () => void }) {
return <button onClick={onClick}>Click me</button>;
}
import { useActionState } from 'react';
function ContactForm() {
const [state, formAction, isPending] = useActionState(
async (prevState: FormState, formData: FormData) => {
const result = await submitForm(formData);
return result;
},
{ message: '' }
);
return (
<form action={formAction}>
<input name="email" type="email" required />
<button type="submit" disabled={isPending}>
{isPending ? 'Sending...' : 'Send'}
</button>
{state.message && <p>{state.message}</p>}
</form>
);
}
import { createContext, useContext, useState, ReactNode } from 'react';
interface ThemeContextType {
theme: 'light' | 'dark';
toggle: () => void;
}
const ThemeContext = createContext<ThemeContextType | null>(null);
export function ThemeProvider({ children }: { children: ReactNode }) {
const [theme, setTheme] = useState<'light' | 'dark'>('light');
const toggle = () => setTheme(t => t === 'light' ? 'dark' : 'light');
return (
<ThemeContext.Provider value={{ theme, toggle }}>
{children}
</ThemeContext.Provider>
);
}
export function useTheme() {
const context = useContext(ThemeContext);
if (!context) throw new Error('useTheme must be used within ThemeProvider');
return context;
}
useCallback/useMemo only when profiling shows measurable benefitkey props correctly (stable, unique identifiers)useEffect return functionFor comprehensive coverage of these commonly-used React libraries:
| Library | Skill | Coverage |
|---|---|---|
| TanStack Router/Query/Table/Form | tanstack | Full ecosystem |
| Shadcn/ui components | shadcn | All components |
| Tailwind CSS | tailwind | Styling patterns |
Bundle traditional SPA apps into static sets:
vite build
Align Server Actions and components to runtimes offering full Server-Side script continuity safely supporting 'use server' handlers.
Example GitHub Actions workflow for static build:
name: React CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- run: npm ci
- run: npm run build
Add validation instructions here.