Skip to content
All articles
ReactArchitecture

How I Structure My React Projects in 2026

A pragmatic folder structure and set of patterns that have survived three companies and dozens of engineers.

5 March 20267 min read

Why Structure Matters More Than You Think

I've joined three codebases in five years. The single best predictor of how quickly I became productive was the project structure. A well-organized codebase communicates intent. A messy one requires tribal knowledge that lives in Slack threads and people's heads.

The structure I'm about to describe isn't revolutionary. It's boring, and that's the point. I want new engineers to open the project and immediately know where to find things and where to put new code.

The Folder Layout

I use a feature-based structure with a few shared top-level directories. The top-level folders are: app (routes and pages), components (shared UI components), features (feature-specific modules), hooks (shared custom hooks), lib (utilities and configurations), constants (static data and enums), and services (API client functions).

Inside each feature folder, I mirror the top-level structure: components, hooks, utils, and an index file that serves as the public API. Anything inside a feature folder is private to that feature unless explicitly exported through the index file.

This structure scales well from a solo project to a team of 15 engineers. At CARS24, we had 12 feature folders with clear ownership, and engineers rarely needed to touch code outside their feature boundary.

Component Organization

Shared components live in the top-level components directory and are organized by category: layout, forms, feedback, navigation, and data-display. Each component gets its own folder with the component file, a styles file if needed, and a test file.

I avoid creating deeply nested component hierarchies. If a component folder has more than three levels of nesting, it's a sign that the component is doing too much and should be split into separate components or extracted into a feature.

One pattern I've found invaluable is the compound component pattern for complex UI elements. Instead of a single Button component with 20 props, I create Button, ButtonGroup, ButtonIcon, and ButtonLabel components that compose together. It's more files but dramatically better DX.

The Barrel Export Debate

I used to love barrel exports — index.js files that re-export everything from a directory. Then I watched them cause webpack to bundle entire feature directories when only one component was imported. Tree-shaking is not as reliable as we'd like it to be.

My current approach: barrel exports for feature public APIs only. The feature's index.js explicitly exports the components, hooks, and utilities that other features are allowed to use. Imports within a feature use direct paths. This gives you a clean public API without the bundle size penalty.

Naming Conventions That Reduce Cognitive Load

Files are PascalCase for components and camelCase for everything else. Hooks always start with use. Utility functions are pure and named as verbs: formatPrice, parseDate, validateEmail. Constants are UPPER_SNAKE_CASE for primitive values and camelCase for objects and arrays.

I prefix test files with the same name as the file they test: CarCard.js and CarCard.test.js. Colocating tests with source files makes it obvious when a test is missing and makes refactoring easier because the test moves with the code.

These conventions sound trivial, but they eliminate an entire category of PR review comments and onboarding questions. When everyone names things the same way, the codebase reads like it was written by one person.

Found this useful? I write about engineering, performance, and career growth.