React Core
Comprehensive guidance for building scalable, performant, and secure React applications with modern best practices.
Quick Start
New Project Setup
Initialize with Vite:
pnpm create vite my-app --template react-ts cd my-app pnpm installUse configuration templates:
- Vite: assets/config-templates/vite.config.ts
- Vitest: assets/config-templates/vitest.config.ts
- ESLint: assets/config-templates/.eslintrc.react.json
Install essential dependencies:
# Routing pnpm add react-router-dom # Data fetching pnpm add @tanstack/react-query # Forms pnpm add react-hook-form @hookform/resolvers zod # State management (if needed) pnpm add zustandOrganize by feature: See project-structure.md for complete layouts
Common Workflows
Resolving Performance Issues:
- Check performance.md for optimization techniques
- Profile with React DevTools
- Implement code splitting, virtualization, or memoization as needed
Setting Up State Management:
- Review state-management.md decision framework
- Choose appropriate solution (component state, Context, Zustand, React Query)
- Implement following documented patterns
Implementing Authentication:
- Follow security guidelines in security.md
- Use HttpOnly cookies for tokens
- Implement protected routes and authorization
Project Architecture
Project Structure
Organize code by feature, not by technical type:
src/
├── app/ # App-level routing
├── features/ # Feature modules (self-contained)
│ ├── authentication/
│ ├── users/
│ └── dashboard/
├── components/ # Shared components
├── hooks/ # Shared hooks
├── lib/ # Third-party setup
└── utils/ # Shared utilities
Key principles:
- Feature isolation with clear public APIs
- Unidirectional dependency flow (app → features → shared)
- Absolute imports via path aliases
- Consistent naming conventions
See project-structure.md for complete guide including:
- Feature module organization
- Shared code structure
- Enforcing architectural boundaries with ESLint
- Monorepo considerations
State Management
Choose the right state solution for each use case:
| State Type | Tool | Example |
|---|---|---|
| Component | useState, useReducer | Form inputs, toggles |
| Application | Context, Zustand, Jotai | Theme, auth status |
| Server Cache | React Query, SWR | API data |
| Form | React Hook Form | Form values, validation |
| URL | React Router | Filters, pagination |
Decision framework:
- Server data? → Use React Query
- Form data? → Use React Hook Form
- Should be in URL? → Use useSearchParams
- Shared across app? → Use Zustand/Context
- Otherwise → Component state
See state-management.md for complete patterns including:
- useState vs useReducer
- Context optimization
- Zustand and Jotai examples
- React Query patterns
- State colocation best practices
Performance
Critical Optimizations
Code Splitting - Load code on demand
const Dashboard = lazy(() => import('./routes/Dashboard'));List Virtualization - Render only visible items
import { useVirtualizer } from '@tanstack/react-virtual';Image Optimization - Lazy load and use modern formats
<img src="/image.jpg" loading="lazy" />Bundle Optimization - Analyze and reduce bundle size
npx vite-bundle-visualizer
React 19 Compiler
React 19's compiler automatically memoizes - remove manual React.memo, useMemo, useCallback when using the compiler.
See performance.md for complete guide including:
- Component optimization (memoization)
- List virtualization with examples
- Web Vitals optimization
- Data prefetching strategies
- Performance monitoring tools
API Layer
Structure API calls for maintainability and type safety:
// features/users/api/get-user.ts
import { z } from 'zod';
import { useQuery } from '@tanstack/react-query';
const userSchema = z.object({
id: z.string(),
name: z.string(),
email: z.string().email(),
});
export type User = z.infer<typeof userSchema>;
export async function getUser(userId: string): Promise<User> {
const response = await apiClient.get(`/users/${userId}`);
return userSchema.parse(response.data);
}
export function useUser(userId: string) {
return useQuery({
queryKey: ['users', userId],
queryFn: () => getUser(userId),
});
}
See api-layer.md for complete patterns including:
- API client setup (Axios/Fetch)
- Request organization
- Error handling
- TypeScript integration
- Authentication patterns
Testing
Follow the testing pyramid:
/\
/E2E\ ← Few
/------\
/Integr.\ ← Some
/----------\
/ Unit \ ← Many
Tools:
- Vitest (test runner)
- React Testing Library (component testing)
- Playwright (E2E testing)
- MSW (API mocking)
Example:
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
test('button calls onClick when clicked', async () => {
const handleClick = vi.fn();
const user = userEvent.setup();
render(<Button me</Button>);
await user.click(screen.getByRole('button'));
expect(handleClick).toHaveBeenCalledTimes(1);
});
See testing.md for complete guide including:
- Component testing patterns
- Hook testing
- Integration tests
- MSW setup
- E2E with Playwright
Security
Key Security Practices
- Authentication - Use HttpOnly cookies
- Authorization - Implement RBAC/PBAC
- XSS Prevention - Sanitize user content
- CSRF Protection - Use SameSite cookies
- Input Validation - Validate client and server-side
Example:
// ✅ Secure token storage
// Server sets HttpOnly cookie
res.cookie('auth_token', token, {
httpOnly: true,
secure: true,
sameSite: 'strict',
});
// ✅ Sanitize user content
import DOMPurify from 'dompurify';
const sanitized = DOMPurify.sanitize(userContent);
See security.md for complete guide including:
- Token storage best practices
- Protected routes
- Role and permission-based access control
- XSS and CSRF prevention
- CSP configuration
React 19 Features
Major Improvements
- React Compiler - Automatic memoization
- Server Components - Render on server
- Actions - Simplified form handling
- New Hooks - use(), useFormStatus(), useOptimistic()
- Simplified refs - No more forwardRef
Example:
'use client';
import { useActionState } from 'react';
async function createUserAction(prevState, formData) {
const user = await api.createUser(formData);
return { success: true, user };
}
export function CreateUserForm() {
const [state, formAction, isPending] = useActionState(createUserAction, null);
return (
<form action={formAction}>
<input name="email" required />
<button disabled={isPending}>
{isPending ? 'Creating...' : 'Create'}
</button>
</form>
);
}
See react-19-best-practices.md for complete guide.
Build & Tooling
Vite Configuration
Optimized build setup with code splitting, minification, and tree shaking.
See build-and-bundling.md for:
- Complete Vite configuration
- Code splitting strategies
- Bundle analysis
- Production optimizations
Essential Tools
See ecosystem-tools.md for recommended packages:
- Routing (React Router, TanStack Router)
- Data fetching (React Query, SWR)
- Forms (React Hook Form)
- State (Zustand, Jotai)
- Styling (Tailwind, CSS Modules)
- UI Components (Radix UI, shadcn/ui)
Common Pitfalls
Avoid these frequent mistakes:
- Stale closures in useEffect
- Missing dependencies in dependency arrays
- Unnecessary useEffect for derived state
- Mutating state directly
- Using index as key in lists
See common-pitfalls.md for examples and solutions.
TypeScript Integration
Type your React components properly:
type ButtonProps = {
children: React.ReactNode;
variant?: 'primary' | 'secondary';
onClick?: () => void;
};
export function Button({ children, variant = 'primary', onClick }: ButtonProps) {
return <button className={variant}
}
See typescript-react.md for complete patterns including:
- Component typing
- Event handlers
- Hooks with TypeScript
- React Query types
- Utility types
Reference Files
Architecture & Organization:
- project-structure.md - Feature-based organization, imports, naming
- state-management.md - State categories, decision framework, patterns
Performance & Optimization:
- performance.md - Code splitting, virtualization, Web Vitals
- build-and-bundling.md - Vite config, bundle optimization
API & Data:
- api-layer.md - API client, request patterns, error handling
Testing & Quality:
- testing.md - Component tests, integration tests, E2E
- security.md - Auth, authorization, XSS/CSRF prevention
React 19 & Modern Features:
- react-19-best-practices.md - Compiler, Server Components, Actions
Tools & Ecosystem:
- ecosystem-tools.md - Recommended packages by category
- typescript-react.md - TypeScript patterns for React
Troubleshooting:
- common-pitfalls.md - Frequent mistakes and solutions
Configuration Templates
Pre-configured files for quick project setup:
- vite.config.ts - Optimized Vite configuration
- vitest.config.ts - Testing setup
- .eslintrc.react.json - React linting rules
Best Practices Summary
- Organize by feature - Keep related code together
- Choose state wisely - Use React Query for server data
- Optimize strategically - Profile before optimizing
- Test behavior - Test what users see and do
- Secure by default - HttpOnly cookies, sanitize input
- Type everything - Leverage TypeScript fully
- Stay modern - Adopt React 19 features
- Keep it simple - Avoid premature optimization
Build React applications that are fast, secure, and maintainable.
Converted and distributed by TomeVault — claim your Tome and manage your conversions.