Skip to main content
ClaudeWave
ES, Spanish
Skill1.1k estrellas del repoactualizado 19d ago

react-patterns

react-patterns provides 50+ ranked performance and composition rules for React 19 projects using Vite and Cloudflare Workers, covering waterfalls, bundle optimization, re-render prevention, and server/client boundaries. Use it as a checklist when writing new components, a review guide for auditing code, or a refactoring reference when troubleshooting slow performance or tangled component hierarchies.

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/jezweb/claude-skills /tmp/react-patterns && cp -r /tmp/react-patterns/plugins/frontend/skills/react-patterns ~/.claude/skills/react-patterns
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

SKILL.md

# React Patterns

Performance and composition patterns for React 19 + Vite + Cloudflare Workers projects. Use as a checklist when writing new components, a review guide when auditing existing code, or a refactoring playbook when something feels slow or tangled.

Rules are ranked by impact. Fix CRITICAL issues before touching MEDIUM ones.

## When to Apply

- Writing new React components or pages
- Reviewing code for performance issues
- Refactoring components with too many props or re-renders
- Debugging "why is this slow?" or "why does this re-render?"
- Building reusable component libraries
- Code review before merging

## 1. Eliminating Waterfalls (CRITICAL)

Sequential async calls where they could be parallel. The #1 performance killer.

| Pattern | Problem | Fix |
|---------|---------|-----|
| **Await in sequence** | `const a = await getA(); const b = await getB();` | `const [a, b] = await Promise.all([getA(), getB()]);` |
| **Fetch in child** | Parent renders, then child fetches, then grandchild fetches | Hoist fetches to the highest common ancestor, pass data down |
| **Suspense cascade** | Multiple Suspense boundaries that resolve sequentially | One Suspense boundary wrapping all async siblings |
| **Await before branch** | `const data = await fetch(); if (condition) { use(data); }` | Move await inside the branch — don't fetch what you might not use |
| **Import then render** | `const Component = await import('./Heavy'); return <Component />` | Use `React.lazy()` + `<Suspense>` — renders fallback instantly |

**How to find them**: Search for `await` in components. Each `await` is a potential waterfall. If two awaits are independent, they should be parallel.

## 2. Bundle Size (CRITICAL)

Every KB the user downloads is a KB they wait for.

| Pattern | Problem | Fix |
|---------|---------|-----|
| **Barrel imports** | `import { Button } from '@/components'` pulls the entire barrel file | `import { Button } from '@/components/ui/button'` — direct import |
| **No code splitting** | Heavy component loaded on every page | `React.lazy(() => import('./HeavyComponent'))` + `<Suspense>` |
| **Third-party at load** | Analytics/tracking loaded before the app renders | Load after hydration: `useEffect(() => { import('./analytics') }, [])` |
| **Full library import** | `import _ from 'lodash'` (70KB) | `import debounce from 'lodash/debounce'` (1KB) |
| **Lucide tree-shaking** | `import * as Icons from 'lucide-react'` (all icons) | Explicit map: `import { Home, Settings } from 'lucide-react'` |
| **Duplicate React** | Library bundles its own React → "Cannot read properties of null" | `resolve.dedupe: ['react', 'react-dom']` in vite.config.ts |

**How to find them**: `npx vite-bundle-visualizer` — shows what's in your bundle.

## 3. Composition Architecture (HIGH)

How you structure components matters more than how you optimise them.

| Pattern | Problem | Fix |
|---------|---------|-----|
| **Boolean prop explosion** | `<Card isCompact isClickable showBorder hasIcon isLoading>` | Explicit variants: `<CompactCard>`, `<ClickableCard>` |
| **Compound components** | Complex component with 15 props | Split into `<Dialog>`, `<Dialog.Trigger>`, `<Dialog.Content>` with shared context |
| **renderX props** | `<Layout renderSidebar={...} renderHeader={...} renderFooter={...}>` | Use children + named slots: `<Layout><Sidebar /><Header /></Layout>` |
| **Lift state** | Sibling components can't share state | Move state to parent or context provider |
| **Provider implementation** | Consumer code knows about state management internals | Provider exposes interface `{ state, actions, meta }` — implementation hidden |
| **Inline components** | `function Parent() { function Child() { ... } return <Child /> }` | Define Child outside Parent — inline components remount on every render |

**The test**: If a component has more than 5 boolean props, it needs composition, not more props.

## 4. Re-render Prevention (MEDIUM)

Not all re-renders are bad. Only fix re-renders that cause visible jank or wasted computation.

| Pattern | Problem | Fix |
|---------|---------|-----|
| **Default object/array props** | `function Foo({ items = [] })` → new array ref every render | Hoist: `const DEFAULT = []; function Foo({ items = DEFAULT })` |
| **Derived state in effect** | `useEffect(() => setFiltered(items.filter(...)), [items])` | Derive during render: `const filtered = useMemo(() => items.filter(...), [items])` |
| **Object dependency** | `useEffect(() => {...}, [config])` fires every render if config is `{}` | Use primitive deps: `useEffect(() => {...}, [config.id, config.type])` |
| **Subscribe to unused state** | Component reads `{ user, theme, settings }` but only uses `user` | Split context or use selector: `useSyncExternalStore` |
| **State for transient values** | `const [mouseX, setMouseX] = useState(0)` on mousemove | Use `useRef` for values that change frequently but don't need re-render |
| **Inline callback props** | `<Button onClick={() => doThing(id)} />` — new function every render | `useCallback` or functional setState: `<Button onClick={handleClick} />` |

**How to find them**: React DevTools Profiler → "Why did this render?" or `<React.StrictMode>` double-renders in dev.

## 5. React 19 Specifics (MEDIUM)

Patterns that changed or are new in React 19.

| Pattern | Old (React 18) | New (React 19) |
|---------|---------------|----------------|
| **Form state** | `useFormState` | `useActionState` — renamed |
| **Ref forwarding** | `forwardRef((props, ref) => ...)` | `function Component({ ref, ...props })` — ref is a regular prop |
| **Context** | `useContext(MyContext)` | `use(MyContext)` — works in conditionals and loops |
| **Pending UI** | Manual loading state | `useTransition` + `startTransition` for non-urgent updates |
| **Route-level lazy** | Works with `createBrowserRouter` only | Still true — `<Route lazy={...}>` is silently ignored with `<BrowserRouter>` |
| **Optimistic updates** | Manual state man
ai-image-generatorSkill

Generate AI images using Gemini or GPT APIs directly. Covers model selection (Gemini for scenes; GPT Image 2 for text rendering, batch variations, multi-reference compositing; GPT Image 1.5 for transparent icons), the 5-part prompting framework, API calling patterns, multi-turn editing, and quality assurance. Produces photorealistic scenes, icons, illustrations, OG images, posters, infographics, and product shots. Use when building websites that need images, creating marketing assets, or generating visual content. Triggers: 'generate image', 'ai image', 'create hero image', 'make an icon', 'generate illustration', 'create og image', 'poster', 'infographic', 'image variations', 'gpt-image-2', 'ai art', 'image generation'.

app-docsSkill

Generate complete user documentation for a web app with screenshots. Browses the app via browser automation, screenshots every screen, and produces a structured user guide with step-by-step instructions, annotated screenshots, workflow diagrams, and reference tables. Supports quick (key screens), standard (all pages), thorough (every state and flow), and exhaustive (publishable documentation suite). Triggers: 'document the app', 'user guide', 'app documentation', 'screenshot docs', 'generate user docs', 'help docs', 'how-to guide', 'write the docs'.

aussie-business-englishSkill

Australian business English for professional writing — warm, direct, EN-AU spelling (colour, organise, centre), no filler words. Use whenever the user is writing for an Australian audience: emails, chat messages, proposals, client communications, blog posts, web copy, or any business writing. Apply to drafting, editing, and tone-checking professional text.

award-applicationSkill

Write compelling award submissions, grant applications, and competition entries. Maps achievements to selection criteria using evidence-based narratives. Use whenever the user is applying for a business award (Telstra, chamber of commerce, industry awards), a grant, a competition, or any submission demonstrating merit against defined criteria.

brains-trustSkill

Get a second opinion from leading AI models on code, architecture, strategy, prompting, or anything. Queries models via OpenRouter, Gemini, or OpenAI APIs. Supports single opinion, multi-model consensus, and devil's advocate patterns. Use whenever the user says 'brains trust', 'second opinion', 'ask gemini', 'ask gpt', 'peer review', 'consult another model', 'challenge this', or 'devil's advocate'.

cloudflare-apiSkill

Hit the Cloudflare REST API directly for operations that wrangler and MCP can't handle well. Bulk DNS, custom hostnames, email routing, cache purge, WAF rules, redirect rules, zone settings, Worker routes, D1 cross-database queries, R2 bulk operations, KV bulk read/write, Vectorize queries, Queues, and fleet-wide resource audits. Produces curl commands or scripts. Triggers: 'cloudflare api', 'bulk dns', 'custom hostname', 'email routing', 'cache purge', 'waf rule', 'd1 query', 'r2 bucket', 'kv bulk', 'vectorize query', 'audit resources', 'fleet operation'.

cloudflare-worker-builderSkill

Scaffold and deploy Cloudflare Workers with Hono routing, Vite plugin, and Static Assets. Describe project, scaffold structure, configure bindings, deploy. Use whenever the user wants to create a Worker project, set up Hono on Cloudflare, configure D1 / R2 / KV / Queues bindings, or troubleshoot Worker export syntax, API route conflicts, HMR issues, or deployment failures.

codex-reviewSkill

Run an independent code review using the OpenAI Codex CLI in headless mode. Gets a second opinion from a different model family (the current Codex models) on recent changes, a PR, a commit, or the whole app — covering bugs, regressions, security, data consistency, UX/state bugs, performance risks, and testing gaps. Saves a severity-prioritised report to .jez/reviews/. Triggers: 'codex review', 'review with codex', 'independent code review', 'what does codex think', 'get codex to review'.