A detailed exploration and comparison of the most effective and scalable folder structures for modern React applications. Choosing the right architecture is crucial for team velocity, maintainability, and long-term project health.
As a React application grows past a dozen components, the location of files directly impacts how quickly new features can be added and how easily bugs can be fixed.
A good folder structure helps development teams by:
-
Improving Discoverability: Quickly find where a specific piece of logic (a component, a hook, a service) resides.
-
Enforcing Consistency: Ensures all team members follow the same organisation pattern.
-
Enhancing Scalability: Allows the app to grow without becoming a tangled mess of imports.
-
Facilitating Refactoring: Makes it easier to safely move or delete features with minimal ripple effects.
We analyze three primary patterns used in the industry, detailing the pros and cons of each.
A component-based (type-based) folder structure in React organises files based on their type or role within the application, promoting modularity and reusability.
src/
βββ components/
β βββ Button/
β β βββ Button.tsx # The primary component file
β β βββ Button.css # Local styles (or .module.css, .scss)
β β βββ Button.test.tsx # Unit tests
β β βββ index.ts # Exporting the component (facade)
β β βββ types.ts # TypeScript interfaces/props
β βββ Card/
β β βββ Card.tsx
β β βββ Card.css
β β βββ index.ts
β β βββ types.ts
β βββ index.ts # Main export file for the *entire* library
β βββ shared-types.ts # Global types used across components
βββ hooks/ # Any reusable hooks
βββ utils/ # Any reusable utilities
βββ index.ts # Entry point for build tools (e.g., Webpack/Rollup)src/
βββ components/ // Reusable, generic components used throughout the application
β βββ Button/
β β βββ Button.jsx
β β βββ Button.module.css
β βββ Card/
β β βββ Card.jsx
β β βββ Card.module.css
β βββ ...
βββ layout/ // Components specifically for application layout
β βββ MainLayout/
β β βββ MainLayout.jsx
β β βββ MainLayout.module.css
β βββ Header/
β β βββ Header.jsx
β β βββ Header.module.css
β βββ Footer/
β β βββ Footer.jsx
β β βββ Footer.module.css
β βββ ...
βββ menu/ // Components specifically for navigation menus
β βββ MainMenu/
β β βββ MainMenu.jsx
β β βββ MainMenu.module.css
β βββ UserMenu/
β β βββ UserMenu.jsx
β β βββ UserMenu.module.css
β βββ ...
βββ pages/ // Top-level components representing distinct application pages/views
β βββ HomePage/
β β βββ HomePage.jsx
β β βββ HomePage.module.css
β βββ AboutPage/
β β βββ AboutPage.jsx
β β βββ AboutPage.module.css
β βββ ...
βββ hooks/ // Custom React hooks
β βββ useAuth.js
β βββ useDebounce.js
βββ utils/ // Utility functions
β βββ api.js
β βββ helpers.js
βββ assets/ // Static assets (images, fonts, etc.)
β βββ images/
β βββ fonts/
βββ App.jsx // Main application component
βββ index.js // Entry point of the application
βββ styles/ // Global styles or theme variables
βββ global.css
βββ variables.cssHouses small, independent, and reusable UI components that can be used across different parts of the application (e.g., Button, Card, Input)
Contains components responsible for the overall structure and arrangement of content on a page. This includes components like MainLayout (which might wrap the entire application content), Header, and Footer.
Represents distinct views or screens of the application. These components often compose other smaller components to form a complete page (e.g., HomePage, ProductPage).
Stores custom React hooks for encapsulating reusable logic.
The root component that defines routing and layout selection.
Entry point of the React application where the React root is created and the app is mounted.
-
Simple to Start: Easy for small projects and new developers to understand.
-
Clear Technical Separation: If you know you're looking for a component, you go to
components/.
-
Poor Scalability: As the app grows, the
components/folder can become a massive, unmanageable list of hundreds of files. -
Feature Dispersal: Files related to a single feature (e.g., "User Profile") are spread across multiple top-level folders (
components/ProfileButton,hooks/useProfileData,services/profileAPI).
This approach groups all files related to a specific feature or domain into one self-contained folder. This is the recommended modern approach for medium-to-large applications.
src/
βββ features/
β βββ Auth/
β β βββ components/
β β β βββ LoginForm.jsx
β β β βββ RegisterForm.jsx
β β βββ hooks/
β β β βββ useAuth.js
β β βββ pages/
β β βββ LoginPage.jsx
β βββ Dashboard/
β β βββ components/
β β β βββ Widget.jsx
β β βββ pages/
β β βββ DashboardPage.jsx
β βββ ... (other features)
βββ layouts/
β βββ MainLayout.jsx
β βββ AdminLayout.jsx
β βββ components/
β βββ Header.jsx
β βββ Sidebar.jsx
β βββ Footer.jsx
β βββ Menu.jsx
βββ shared/
β βββ components/
β β βββ Button.jsx
β β βββ Modal.jsx
β βββ hooks/
β β βββ useDebounce.js
β βββ utils/
β βββ helpers.js
βββ App.jsx
βββ index.jsContains isolated feature modules. Each module may include:
- Components
- Hooks
- Pages
- API logic
- Context or state management
Houses global layout components that define structural UI for different app sections.
- MainLayout.jsx β used for general/public sections
- AdminLayout.jsx β used for admin-only sections
- layouts/components/ β structural UI elements shared across layouts (Header, Sidebar, Menu, etc.)
Contains fully reusable, truly generic utilities and UI elements designed to be used anywhere in the app.
The root component that defines routing and layout selection.
Entry point of the React application where the React root is created and the app is mounted.
-
High Cohesion (Feature Concentration): Everything you need for a feature is in one folder. Deleting a feature often means just deleting one directory.
-
Reduced Scope Creep: Developers only need to worry about the files within their current feature directory.
-
Excellent Scalability: Adding a new feature simply means creating a new top-level folder under
features/.
-
Initial Overhead: Can feel overly complex for very small projects.
-
Defining "Shared" vs. "Feature-Specific": Sometimes tricky to decide if a component belongs in a feature's subfolder or the global
shared/componentsfolder.
Contributions are what make the open-source community an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
-
Fork the Project.
-
Create your Feature Branch (
git checkout -b feature/AmazingFeature). -
Commit your Changes (
git commit -m 'Add some AmazingFeature'). -
Push to the Branch (
git push origin feature/AmazingFeature). -
Open a Pull Request.
Distributed under the MIT License. See LICENSE for more information.