Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Comprehensive React 19 patterns including all hooks, Server/Client Components, Suspense, streaming, and transitions. Ensures correct React 19 usage with TypeScript.
.claude/skills/aiskillstore-react-19-patterns/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 38% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 126% | 0% |
| case-17 | ✗→✓ | ▲ Improved | 58% | 0% |
| case-06 | ✓→✓ | = Same ✓ | 88% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 89% | 0% |
Use this skill when:
use() - For async data in componentsuseOptimistic() - For optimistic UI updatesuseFormStatus() - For form submission stateuseActionState() - For Server Action stateuseTransition() - Better performancetypescript// ✅ Default - async data fetching export default async function ProjectsPage() { const projects = await db.project.findMany() return <ProjectList projects={projects} /> }
typescript// ✅ Use 'use client' for interactivity 'use client' import { useState } from 'react' export function InteractiveComponent() { const [count, setCount] = useState(0) return <button onClick={() => setCount(count + 1)}>{count}</button> }
typescript'use client' import { useOptimistic } from 'react' export function TodoList({ todos }: Props) { const [optimisticTodos, addOptimisticTodo] = useOptimistic( todos, (state, newTodo: string) => [...state, { id: 'temp', text: newTodo, pending: true }] ) return ( <form action={async (formData) => { addOptimisticTodo(formData.get('todo')) await createTodo(formData) }}> <input name="todo" /> <button type="submit">Add</button> </form> ) }
This skill is organized into detailed guides:
START: Creating new component
│
├─ Does it need interactivity (onClick, onChange)?
│ ├─ YES → Read client-components-complete.md
│ └─ NO → Continue
│
├─ Does it need React hooks (useState, useEffect)?
│ ├─ YES → Read client-components-complete.md + hooks-complete.md
│ └─ NO → Continue
│
├─ Does it fetch data?
│ ├─ YES → Read server-components-complete.md
│ └─ NO → Continue
│
└─ Default → Server Component (read server-components-complete.md)
Need specific hook help?
└─ Read hooks-complete.md (complete reference)
Need Suspense/streaming?
└─ Read suspense-patterns.md + streaming-patterns.md
Need optimistic UI?
└─ Read hooks-complete.md (useOptimistic section)
Need form handling?
└─ Read hooks-complete.md (useFormStatus, useActionState)
Migrating from React 18?
└─ Read migration-guide.mdtypescript'use client' export default async function Bad() {} // ERROR!
typescript// Option 1: Server Component export default async function Good() {} // ✅ // Option 2: Client with useEffect 'use client' export default function Good() { useEffect(() => { fetchData() }, []) }
typescriptif (condition) { useState(0) // ERROR: Rules of Hooks violation }
typescriptconst [value, setValue] = useState(0) if (condition) { // Use the hook result here }
typescriptexport default function Bad() { const data = localStorage.getItem('key') // ERROR! return <div>{data}</div> }
typescript'use client' export default function Good() { const [data, setData] = useState(() => localStorage.getItem('key') ) return <div>{data}</div> }
Use validate-react.py to check your React code:
bash# Validate single file python .claude/skills/react-19-patterns/validate-react.py src/components/Button.tsx # Validate directory python .claude/skills/react-19-patterns/validate-react.py src/components/ # Auto-fix (where possible) python .claude/skills/react-19-patterns/validate-react.py --fix src/components/
Checks for:
use() for async datauseOptimistic() for instant feedbackuseFormStatus() for form statesuseActionState() for Server ActionsLast Updated: 2025-11-23 React Version: 19.2.0 Next.js Version: 15.5
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-06 | pass→pass | 17,351 | 15,037 | -13% | 1 | 1 | 0% | 2,052 | 3,851 | +88% | 0 | 0 | — |
case-01 | fail→pass | 23,466 | 20,182 | -14% | 1 | 1 | 0% | 3,328 | 4,608 | +38% | 0 | 0 | — |
case-02 | pass→pass | 18,603 | 20,622 | +11% | 1 | 1 | 0% | 2,493 | 4,718 | +89% | 0 | 0 | — |
case-03 | pass→pass | 11,056 | 6,960 | -37% | 1 | 1 | 0% | 1,150 | 3,097 | +169% | 0 | 0 | — |
case-04 | pass→pass | 10,214 | 13,211 | +29% | 1 | 1 | 0% | 1,732 | 3,578 | +107% | 0 | 0 | — |
case-05 | pass→pass | 14,743 | 9,050 | -39% | 1 | 1 | 0% | 1,827 | 3,656 | +100% | 0 | 0 | — |
case-07 | pass→pass | 18,766 | 15,436 | -18% | 1 | 1 | 0% | 2,593 | 4,172 | +61% | 0 | 0 | — |
case-08 | pass→pass | 15,837 | 9,583 | -39% | 1 | 1 | 0% | 1,890 | 3,705 | +96% | 0 | 0 | — |
case-09 | pass→pass | 10,205 | 7,101 | -30% | 1 | 1 | 0% | 1,645 | 3,290 | +100% | 0 | 0 | — |
case-10 | pass→pass | 18,244 | 12,928 | -29% | 1 | 1 | 0% | 2,669 | 4,725 | +77% | 0 | 0 | — |
case-11 | pass→pass | 14,956 | 14,787 | -1% | 1 | 1 | 0% | 1,866 | 4,577 | +145% | 0 | 0 | — |
case-12 | fail→pass | 9,699 | 12,250 | +26% | 1 | 1 | 0% | 1,735 | 3,925 | +126% | 0 | 0 | — |
case-13 | pass→pass | 22,590 | 12,114 | -46% | 1 | 1 | 0% | 2,127 | 4,232 | +99% | 0 | 0 | — |
case-14 | pass→pass | 18,937 | 17,929 | -5% | 1 | 1 | 0% | 2,472 | 4,503 | +82% | 0 | 0 | — |
case-15 | pass→pass | 8,890 | 10,444 | +17% | 1 | 1 | 0% | 669 | 2,784 | +316% | 0 | 0 | — |
case-16 | pass→pass | 12,728 | 18,283 | +44% | 1 | 1 | 0% | 2,487 | 4,324 | +74% | 0 | 0 | — |
case-17 | fail→pass | 13,643 | 7,723 | -43% | 1 | 1 | 0% | 1,529 | 2,415 | +58% | 0 | 0 | — |
case-18 | pass→pass | 17,308 | 13,343 | -23% | 1 | 1 | 0% | 1,536 | 3,120 | +103% | 0 | 0 | — |
case-19 | pass→pass | 14,370 | 21,785 | +52% | 1 | 1 | 0% | 2,560 | 4,885 | +91% | 0 | 0 | — |
case-20 | pass→pass | 15,105 | 14,331 | -5% | 1 | 1 | 0% | 1,633 | 3,692 | +126% | 0 | 0 | — |
case-21 | pass→pass | 11,895 | 15,590 | +31% | 1 | 1 | 0% | 1,939 | 3,659 | +89% | 0 | 0 | — |
case-22 | pass→pass | 20,154 | 19,019 | -6% | 1 | 1 | 0% | 2,199 | 4,305 | +96% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +14 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.