- Adopt feature-based or domain-driven folder structure
- Colocate related files (component + hooks + styles)
- Avoid deep nesting (>4 levels is a red flag)
- Move reusable UI to
shared/ui/(buttons, modals)
- Split monolithic components into smaller ones
- Follow Single Responsibility Principle
- Use composition (
<Card><Header /></Card>) - Convert class components to functional + hooks
- Eliminate prop drilling (use Context/Zustand)
- Separate server state (TanStack Query) from client state
- Avoid unnecessary global state
- Memoize selectors in Redux/Zustand
- Memoize components with
React.memo - Cache expensive calcs with
useMemo - Prevent re-renders with
useCallback - Lazy-load routes (
React.lazy + Suspense) - Virtualize long lists (react-window)
- Migrate to TypeScript (or add PropTypes)
- Define strict types for API responses
- Use generics for reusable hooks
- Add unit tests (React Testing Library)
- Test critical user flows (login, checkout)
- Mock API calls (MSW/fetch-mock)
- Enforce consistent naming (PascalCase, camelCase)
- Setup ESLint/Prettier (shared config)
- Document components (Storybook/JSDoc)
- Add error boundaries
- Identify "code smell" components
- Write tests before refactoring
- Refactor in small, verified steps
- Verify no regressions