--- name: react-best-practices description: Comprehensive React and Next.js best practices guide covering performance optimization, component architecture, shadcn/ui patterns, Motion animations, and modern React 19+ patterns. This skill should be used when writing, reviewing, or refactoring React/Next.js code. Triggers on tasks involving React components, Next.js pages, data fetching, UI components, animations, or code quality improvements. license: MIT --- # React Best Practices Comprehensive guide for building modern React and Next.js applications. Covers performance optimization, component architecture, shadcn/ui patterns, Motion animations, accessibility, and React 19+ features. ## When to Apply Reference these guidelines when: - Writing new React components or Next.js pages - Implementing data fetching (client or server-side) - Building UI with shadcn/ui components - Adding animations and micro-interactions - Reviewing code for quality and performance - Refactoring existing React/Next.js code - Optimizing bundle size or load times ## Rule Categories by Priority | Priority | Category | Impact | Prefix | |----------|----------|--------|--------| | 1 | Component Architecture | CRITICAL | `arch-` | | 2 | Eliminating Waterfalls | CRITICAL | `async-` | | 3 | Bundle Size Optimization | CRITICAL | `bundle-` | | 4 | Server Components & Actions | HIGH | `server-` | | 5 | shadcn/ui Patterns | HIGH | `shadcn-` | | 6 | State Management | MEDIUM-HIGH | `state-` | | 7 | Motion & Animations | MEDIUM | `motion-` | | 8 | Re-render Optimization | MEDIUM | `rerender-` | | 9 | Accessibility | MEDIUM | `a11y-` | | 10 | TypeScript Patterns | MEDIUM | `ts-` | --- ## 1. Component Architecture (CRITICAL) ### Quick Reference - `arch-functional-components` - Use functional components with hooks exclusively - `arch-composition-over-inheritance` - Build on existing components, don't extend - `arch-single-responsibility` - Each component should do one thing well - `arch-presentational-container` - Separate UI from logic when beneficial - `arch-colocation` - Keep related files together (component, styles, tests) - `arch-avoid-prop-drilling` - Use Context or composition for deep props ### Key Principles **Functional Components Only** ```typescript // Correct: Functional component with hooks function UserProfile({ userId }: { userId: string }) { const { data: user } = useUser(userId) return
{user?.name}
} // Incorrect: Class component class UserProfile extends React.Component { /* ... */ } ``` **Composition Pattern** ```typescript // Correct: Compose smaller components function Card({ children }: { children: React.ReactNode }) { return
{children}
} function CardHeader({ children }: { children: React.ReactNode }) { return
{children}
} // Usage Title

Content

``` **Avoid Prop Drilling** ```typescript // Incorrect: Passing props through many levels // Correct: Use Context for shared state const UserContext = createContext(null) function App() { const user = useCurrentUser() return ( ) } ``` --- ## 2. Eliminating Waterfalls (CRITICAL) ### Quick Reference - `async-defer-await` - Move await into branches where actually used - `async-parallel` - Use Promise.all() for independent operations - `async-dependencies` - Handle partial dependencies correctly - `async-api-routes` - Start promises early, await late in API routes - `async-suspense-boundaries` - Use Suspense to stream content ### Key Principles Waterfalls are the #1 performance killer. Each sequential await adds full network latency. **Parallel Data Fetching** ```typescript // Incorrect: Sequential waterfalls async function Page() { const user = await fetchUser() const posts = await fetchPosts() const comments = await fetchComments() return
{/* render */}
} // Correct: Parallel fetching async function Page() { const [user, posts, comments] = await Promise.all([ fetchUser(), fetchPosts(), fetchComments() ]) return
{/* render */}
} ``` **Strategic Suspense Boundaries** ```typescript // Stream content as it becomes available function Page() { return (
}> }>
) } ``` --- ## 3. Bundle Size Optimization (CRITICAL) ### Quick Reference - `bundle-barrel-imports` - Import directly, avoid barrel files - `bundle-dynamic-imports` - Use next/dynamic for heavy components - `bundle-defer-third-party` - Load analytics/logging after hydration - `bundle-conditional` - Load modules only when feature is activated - `bundle-preload` - Preload on hover/focus for perceived speed ### Key Principles **Avoid Barrel File Imports** ```typescript // Incorrect: Imports entire library import { Button } from '@/components' import { formatDate } from '@/utils' // Correct: Direct imports enable tree-shaking import { Button } from '@/components/ui/button' import { formatDate } from '@/utils/date' ``` **Dynamic Imports** ```typescript import dynamic from 'next/dynamic' // Load only when needed const HeavyChart = dynamic(() => import('./HeavyChart'), { loading: () => , ssr: false }) function Dashboard({ showChart }) { return showChart ? : null } ``` --- ## 4. Server Components & Actions (HIGH) ### Quick Reference - `server-default-server` - Components are Server Components by default - `server-use-client-boundary` - Add 'use client' only when needed - `server-actions` - Use Server Actions for mutations - `server-cache-react` - Use React.cache() for per-request deduplication - `server-serialization` - Minimize data passed to client components ### Key Principles **Server Components by Default** ```typescript // Server Component (default) - can be async async function ProductPage({ id }: { id: string }) { const product = await db.product.findUnique({ where: { id } }) return } // Client Component - only when needed for interactivity 'use client' function AddToCartButton({ productId }: { productId: string }) { const [isPending, startTransition] = useTransition() return ( ) } ``` **Server Actions** ```typescript // actions.ts 'use server' export async function createPost(formData: FormData) { const title = formData.get('title') as string const content = formData.get('content') as string await db.post.create({ data: { title, content } }) revalidatePath('/posts') } // Component usage function CreatePostForm() { return (