Skip to main content

react-19

React 19 patterns with React Compiler. Trigger: When writing React 19 components/hooks in .tsx (React Compiler rules, hook patterns, refs as props). If using Next.js App Router/Server Actions, also use nextjs-16.

Source facts

Repository
prowler-cloud/prowler
Last source activity
May 12, 2026 at 17:05
Detected SKILL.md language
English
Stars
15,037
Forks
2,435

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
react-19
description
React 19 patterns with React Compiler. Trigger: When writing React 19 components/hooks in .tsx (React Compiler rules, hook patterns, refs as props). If using Next.js App Router/Server Actions, also use nextjs-16.
license
Apache-2.0
metadata
{"author":"prowler-cloud","version":"1.0","scope":["root","ui"],"auto_invoke":"Writing React components"}
allowed-tools
Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
## No Manual Memoization (REQUIRED) ```typescript // ✅ React Compiler handles optimization automatically function Component({ items }) { const filtered = items.filter(x => x.active); const sorted = filtered.sort((a, b) => a.name.localeCompare(b.name)); const handleClick = (id) => { console.log(id); }; return <List items={sorted} onClick={handleClick} />; } // ❌ NEVER: Manual memoization const filtered = useMemo(() => items.filter(x => x.active), [items]); const handleClick = useCallback((id) => console.log(id), []); ``` ## Imports (REQUIRED) ```typescript // ✅ ALWAYS: Named imports import { useState, useEffect, useRef } from "react"; // ❌ NEVER import React from "react"; import * as React from "react"; ``` ## Server Components First ```typescript // ✅ Server Component (default) - no directive export default async function Page() { const data = await fetchData(); return <ClientComponent data={data} />; } // ✅ Client Component - only when needed "use client"; export function Interactive() { const [state, setState] = useState(false); return <button onClick={() => setState(!state)}>Toggle</button>; } ``` ## When to use "use client" - useState, useEffect, useRef, useContext - Event handlers (onClick, onChange) - Browser APIs (window, localStorage) ## use() Hook ```typescript import { use } from "react"; // Read promises (suspends until resolved) function Comments({ promise }) { const comments = use(promise); return comments.map(c => <div key={c.id}>{c.text}</div>); } // Conditional context (not possible with useContext!) function Theme({ showTheme }) { if (showTheme) { const theme = use(ThemeContext); return <div style={{ color: theme.primary }}>Themed</div>; } return <div>Plain</div>; } ``` ## Actions & useActionState ```typescript "use server"; async function submitForm(formData: FormData) { await saveToDatabase(formData); revalidatePath("/"); } // With pending state import { useActionState } from "react"; function Form() { const [state, action, isPending] = useActionState(submitForm, null); return ( <form action={action}> <button disabled={isPending}> {isPending ? "Saving..." : "Save"} </button> </form> ); } ``` ## ref as Prop (No forwardRef) ```typescript // ✅ React 19: ref is just a prop function Input({ ref, ...props }) { return <input ref={ref} {...props} />; } // ❌ Old way (unnecessary now) const Input = forwardRef((props, ref) => <input ref={ref} {...props} />); ```
View on GitHub