Reviews React hooks against design principles: object returns, SSR-safe init, effect cleanup, TypeScript generics, performance, and state patterns.
npx claudepluginhub toss/react-simplikit --plugin react-design-philosophyThis skill uses the workspace's default tool permissions.
Review hooks against coding principles and usage patterns. Report findings by severity.
Guides writing React hooks with conventions for object returns, SSR safety, state design, effect patterns, cleanup, TypeScript, and performance.
Reviews React components for architecture, hooks usage, React 19 patterns, state management, performance optimization, accessibility, and TypeScript. Use before merging PRs, after new features, or for validation.
Provides React best practices for function components, props interfaces, compound components, useState, useEffect hooks, and state management. Useful for optimizing React code architecture and performance.
Share bugs, ideas, or general feedback.
Review hooks against coding principles and usage patterns. Report findings by severity.
Treat C1, C7, and C14 as opinionated conventions unless the target codebase explicitly adopts them. Report them as stronger findings when the repository standard is clear; otherwise phrase them as consistency recommendations.
Return values (C1) — Always return objects, even for single values. { value } not bare primitives.
Why: Named fields, order-independent, extensible without breaking changes.
SSR-safe init (C2) — useState(FIXED) + useEffect(sync). No browser API in initializer.
Why: Server has no window — crashes or hydration mismatch.
Note: For explicitly client-only hooks, a guarded lazy initializer can be acceptable.
Cleanup (C3) — Every useEffect with side effects returns cleanup (listeners, timers, AbortController). Why: Memory leaks. StrictMode double-mount exposes missing cleanup immediately.
No any (C4) — Use generics <T>. Justified eslint-disable with comment is acceptable.
Why: any propagates and defeats the type system.
Named exports (C5) — No default exports. Tree-shaking + unambiguous imports.
Strict booleans (C6) — == null for nullish, !== undefined for distinction. No implicit if (value).
Why: 0, "", false are falsy — silent bugs.
Object parameters (C7) — Hook params as object props, not positional args. Why: Order-independent, self-documenting, extensible.
JSDoc 4-tag (C9) — @description + @param + @returns + @example on every public API. Why: AI doc generation quality + IDE tooltips.
Performance (C10) — Throttle (16ms) for >30 events/sec, deduplicate unchanged, startTransition for non-urgent. Only applies to high-frequency event hooks.
Zero deps (C12) — No runtime dependencies. peerDependencies only.
Dependency isolation (C13) — Inject external dependencies as parameters rather than importing them directly inside hooks. Why: Testability + replaceability.
Guard clauses (C8) — Early return over nested if-else. Flat success path. Trade-off: Stylistic preference with no functional impact.
Function keyword (C11) — function for declarations, arrows for inline callbacks only.
Trade-off: Consistent style, but arrow declarations are valid JS.
Named useEffect (C14) — useEffect(function handleX() {...}) not arrows.
Why: "handleResize" vs "anonymous" in error stacks. Trade-off: more verbose.
useEffect for derived values.initialX.key={id} to remount, not useEffect to clear state.ignore flag or AbortController for every async effect.useMount. Purpose-specific hooks only.codecode