
Frontend React Best Practices
Apply 33 React performance and composition rules when writing, reviewing, or refactoring components so bundles stay lean and re-renders stay predictable.
Overview
Frontend React Best Practices is an agent skill most often used in Build (also Ship review) that applies 33 React rules across 6 categories for rendering and bundle optimization.
Install
npx skills add https://github.com/sergiodxa/agent-skills --skill frontend-react-best-practicesWhat is this skill?
- 33 performance and composition rules organized across 6 categories
- CRITICAL bundle-size rules: direct icon imports, conditional dynamic import, hover/focus preload
- Covers writing, code review, refactoring, hooks, memoization, and bundle optimization
- Concrete bad/good examples (e.g. lucide-react barrel vs deep ESM paths)
- Per-rule markdown references under @rules/ for agent-deep dives
- 33 rules across 6 categories
- Bundle-size category marked CRITICAL with barrel-import latency examples (200–800ms)
Adoption & trust: 873 installs on skills.sh; 87 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your React UI works but feels slow, ships bloated bundles, or re-renders too often because imports, hooks, and composition were never standardized.
Who is it for?
Indie frontend-heavy SaaS or extension builders who want agent-enforced React performance habits during implementation and review.
Skip if: Non-React stacks, pure backend APIs, or teams that only need visual design tokens without runtime performance constraints.
When should I use this skill?
Writing, reviewing, or refactoring React components; tasks involving hooks, memoization, or bundle optimization.
What do I get? / Deliverables
Components and reviews follow documented bundle, hook, and composition rules so rendering cost and import graphs improve before merge.
- Performance-aligned component code
- Review feedback mapped to rule categories
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Canonical shelf is Build frontend because the core triggers are new components, hooks, memoization, and bundle work. Frontend is the natural home for barrel-import fixes, conditional bundles, and hook/state guidance across the rule set.
Where it fits
Author a new dashboard widget using direct ESM icon imports instead of library barrels.
Gate a heavy chart module behind a feature flag with conditional dynamic import.
Run the 33-rule lens on a PR that touches hooks and shared state.
Refactor hot paths after user-reported sluggish UI without rewriting the whole app.
How it compares
Rule-backed review skill for React—use instead of one-off chat suggestions when optimizing bundles and re-renders.
Common Questions / FAQ
Who is frontend-react-best-practices for?
Solo and indie builders using React who want consistent performance guidance while coding or reviewing UI with an agent.
When should I use frontend-react-best-practices?
In Build frontend when writing components; in Ship review when auditing performance; whenever tasks mention hooks, memoization, or bundle size.
Is frontend-react-best-practices safe to install?
Review the Security Audits panel on this Prism page; the skill is documentation-driven and does not require network or shell by default.
SKILL.md
READMESKILL.md - Frontend React Best Practices
# React Best Practices Performance optimization and composition patterns for React components. Contains 33 rules across 6 categories focused on reducing re-renders, optimizing bundles, component composition, and avoiding common React pitfalls. ## When to Apply Reference these guidelines when: - Writing new React components - Reviewing code for performance issues - Refactoring existing React code - Optimizing bundle size - Working with hooks and state ## Rules Summary ### Bundle Size Optimization (CRITICAL) #### bundle-barrel-imports - @rules/bundle-barrel-imports.md Import directly from source, avoid barrel files. ```tsx // Bad: loads entire library (200-800ms) import { Check, X } from "lucide-react"; // Good: loads only what you need import Check from "lucide-react/dist/esm/icons/check"; import X from "lucide-react/dist/esm/icons/x"; ``` #### bundle-conditional - @rules/bundle-conditional.md Load modules only when feature is activated. ```tsx useEffect(() => { if (enabled && typeof window !== "undefined") { import("./heavy-module").then((mod) => setModule(mod)); } }, [enabled]); ``` #### bundle-preload - @rules/bundle-preload.md Preload on hover/focus for perceived speed. ```tsx <button onMouseEnter={() => import("./editor")} onFocus={() => import("./editor")} onClick={openEditor} > Open Editor </button> ``` ### Re-render Optimization (MEDIUM) #### rerender-functional-setstate - @rules/rerender-functional-setstate.md Use functional setState for stable callbacks. ```tsx // Bad: stale closure risk, recreates on items change const addItem = useCallback( (item) => { setItems([...items, item]); }, [items], ); // Good: always uses latest state, stable reference const addItem = useCallback((item) => { setItems((curr) => [...curr, item]); }, []); ``` #### rerender-derived-state-no-effect - @rules/rerender-derived-state-no-effect.md Derive state during render, not in effects. ```tsx // Bad: extra state and effect, extra render const [fullName, setFullName] = useState(""); useEffect(() => { setFullName(firstName + " " + lastName); }, [firstName, lastName]); // Good: derived directly during render const fullName = firstName + " " + lastName; ``` #### rerender-lazy-state-init - @rules/rerender-lazy-state-init.md Pass function to useState for expensive initial values. ```tsx // Bad: runs expensiveComputation() on every render const [data] = useState(expensiveComputation()); // Good: runs only on initial render const [data] = useState(() => expensiveComputation()); ``` #### rerender-dependencies - @rules/rerender-dependencies.md Use primitive dependencies in effects. ```tsx // Bad: runs on any user field change useEffect(() => { console.log(user.id); }, [user]); // Good: runs only when id changes useEffect(() => { console.log(user.id); }, [user.id]); ``` #### rerender-derived-state - @rules/rerender-derived-state.md Subscribe to derived booleans, not raw values. ```tsx // Bad: re-renders on every pixel change const width = useWindowWidth(); const isMobile = width < 768; // Good: re-renders only when boolean changes const isMobile = useMediaQuery("(max-width: 767px)"); ``` #### rerender-memo - @rules/rerender-memo.md Extract expensive work into memoized components. ```tsx // Good: skips computation when loading const UserAvatar = memo(function UserAvatar({ user }) { let id = useMemo(() => computeAvatarId(user), [user]); return <Avatar id={id} />; }); function Profile({ user, loading }) { if (loading) return <Skeleton />; return <UserAvatar user={user} />; } ``` #### rerender-memo-with-default-value - @rules/rerender-memo-with-default-value.md Hoist default non-p