# Frontend Architecture Guide

## Frontend Architecture Checklist

- [ ] Component hierarchy follows atomic design ([Component Design Patterns](#component-design-patterns))
- [ ] Components have consistent, predictable APIs ([Component API Design](#component-api-design))
- [ ] State management follows locality principle ([State Management Strategy](#state-management-strategy))
- [ ] Server state handled separately from client state ([Server State Management](#server-state-management))
- [ ] Routes organized logically with code splitting ([Routing Architecture](#routing-architecture))
- [ ] Forms have proper validation and error handling ([Form Handling](#form-handling))
- [ ] Unnecessary re-renders minimized ([Rendering Optimization](#rendering-optimization))
- [ ] Bundle size optimized with tree shaking ([Bundle Optimization](#bundle-optimization))
- [ ] Images optimized and lazy loaded ([Image Optimization](#image-optimization))
- [ ] WCAG AA compliance achieved ([WCAG Compliance](#wcag-compliance))
- [ ] Keyboard navigation fully supported ([WCAG Compliance](#wcag-compliance))
- [ ] ARIA labels and roles properly used ([WCAG Compliance](#wcag-compliance))
- [ ] Responsive design works on all devices ([Responsive Design](#responsive-design))
- [ ] Performance metrics meet targets ([Performance Optimization](#performance-optimization))
- [ ] Error boundaries implemented ([Component Design Patterns](#component-design-patterns))
- [ ] Loading states handled gracefully ([State Management](#state-management))
- [ ] SEO meta tags configured ([Frontend Architecture Guide](#frontend-architecture-guide))
- [ ] Analytics tracking implemented ([Frontend Architecture Guide](#frontend-architecture-guide))
- [ ] Browser compatibility tested ([Performance Optimization](#performance-optimization))

## Core Philosophy

Build user interfaces that are fast by default, accessible to everyone, and maintainable for years. Optimize for change, not perfection. Every component should be predictable, every state transition should be intentional, and every render should be necessary.

## Component Design Patterns

### Component Hierarchy
Structure components from atomic to complex.

**Why:** A clear component hierarchy prevents duplication, ensures consistency, and makes components predictable. It creates a shared vocabulary between designers and developers.

```typescript
// Atomic Design Structure
components/
├── atoms/          // Single-purpose elements
│   ├── Button/
│   ├── Input/
│   └── Icon/
├── molecules/      // Simple combinations
│   ├── FormField/  // Label + Input + Error
│   ├── SearchBar/  // Icon + Input + Button
│   └── Card/
├── organisms/      // Complex UI sections
│   ├── Header/
│   ├── ProductGrid/
│   └── CheckoutForm/
├── templates/      // Page layouts
│   ├── AuthLayout/
│   └── DashboardLayout/
└── pages/          // Full pages with data
    ├── HomePage/
    └── ProfilePage/

// Component composition example
// Atom
export const Button = ({ children, variant, size, ...props }) => {
  return (
    <button
      className={cn(
        'btn',
        `btn--${variant}`,
        `btn--${size}`
      )}
      {...props}
    >
      {children}
    </button>
  );
};

// Molecule
export const FormField = ({ label, error, required, children }) => {
  return (
    <div className="form-field">
      <label className="form-field__label">
        {label}
        {required && <span className="form-field__required">*</span>}
      </label>
      {children}
      {error && <span className="form-field__error">{error}</span>}
    </div>
  );
};

// Organism
export const LoginForm = () => {
  const [errors, setErrors] = useState({});
  
  return (
    <form className="login-form">
      <FormField 
        label="Email" 
        error={errors.email}
        required
      >
        <Input type="email" name="email" />
      </FormField>
      
      <FormField 
        label="Password" 
        error={errors.password}
        required
      >
        <Input type="password" name="password" />
      </FormField>
      
      <Button variant="primary" size="large" type="submit">
        Sign In
      </Button>
    </form>
  );
};
```

### Component API Design
Design consistent, predictable component interfaces.

**Why:** Well-designed component APIs make components intuitive to use, reduce documentation needs, and prevent misuse. Consistency across components reduces cognitive load.

```typescript
// Component prop patterns
interface ButtonProps {
  // Required props first
  children: ReactNode;
  
  // Optional with defaults
  variant?: 'primary' | 'secondary' | 'danger';
  size?: 'small' | 'medium' | 'large';
  
  // Boolean flags
  disabled?: boolean;
  loading?: boolean;
  fullWidth?: boolean;
  
  // Event handlers
  onClick?: (event: MouseEvent<HTMLButtonElement>) => void;
  
  // Render props for flexibility
  icon?: ReactNode | ((isHovered: boolean) => ReactNode);
  
  // Composition props
  leftAddon?: ReactNode;
  rightAddon?: ReactNode;
  
  // HTML attributes spread
  className?: string;
  style?: CSSProperties;
  'data-testid'?: string;
}

// Compound component pattern
const Select = ({ children, value, onChange }) => {
  const [isOpen, setIsOpen] = useState(false);
  
  return (
    <SelectContext.Provider value={{ value, onChange, isOpen, setIsOpen }}>
      <div className="select">{children}</div>
    </SelectContext.Provider>
  );
};

Select.Trigger = ({ children }) => {
  const { isOpen, setIsOpen } = useSelectContext();
  
  return (
    <button onClick={() => setIsOpen(!isOpen)}>
      {children}
    </button>
  );
};

Select.Options = ({ children }) => {
  const { isOpen } = useSelectContext();
  
  if (!isOpen) return null;
  
  return <div className="select-options">{children}</div>;
};

Select.Option = ({ value, children }) => {
  const { onChange, setIsOpen } = useSelectContext();
  
  return (
    <button
      onClick={() => {
        onChange(value);
        setIsOpen(false);
      }}
    >
      {children}
    </button>
  );
};

// Usage
<Select value={selectedValue} onChange={setSelectedValue}>
  <Select.Trigger>{selectedValue || 'Choose...'}</Select.Trigger>
  <Select.Options>
    <Select.Option value="option1">Option 1</Select.Option>
    <Select.Option value="option2">Option 2</Select.Option>
  </Select.Options>
</Select>

// Polymorphic component pattern
type PolymorphicProps<E extends ElementType> = {
  as?: E;
  children?: ReactNode;
} & ComponentPropsWithoutRef<E>;

function Box<E extends ElementType = 'div'>({ 
  as, 
  ...props 
}: PolymorphicProps<E>) {
  const Component = as || 'div';
  return <Component {...props} />;
}

// Usage
<Box as="section" className="hero" />
<Box as="button" onClick={handleClick} />
```

### Component Composition Patterns
Build flexible components through composition.

**Why:** Composition over configuration creates more flexible, reusable components. It avoids prop explosion and makes components easier to understand and extend.

```typescript
// Slot pattern
interface LayoutProps {
  header?: ReactNode;
  sidebar?: ReactNode;
  footer?: ReactNode;
  children: ReactNode;
}

const Layout = ({ header, sidebar, footer, children }: LayoutProps) => {
  return (
    <div className="layout">
      {header && <header className="layout__header">{header}</header>}
      <div className="layout__body">
        {sidebar && <aside className="layout__sidebar">{sidebar}</aside>}
        <main className="layout__main">{children}</main>
      </div>
      {footer && <footer className="layout__footer">{footer}</footer>}
    </div>
  );
};

// Usage
<Layout
  header={<Header />}
  sidebar={<Navigation />}
  footer={<Footer />}
>
  <PageContent />
</Layout>

// Render prop pattern
interface DataFetcherProps<T> {
  url: string;
  children: (data: T | null, loading: boolean, error: Error | null) => ReactNode;
}

function DataFetcher<T>({ url, children }: DataFetcherProps<T>) {
  const { data, loading, error } = useFetch<T>(url);
  return <>{children(data, loading, error)}</>;
}

// Usage
<DataFetcher url="/api/user">
  {(user, loading, error) => {
    if (loading) return <Spinner />;
    if (error) return <ErrorMessage error={error} />;
    return <UserProfile user={user} />;
  }}
</DataFetcher>

// Higher-order component pattern
function withAuth<P extends object>(
  Component: ComponentType<P>
): ComponentType<P> {
  return (props: P) => {
    const { user, loading } = useAuth();
    
    if (loading) return <LoadingScreen />;
    if (!user) return <Navigate to="/login" />;
    
    return <Component {...props} user={user} />;
  };
}

// Usage
const ProtectedProfile = withAuth(ProfilePage);
```

## State Management

### State Management Strategy
Choose the right state solution for each use case.

**Why:** Different state has different requirements. Using the right tool for each type of state keeps complexity manageable and performance optimal.

```typescript
// State locality principle
// 1. Component state - for UI state
const [isOpen, setIsOpen] = useState(false);
const [searchTerm, setSearchTerm] = useState('');

// 2. Context - for prop drilling solutions
const ThemeContext = createContext<Theme>('light');

// 3. URL state - for shareable UI state
const [searchParams, setSearchParams] = useSearchParams();
const page = searchParams.get('page') || '1';

// 4. Global store - for app-wide state
const user = useAuthStore(state => state.user);
const cart = useCartStore(state => state.items);

// 5. Server state - for remote data
const { data, error, mutate } = useSWR('/api/posts', fetcher);

// State colocation hierarchy
const StateHierarchy = () => {
  // ❌ Bad: Everything in global state
  const { formData, isModalOpen, validationErrors } = useGlobalStore();
  
  // ✅ Good: State where it's needed
  // Global: user, cart, theme
  const user = useAuthStore(state => state.user);
  
  // URL: shareable filters
  const [searchParams] = useSearchParams();
  const category = searchParams.get('category');
  
  // Component: UI state
  const [isModalOpen, setIsModalOpen] = useState(false);
  
  // Form library: form state
  const { register, handleSubmit, errors } = useForm();
  
  return <div>...</div>;
};

// Zustand store pattern
interface AuthStore {
  user: User | null;
  token: string | null;
  login: (credentials: Credentials) => Promise<void>;
  logout: () => void;
  refreshToken: () => Promise<void>;
}

const useAuthStore = create<AuthStore>((set, get) => ({
  user: null,
  token: null,
  
  login: async (credentials) => {
    const response = await api.post('/auth/login', credentials);
    set({ 
      user: response.data.user,
      token: response.data.token 
    });
    localStorage.setItem('token', response.data.token);
  },
  
  logout: () => {
    set({ user: null, token: null });
    localStorage.removeItem('token');
  },
  
  refreshToken: async () => {
    const token = get().token;
    if (!token) throw new Error('No token');
    
    const response = await api.post('/auth/refresh', { token });
    set({ token: response.data.token });
  }
}));

// Optimistic updates pattern
const useOptimisticTodos = () => {
  const { data, mutate } = useSWR<Todo[]>('/api/todos', fetcher);
  
  const addTodo = async (newTodo: Partial<Todo>) => {
    const optimisticTodo = {
      ...newTodo,
      id: `temp-${Date.now()}`,
      completed: false
    };
    
    // Optimistically update UI
    await mutate(
      async (todos) => {
        const created = await api.post('/api/todos', newTodo);
        return todos?.map(t => 
          t.id === optimisticTodo.id ? created.data : t
        );
      },
      {
        optimisticData: [...(data || []), optimisticTodo],
        rollbackOnError: true,
        populateCache: true,
        revalidate: false
      }
    );
  };
  
  return { todos: data, addTodo };
};
```

### Server State Management
Handle server state as a separate concern.

**Why:** Server state has unique requirements: caching, synchronization, background refetching, and optimistic updates. Treating it separately from client state reduces complexity.

```typescript
// SWR configuration for server state
const swrConfig = {
  refreshInterval: 30000, // Poll every 30 seconds
  revalidateOnFocus: true,
  revalidateOnReconnect: true,
  dedupingInterval: 2000,
  errorRetryCount: 3,
  errorRetryInterval: 5000,
  shouldRetryOnError: (error) => {
    // Don't retry on 4xx errors
    return error.status >= 500;
  },
  onError: (error) => {
    if (error.status === 401) {
      // Token expired, redirect to login
      window.location.href = '/login';
    }
  }
};

// Data fetching patterns
// 1. Simple fetch with SWR
const useUser = (id: string) => {
  const { data, error, isLoading } = useSWR(
    `/api/users/${id}`,
    fetcher
  );
  
  return {
    user: data,
    isLoading,
    isError: error
  };
};

// 2. Dependent fetching
const useProjectWithTasks = (projectId: string) => {
  const { data: project } = useSWR(
    projectId ? `/api/projects/${projectId}` : null,
    fetcher
  );
  
  const { data: tasks } = useSWR(
    project ? `/api/projects/${projectId}/tasks` : null,
    fetcher
  );
  
  return { project, tasks };
};

// 3. Infinite loading
const useInfinitePosts = () => {
  const getKey = (pageIndex: number, previousPageData: any) => {
    if (previousPageData && !previousPageData.length) return null;
    return `/api/posts?page=${pageIndex}&limit=10`;
  };
  
  const { data, error, size, setSize, isValidating } = useSWRInfinite(
    getKey,
    fetcher
  );
  
  const posts = data ? data.flat() : [];
  const isLoadingMore = isValidating && size > 1;
  const isEmpty = data?.[0]?.length === 0;
  const isReachingEnd = isEmpty || (data && data[data.length - 1]?.length < 10);
  
  return {
    posts,
    loadMore: () => setSize(size + 1),
    isLoadingMore,
    isReachingEnd
  };
};

// 4. Mutations with optimistic updates
const useUpdateUser = () => {
  const { trigger, isMutating } = useSWRMutation(
    '/api/user',
    async (url, { arg }: { arg: Partial<User> }) => {
      return api.patch(url, arg);
    }
  );
  
  return {
    updateUser: trigger,
    isUpdating: isMutating
  };
};

// Cache invalidation strategies
const useCacheInvalidation = () => {
  const { mutate } = useSWRConfig();
  
  // Invalidate specific key
  const invalidateUser = (id: string) => {
    mutate(`/api/users/${id}`);
  };
  
  // Invalidate pattern
  const invalidateAllUsers = () => {
    mutate(key => typeof key === 'string' && key.startsWith('/api/users'));
  };
  
  // Global cache clear
  const clearCache = () => {
    mutate(() => true, undefined, { revalidate: false });
  };
  
  return { invalidateUser, invalidateAllUsers, clearCache };
};
```

## Routing Architecture

### Route Organization
Structure routes for scalability and clarity.

**Why:** Well-organized routes make navigation predictable, enable code splitting, and improve SEO. A clear routing structure helps users understand the application's information architecture.

```typescript
// Route configuration with React Router v6
const routes = [
  {
    path: '/',
    element: <RootLayout />,
    errorElement: <ErrorBoundary />,
    children: [
      {
        index: true,
        element: <HomePage />,
      },
      {
        path: 'auth',
        element: <AuthLayout />,
        children: [
          {
            path: 'login',
            element: <LoginPage />,
          },
          {
            path: 'register',
            element: <RegisterPage />,
          },
          {
            path: 'forgot-password',
            element: <ForgotPasswordPage />,
          },
        ],
      },
      {
        path: 'dashboard',
        element: <ProtectedRoute><DashboardLayout /></ProtectedRoute>,
        children: [
          {
            index: true,
            element: <DashboardHome />,
          },
          {
            path: 'projects',
            children: [
              {
                index: true,
                element: <ProjectsList />,
              },
              {
                path: ':projectId',
                element: <ProjectDetail />,
                loader: projectLoader,
              },
              {
                path: 'new',
                element: <CreateProject />,
              },
            ],
          },
        ],
      },
      {
        path: '*',
        element: <NotFoundPage />,
      },
    ],
  },
];

// Protected route implementation
const ProtectedRoute = ({ children }: { children: ReactNode }) => {
  const { user, loading } = useAuth();
  const location = useLocation();
  
  if (loading) {
    return <LoadingScreen />;
  }
  
  if (!user) {
    return <Navigate to="/auth/login" state={{ from: location }} replace />;
  }
  
  return <>{children}</>;
};

// Route-based code splitting
const HomePage = lazy(() => import('./pages/Home'));
const DashboardPage = lazy(() => import('./pages/Dashboard'));
const ProfilePage = lazy(() => import('./pages/Profile'));

// Nested route handling
const ProjectRoutes = () => {
  return (
    <Routes>
      <Route index element={<ProjectsList />} />
      <Route path=":id" element={<ProjectDetail />} />
      <Route path=":id/edit" element={<ProjectEdit />} />
      <Route path="new" element={<ProjectNew />} />
    </Routes>
  );
};

// Route guards and middleware
const RouteGuard = ({ 
  children, 
  requiredRole,
  requiredPermissions = [] 
}: RouteGuardProps) => {
  const { user, permissions } = useAuth();
  
  const hasRole = !requiredRole || user?.role === requiredRole;
  const hasPermissions = requiredPermissions.every(
    permission => permissions.includes(permission)
  );
  
  if (!hasRole || !hasPermissions) {
    return <AccessDenied />;
  }
  
  return <>{children}</>;
};

// Breadcrumb generation
const useBreadcrumbs = () => {
  const location = useLocation();
  const matches = useMatches();
  
  return matches
    .filter(match => match.handle?.breadcrumb)
    .map(match => ({
      path: match.pathname,
      label: match.handle.breadcrumb(match.data)
    }));
};
```

### Navigation Patterns
Implement consistent navigation throughout the app.

**Why:** Predictable navigation patterns reduce user cognitive load, improve accessibility, and make the application easier to learn and use.

```typescript
// Programmatic navigation
const useNavigation = () => {
  const navigate = useNavigate();
  const location = useLocation();
  
  const goBack = () => {
    if (window.history.length > 2) {
      navigate(-1);
    } else {
      navigate('/');
    }
  };
  
  const goToWithState = (to: string, state: any) => {
    navigate(to, { state });
  };
  
  const replaceWith = (to: string) => {
    navigate(to, { replace: true });
  };
  
  const goToWithReturnUrl = (to: string) => {
    navigate(to, { 
      state: { returnUrl: location.pathname } 
    });
  };
  
  return { goBack, goToWithState, replaceWith, goToWithReturnUrl };
};

// Tab navigation with URL sync
const TabNavigation = ({ tabs }: { tabs: Tab[] }) => {
  const [searchParams, setSearchParams] = useSearchParams();
  const activeTab = searchParams.get('tab') || tabs[0].id;
  
  const handleTabChange = (tabId: string) => {
    setSearchParams(prev => {
      prev.set('tab', tabId);
      return prev;
    });
  };
  
  return (
    <div>
      <nav className="tabs">
        {tabs.map(tab => (
          <button
            key={tab.id}
            onClick={() => handleTabChange(tab.id)}
            className={activeTab === tab.id ? 'active' : ''}
            aria-current={activeTab === tab.id ? 'page' : undefined}
          >
            {tab.label}
          </button>
        ))}
      </nav>
      <div className="tab-content">
        {tabs.find(t => t.id === activeTab)?.content}
      </div>
    </div>
  );
};

// Wizard/multi-step navigation
const useWizard = (steps: string[]) => {
  const [currentStep, setCurrentStep] = useState(0);
  const [history, setHistory] = useState<number[]>([0]);
  
  const canGoNext = currentStep < steps.length - 1;
  const canGoPrev = history.length > 1;
  
  const goToNext = () => {
    if (canGoNext) {
      setHistory([...history, currentStep + 1]);
      setCurrentStep(currentStep + 1);
    }
  };
  
  const goToPrev = () => {
    if (canGoPrev) {
      const newHistory = history.slice(0, -1);
      setHistory(newHistory);
      setCurrentStep(newHistory[newHistory.length - 1]);
    }
  };
  
  const goToStep = (step: number) => {
    if (step >= 0 && step < steps.length) {
      setHistory([...history, step]);
      setCurrentStep(step);
    }
  };
  
  return {
    currentStep,
    canGoNext,
    canGoPrev,
    goToNext,
    goToPrev,
    goToStep,
    progress: ((currentStep + 1) / steps.length) * 100
  };
};
```

## Form Handling

### Form Architecture
Build robust, accessible forms.

**Why:** Forms are critical user interaction points. Good form architecture reduces errors, improves completion rates, and provides better user experience through proper validation and feedback.

```typescript
// React Hook Form with Zod validation
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';

// Define schema
const userFormSchema = z.object({
  email: z
    .string()
    .min(1, 'Email is required')
    .email('Invalid email address'),
  name: z
    .string()
    .min(2, 'Name must be at least 2 characters')
    .max(50, 'Name must be less than 50 characters'),
  age: z
    .number()
    .min(18, 'Must be at least 18')
    .max(120, 'Invalid age'),
  password: z
    .string()
    .min(8, 'Password must be at least 8 characters')
    .regex(/[A-Z]/, 'Password must contain uppercase letter')
    .regex(/[a-z]/, 'Password must contain lowercase letter')
    .regex(/[0-9]/, 'Password must contain number'),
  confirmPassword: z.string()
}).refine((data) => data.password === data.confirmPassword, {
  message: "Passwords don't match",
  path: ['confirmPassword'],
});

type UserFormData = z.infer<typeof userFormSchema>;

// Form component
const UserForm = ({ onSubmit }: { onSubmit: (data: UserFormData) => void }) => {
  const {
    register,
    handleSubmit,
    formState: { errors, isSubmitting, dirtyFields, touchedFields },
    watch,
    setError,
    clearErrors,
    reset
  } = useForm<UserFormData>({
    resolver: zodResolver(userFormSchema),
    mode: 'onBlur', // Validate on blur
    defaultValues: {
      email: '',
      name: '',
      age: 18,
      password: '',
      confirmPassword: ''
    }
  });
  
  // Watch specific field
  const password = watch('password');
  
  // Custom submit handler with error handling
  const handleFormSubmit = async (data: UserFormData) => {
    try {
      await onSubmit(data);
      reset(); // Clear form on success
    } catch (error) {
      if (error.field) {
        setError(error.field, { 
          message: error.message 
        });
      } else {
        setError('root', { 
          message: 'Something went wrong' 
        });
      }
    }
  };
  
  return (
    <form onSubmit={handleSubmit(handleFormSubmit)} noValidate>
      <FormField
        label="Email"
        error={errors.email?.message}
        required
      >
        <input
          {...register('email')}
          type="email"
          aria-invalid={errors.email ? 'true' : 'false'}
          aria-describedby={errors.email ? 'email-error' : undefined}
        />
      </FormField>
      
      <FormField
        label="Password"
        error={errors.password?.message}
        required
      >
        <input
          {...register('password')}
          type="password"
          aria-invalid={errors.password ? 'true' : 'false'}
        />
        <PasswordStrength password={password} />
      </FormField>
      
      {errors.root && (
        <Alert variant="error">{errors.root.message}</Alert>
      )}
      
      <Button
        type="submit"
        disabled={isSubmitting}
        loading={isSubmitting}
      >
        {isSubmitting ? 'Submitting...' : 'Submit'}
      </Button>
    </form>
  );
};

// Controlled component pattern
const ControlledForm = () => {
  const [formData, setFormData] = useState({
    search: '',
    category: 'all',
    sortBy: 'relevance'
  });
  
  const handleInputChange = (
    e: ChangeEvent<HTMLInputElement | HTMLSelectElement>
  ) => {
    const { name, value, type } = e.target;
    
    setFormData(prev => ({
      ...prev,
      [name]: type === 'checkbox' ? e.target.checked : value
    }));
  };
  
  // Debounced search
  const debouncedSearch = useMemo(
    () => debounce((value: string) => {
      searchAPI(value);
    }, 300),
    []
  );
  
  useEffect(() => {
    if (formData.search) {
      debouncedSearch(formData.search);
    }
  }, [formData.search, debouncedSearch]);
  
  return (
    <form>
      <input
        name="search"
        value={formData.search}
        onChange={handleInputChange}
        placeholder="Search..."
      />
    </form>
  );
};

// Multi-step form
const MultiStepForm = () => {
  const [step, setStep] = useState(0);
  const [formData, setFormData] = useState<Partial<FormData>>({});
  
  const steps = [
    { component: PersonalInfoStep, validation: personalInfoSchema },
    { component: AddressStep, validation: addressSchema },
    { component: PaymentStep, validation: paymentSchema },
    { component: ReviewStep, validation: null }
  ];
  
  const CurrentStep = steps[step].component;
  
  const handleStepSubmit = async (stepData: any) => {
    const updatedData = { ...formData, ...stepData };
    setFormData(updatedData);
    
    if (step < steps.length - 1) {
      setStep(step + 1);
    } else {
      await submitForm(updatedData);
    }
  };
  
  return (
    <div>
      <ProgressIndicator current={step} total={steps.length} />
      <CurrentStep
        data={formData}
        onSubmit={handleStepSubmit}
        onBack={() => setStep(step - 1)}
      />
    </div>
  );
};
```

### Form Validation Patterns
Implement comprehensive validation strategies.

**Why:** Good validation prevents errors, guides users, and ensures data quality. Real-time validation provides immediate feedback while avoiding user frustration.

```typescript
// Field-level validation
const useFieldValidation = (name: string, value: any, rules: ValidationRule[]) => {
  const [error, setError] = useState<string | null>(null);
  const [validating, setValidating] = useState(false);
  
  const validate = useCallback(async () => {
    setValidating(true);
    
    try {
      for (const rule of rules) {
        const result = await rule.validate(value);
        if (!result.valid) {
          setError(result.message);
          setValidating(false);
          return false;
        }
      }
      
      setError(null);
      setValidating(false);
      return true;
    } catch (err) {
      setError('Validation failed');
      setValidating(false);
      return false;
    }
  }, [value, rules]);
  
  return { error, validating, validate };
};

// Async validation
const useAsyncValidation = () => {
  const checkEmailAvailability = useCallback(async (email: string) => {
    const response = await api.post('/api/check-email', { email });
    return response.data.available;
  }, []);
  
  const checkUsernameAvailability = useCallback(
    debounce(async (username: string) => {
      const response = await api.post('/api/check-username', { username });
      return response.data.available;
    }, 500),
    []
  );
  
  return { checkEmailAvailability, checkUsernameAvailability };
};

// Cross-field validation
const crossFieldValidation = {
  passwordMatch: (values: any) => {
    if (values.password !== values.confirmPassword) {
      return 'Passwords must match';
    }
  },
  
  dateRange: (values: any) => {
    if (new Date(values.startDate) > new Date(values.endDate)) {
      return 'End date must be after start date';
    }
  },
  
  conditionalRequired: (values: any) => {
    if (values.accountType === 'business' && !values.companyName) {
      return 'Company name is required for business accounts';
    }
  }
};

// Progressive validation
const useProgressiveValidation = (fields: Field[]) => {
  const [validationLevel, setValidationLevel] = useState<'basic' | 'full'>('basic');
  
  const validate = (value: any, field: Field) => {
    if (validationLevel === 'basic') {
      // Only check required and format
      return field.required && !value 
        ? 'This field is required' 
        : null;
    }
    
    // Full validation including async checks
    return field.validate(value);
  };
  
  const upgradeValidation = () => setValidationLevel('full');
  
  return { validate, upgradeValidation };
};
```

## Performance Optimization

### Rendering Optimization
Minimize unnecessary re-renders.

**Why:** Unnecessary re-renders waste CPU cycles, drain battery, and create janky user experiences. Optimizing rendering ensures smooth 60fps interactions even on low-end devices.

```typescript
// React.memo for component memoization
const ExpensiveComponent = React.memo(
  ({ data, onUpdate }: Props) => {
    console.log('Rendering ExpensiveComponent');
    return <ComplexVisualization data={data} onUpdate={onUpdate} />;
  },
  (prevProps, nextProps) => {
    // Custom comparison
    return (
      prevProps.data.id === nextProps.data.id &&
      prevProps.data.version === nextProps.data.version
    );
  }
);

// useMemo for expensive computations
const DataGrid = ({ rows, columns, filters }: DataGridProps) => {
  const filteredRows = useMemo(
    () => {
      console.log('Filtering rows');
      return rows.filter(row => 
        filters.every(filter => filter.match(row))
      );
    },
    [rows, filters] // Only recompute when these change
  );
  
  const sortedRows = useMemo(
    () => {
      console.log('Sorting rows');
      return [...filteredRows].sort((a, b) => 
        a.name.localeCompare(b.name)
      );
    },
    [filteredRows]
  );
  
  return <Grid data={sortedRows} columns={columns} />;
};

// useCallback for stable function references
const SearchInput = ({ onSearch }: { onSearch: (term: string) => void }) => {
  const [value, setValue] = useState('');
  
  // Without useCallback, this creates a new function every render
  const handleSearch = useCallback(
    debounce((term: string) => {
      onSearch(term);
    }, 300),
    [onSearch] // Only recreate if onSearch changes
  );
  
  useEffect(() => {
    handleSearch(value);
  }, [value, handleSearch]);
  
  return (
    <input 
      value={value}
      onChange={(e) => setValue(e.target.value)}
    />
  );
};

// Virtualization for large lists
import { VariableSizeList } from 'react-window';

const VirtualizedList = ({ items }: { items: Item[] }) => {
  const getItemSize = (index: number) => {
    // Variable heights based on content
    return items[index].type === 'header' ? 50 : 100;
  };
  
  const Row = ({ index, style }: RowProps) => (
    <div style={style}>
      <ItemComponent item={items[index]} />
    </div>
  );
  
  return (
    <VariableSizeList
      height={600}
      itemCount={items.length}
      itemSize={getItemSize}
      width="100%"
      overscanCount={5} // Render 5 items outside viewport
    >
      {Row}
    </VariableSizeList>
  );
};

// Code splitting at route level
const routes = [
  {
    path: '/dashboard',
    component: lazy(() => import('./pages/Dashboard'))
  },
  {
    path: '/analytics',
    component: lazy(() => 
      import('./pages/Analytics').then(module => ({
        default: module.Analytics
      }))
    )
  }
];

// Component-level code splitting
const HeavyComponent = lazy(() => import('./HeavyComponent'));

const App = () => {
  const [showHeavy, setShowHeavy] = useState(false);
  
  return (
    <div>
      <button onClick={() => setShowHeavy(true)}>
        Load Heavy Component
      </button>
      
      {showHeavy && (
        <Suspense fallback={<Spinner />}>
          <HeavyComponent />
        </Suspense>
      )}
    </div>
  );
};
```

### Bundle Optimization
Reduce JavaScript bundle size.

**Why:** Smaller bundles mean faster downloads, quicker parsing, and better performance on mobile networks. Every KB matters for user experience and SEO.

```typescript
// Dynamic imports for conditional features
const loadAdvancedFeatures = async () => {
  const { 
    AdvancedEditor,
    AdvancedAnalytics,
    AdvancedVisualization 
  } = await import('./advanced-features');
  
  return { AdvancedEditor, AdvancedAnalytics, AdvancedVisualization };
};

// Tree-shakeable exports
// ❌ Bad: Barrel exports that import everything
export * from './components'; // Imports all components

// ✅ Good: Named exports that can be tree-shaken
export { Button } from './components/Button';
export { Input } from './components/Input';
export type { ButtonProps } from './components/Button';

// Webpack config for optimization
module.exports = {
  optimization: {
    usedExports: true, // Tree shaking
    sideEffects: false, // Mark as side-effect free
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          priority: 10,
        },
        common: {
          minChunks: 2,
          priority: 5,
          reuseExistingChunk: true,
        },
      },
    },
  },
};

// Package.json sideEffects configuration
{
  "sideEffects": [
    "*.css",
    "*.scss",
    "./src/polyfills.js"
  ]
}

// Lazy load heavy libraries
const loadChartLibrary = () => import('chart.js');
const loadDateLibrary = () => import('date-fns');
const loadAnimationLibrary = () => import('framer-motion');

// Use dynamic imports with React
const ChartComponent = () => {
  const [Chart, setChart] = useState(null);
  
  useEffect(() => {
    loadChartLibrary().then(module => {
      setChart(() => module.default);
    });
  }, []);
  
  if (!Chart) return <ChartSkeleton />;
  
  return <Chart {...props} />;
};
```

### Image Optimization
Optimize image loading and rendering.

**Why:** Images are often the heaviest assets on a page. Proper optimization reduces bandwidth usage, improves loading times, and provides better user experience across different devices and network conditions.

```typescript
// Responsive image component
interface ResponsiveImageProps {
  src: string;
  alt: string;
  sizes?: string;
  loading?: 'lazy' | 'eager';
  priority?: boolean;
}

const ResponsiveImage = ({ 
  src, 
  alt, 
  sizes = '100vw',
  loading = 'lazy',
  priority = false
}: ResponsiveImageProps) => {
  const imageUrl = (width: number, format?: string) => {
    const params = new URLSearchParams({
      w: width.toString(),
      q: '75',
      ...(format && { fm: format })
    });
    return `${src}?${params}`;
  };
  
  return (
    <picture>
      <source
        type="image/avif"
        srcSet={`
          ${imageUrl(640, 'avif')} 640w,
          ${imageUrl(750, 'avif')} 750w,
          ${imageUrl(1080, 'avif')} 1080w,
          ${imageUrl(1200, 'avif')} 1200w,
          ${imageUrl(1920, 'avif')} 1920w
        `}
        sizes={sizes}
      />
      <source
        type="image/webp"
        srcSet={`
          ${imageUrl(640, 'webp')} 640w,
          ${imageUrl(750, 'webp')} 750w,
          ${imageUrl(1080, 'webp')} 1080w,
          ${imageUrl(1200, 'webp')} 1200w,
          ${imageUrl(1920, 'webp')} 1920w
        `}
        sizes={sizes}
      />
      <img
        src={imageUrl(1200)}
        alt={alt}
        loading={priority ? 'eager' : loading}
        decoding="async"
        srcSet={`
          ${imageUrl(640)} 640w,
          ${imageUrl(750)} 750w,
          ${imageUrl(1080)} 1080w,
          ${imageUrl(1200)} 1200w,
          ${imageUrl(1920)} 1920w
        `}
        sizes={sizes}
      />
    </picture>
  );
};

// Progressive image loading
const ProgressiveImage = ({ src, placeholder, alt }: ProgressiveImageProps) => {
  const [imageSrc, setImageSrc] = useState(placeholder);
  const [imageRef, setImageRef] = useState<HTMLImageElement>();
  const [isLoaded, setIsLoaded] = useState(false);
  
  useEffect(() => {
    const img = new Image();
    img.src = src;
    img.onload = () => {
      setImageSrc(src);
      setIsLoaded(true);
    };
    setImageRef(img);
  }, [src]);
  
  return (
    <div className={cn('progressive-image', { loaded: isLoaded })}>
      <img
        src={imageSrc}
        alt={alt}
        style={{
          filter: isLoaded ? 'none' : 'blur(20px)',
          transition: 'filter 0.3s ease-out'
        }}
      />
    </div>
  );
};

// Intersection Observer for lazy loading
const useLazyLoad = (ref: RefObject<HTMLElement>, rootMargin = '200px') => {
  const [isIntersecting, setIsIntersecting] = useState(false);
  
  useEffect(() => {
    const element = ref.current;
    if (!element) return;
    
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setIsIntersecting(true);
          observer.disconnect();
        }
      },
      { rootMargin }
    );
    
    observer.observe(element);
    
    return () => observer.disconnect();
  }, [ref, rootMargin]);
  
  return isIntersecting;
};

const LazyImage = ({ src, alt, placeholder }: LazyImageProps) => {
  const ref = useRef<HTMLDivElement>(null);
  const isVisible = useLazyLoad(ref);
  
  return (
    <div ref={ref}>
      {isVisible ? (
        <img src={src} alt={alt} />
      ) : (
        <div className="placeholder" style={{ background: placeholder }} />
      )}
    </div>
  );
};
```

## Accessibility Standards

### WCAG Compliance
Meet Web Content Accessibility Guidelines.

**Why:** Accessibility ensures your application is usable by everyone, including people with disabilities. It's not just ethical and often legally required - it also improves usability for all users.

```typescript
// Semantic HTML structure
const ArticleCard = ({ article }: { article: Article }) => {
  return (
    <article aria-labelledby={`article-${article.id}`}>
      <header>
        <h2 id={`article-${article.id}`}>{article.title}</h2>
        <time dateTime={article.publishedAt}>
          {formatDate(article.publishedAt)}
        </time>
      </header>
      
      <section>{article.summary}</section>
      
      <footer>
        <address>
          By <a href={`/authors/${article.author.id}`} rel="author">
            {article.author.name}
          </a>
        </address>
      </footer>
    </article>
  );
};

// Keyboard navigation
const useKeyboardNavigation = (items: any[], onSelect: (item: any) => void) => {
  const [focusedIndex, setFocusedIndex] = useState(0);
  
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      switch (e.key) {
        case 'ArrowDown':
          e.preventDefault();
          setFocusedIndex((prev) => 
            Math.min(prev + 1, items.length - 1)
          );
          break;
        case 'ArrowUp':
          e.preventDefault();
          setFocusedIndex((prev) => Math.max(prev - 1, 0));
          break;
        case 'Enter':
        case ' ':
          e.preventDefault();
          onSelect(items[focusedIndex]);
          break;
        case 'Home':
          e.preventDefault();
          setFocusedIndex(0);
          break;
        case 'End':
          e.preventDefault();
          setFocusedIndex(items.length - 1);
          break;
      }
    };
    
    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [items, focusedIndex, onSelect]);
  
  return { focusedIndex, setFocusedIndex };
};

// ARIA labels and roles
const Modal = ({ isOpen, onClose, title, children }: ModalProps) => {
  const titleId = useId();
  const descId = useId();
  
  useEffect(() => {
    if (isOpen) {
      // Trap focus in modal
      const previouslyFocused = document.activeElement as HTMLElement;
      const modal = document.getElementById('modal');
      modal?.focus();
      
      return () => {
        previouslyFocused?.focus();
      };
    }
  }, [isOpen]);
  
  if (!isOpen) return null;
  
  return (
    <div
      role="dialog"
      aria-modal="true"
      aria-labelledby={titleId}
      aria-describedby={descId}
      id="modal"
      tabIndex={-1}
    >
      <div className="modal-overlay" onClick={onClose} aria-hidden="true" />
      <div className="modal-content">
        <h2 id={titleId}>{title}</h2>
        <div id={descId}>{children}</div>
        <button
          onClick={onClose}
          aria-label="Close dialog"
        >
          <span aria-hidden="true">×</span>
        </button>
      </div>
    </div>
  );
};

// Screen reader announcements
const useAnnounce = () => {
  const [announcement, setAnnouncement] = useState('');
  
  const announce = (message: string, priority: 'polite' | 'assertive' = 'polite') => {
    setAnnouncement('');
    setTimeout(() => {
      setAnnouncement(message);
    }, 100);
  };
  
  return {
    announcement,
    announce,
    Announcer: () => (
      <div
        role="status"
        aria-live="polite"
        aria-atomic="true"
        className="sr-only"
      >
        {announcement}
      </div>
    )
  };
};

// Focus management
const FocusTrap = ({ children, active }: FocusTrapProps) => {
  const trapRef = useRef<HTMLDivElement>(null);
  
  useEffect(() => {
    if (!active) return;
    
    const element = trapRef.current;
    if (!element) return;
    
    const focusableElements = element.querySelectorAll(
      'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
    );
    
    const firstElement = focusableElements[0] as HTMLElement;
    const lastElement = focusableElements[focusableElements.length - 1] as HTMLElement;
    
    const handleTabKey = (e: KeyboardEvent) => {
      if (e.key !== 'Tab') return;
      
      if (e.shiftKey) {
        if (document.activeElement === firstElement) {
          e.preventDefault();
          lastElement.focus();
        }
      } else {
        if (document.activeElement === lastElement) {
          e.preventDefault();
          firstElement.focus();
        }
      }
    };
    
    element.addEventListener('keydown', handleTabKey);
    firstElement?.focus();
    
    return () => {
      element.removeEventListener('keydown', handleTabKey);
    };
  }, [active]);
  
  return <div ref={trapRef}>{children}</div>;
};
```

## Responsive Design

### Breakpoint Strategy
Design for all screen sizes.

**Why:** Users access applications from diverse devices. A solid breakpoint strategy ensures consistent experiences across all screen sizes while maintaining design integrity.

```typescript
// Breakpoint configuration
const breakpoints = {
  xs: 320,
  sm: 640,
  md: 768,
  lg: 1024,
  xl: 1280,
  '2xl': 1536,
} as const;

// Media query hooks
const useMediaQuery = (query: string): boolean => {
  const [matches, setMatches] = useState(false);
  
  useEffect(() => {
    const media = window.matchMedia(query);
    
    if (media.matches !== matches) {
      setMatches(media.matches);
    }
    
    const listener = (e: MediaQueryListEvent) => setMatches(e.matches);
    media.addEventListener('change', listener);
    
    return () => media.removeEventListener('change', listener);
  }, [matches, query]);
  
  return matches;
};

const useBreakpoint = () => {
  const isXs = useMediaQuery(`(min-width: ${breakpoints.xs}px)`);
  const isSm = useMediaQuery(`(min-width: ${breakpoints.sm}px)`);
  const isMd = useMediaQuery(`(min-width: ${breakpoints.md}px)`);
  const isLg = useMediaQuery(`(min-width: ${breakpoints.lg}px)`);
  const isXl = useMediaQuery(`(min-width: ${breakpoints.xl}px)`);
  const is2xl = useMediaQuery(`(min-width: ${breakpoints['2xl']}px)`);
  
  return { isXs, isSm, isMd, isLg, isXl, is2xl };
};

// Responsive component variants
const ResponsiveGrid = ({ children }: { children: ReactNode }) => {
  const { isMd, isLg } = useBreakpoint();
  
  const columns = isLg ? 4 : isMd ? 3 : 2;
  
  return (
    <div
      className="grid"
      style={{
        gridTemplateColumns: `repeat(${columns}, 1fr)`,
        gap: isLg ? '2rem' : isMd ? '1.5rem' : '1rem'
      }}
    >
      {children}
    </div>
  );
};

// Container queries for component-level responsiveness
const CardContainer = styled.div`
  container-type: inline-size;
  
  .card {
    display: grid;
    gap: 1rem;
  }
  
  @container (min-width: 400px) {
    .card {
      grid-template-columns: auto 1fr;
    }
  }
  
  @container (min-width: 600px) {
    .card {
      grid-template-columns: 200px 1fr auto;
    }
  }
`;

// Responsive typography
const useResponsiveTypography = () => {
  const { isMd, isLg } = useBreakpoint();
  
  return {
    h1: isLg ? '3rem' : isMd ? '2.5rem' : '2rem',
    h2: isLg ? '2.5rem' : isMd ? '2rem' : '1.75rem',
    h3: isLg ? '2rem' : isMd ? '1.75rem' : '1.5rem',
    body: isLg ? '1.125rem' : '1rem',
    small: isLg ? '0.875rem' : '0.75rem',
  };
};
```

