Logo

A Battle-Tested Way to Structure React Projects

Learn how to structure your React projects with a focus on scalability, maintainability, and team collaboration.

Published: 03 Mar, 2025


In large-scale React projects, I structure components with a focus on scalability, maintainability, and team collaboration. Here’s my battle-tested approach:

Atomic Design + Feature-Based Hybrid Structure

src/
├── core/                 # Global system components
   ├── design-system/    # Atomic design implementation
   ├── atoms/
   ├── molecules/
   └── organisms/
   ├── providers/        # All context providers
   ├── hooks/            # Reusable custom hooks
   └── utils/            # Shared utilities

├── features/             # Feature-based modules
   ├── cart/
   ├── components/   # Feature-specific components
   ├── hooks/        # Feature-specific hooks
   ├── types/        # Feature-specific TS types
   └── index.ts      # Clean public API
   └── user-profile/

├── app/                  # Main app structure
   ├── layouts/          # Layout components
   └── routes/           # Route configuration

├── assets/               # Static assets
└── lib/                  # Third-party integrations/adapters

Component Categorization Strategy

  • Core Components: Reusable UI building blocks (Buttons, Inputs)
  • Domain Components: Business logic components (ProductCard, PaymentForm)
  • Container Components: State management + data fetching
  • Layout Components: Page structure providers
  • HOC Components: Cross-cutting concerns (auth, logging)

Strict Component Contracts

// ComponentName.tsx
interface ComponentNameProps {
  variant: "primary" | "secondary";
  children: React.ReactNode;
  /** @default false */
  disabled?: boolean;
}

export const ComponentName = ({
  variant = "primary",
  children,
  disabled = false,
}: ComponentNameProps) => {
  // Component implementation
};

State Management Hierarchy

  • Local State: useState/useReducer for UI state
  • Component Group State: Context API for medium-scoped state
  • Global State: Jotai for app-wide state
  • Server State: TanStack Query for async data

Performance Architecture

  • Code splitting at route level with React.lazy()
  • Memoization strategy:
    • React.memo for component memoization
    • useMemo for expensive calculations
    • useCallback for stable function references
  • Virtualization for large lists (react-virtual)

Testing Strategy

  • Unit Tests: Jest + Testing Library (75% coverage minimum)
  • Integration Tests: Playwright for critical user flows
  • Visual Tests: Chromatic/Storybook for UI consistency
  • E2E Tests: Cypress for key business journeys

Documentation System

  • Storybook for component documentation
  • TypeDoc for TypeScript type documentation
  • ADRs (Architectural Decision Records) for major decisions
  • CONTRIBUTING.md with component patterns and anti-patterns

Dependency Management

  • Internal component library package (@company/ui)
  • Dedicated API client layer
  • Strict dependency injection pattern:
// Instead of direct imports
import { api } from "core/http";

// Use dependency injection
const MyComponent = ({ httpClient }: { httpClient: HttpClient }) => {
  // Component implementation
};

Onboarding Infrastructure

  • Component playground environment
  • CLI scaffolding tool for new features
  • Visual regression testing dashboard
  • Interactive architecture diagram (Mermaid/FigJam)

Continuous Refactoring Process

  • Bi-weekly tech debt sprints
  • Automated code smell detection (SonarQube)
  • TypeScript strict mode enforcement
  • Deprecation policy for legacy components

Conclusion

This structure has proven effective across multiple enterprise React codebases (100k+ LOC). The key is maintaining strict boundaries between layers while allowing flexibility within feature modules. We enforce this architecture through:

ESLint import/export rules CI pipeline checks Monorepo strategy (when applicable) Automated dependency graph analysis

The goal is to create a system where developers can work in isolation on features while maintaining consistent patterns across the entire application.

I'm currently available for freelance work. If you know someone who would benefit from my expertise, please direct them to my work page, or email me their contact details.


Email me if you have any questions about this post.

Subscribe to the RSS feed to keep updated.