React’s rise as the premier JavaScript library for building user interfaces is no accident. Its component-driven design promotes reusability, maintainability, and scalability. However, as projects grow, organizing your React codebase becomes crucial to maintain productivity and clarity.
At Skye8, we adopt a clear, scalable folder structure and best practices that empower our teams to rapidly deliver high-quality web applications. In this article, I will guide you through how to structure React projects for success, complemented by code examples and explanations.
1. Why Folder Structure Matters in React Projects
A well-designed folder structure:
-
Simplifies navigation and onboarding.
-
Encourages separation of concerns.
-
Supports scalability as your app grows.
-
Facilitates collaboration across frontend teams.
Poorly organized codebases often lead to technical debt and slowed development cycles.
2. Recommended Folder Structure Overview
Here is a scalable folder structure pattern we use at Skye8 for React applications:
src/
├── assets/ # Images, fonts, stylesheets, icons
├── components/ # Reusable UI components
│ ├── Button/
│ │ ├── Button.jsx
│ │ ├── Button.test.jsx
│ │ └── Button.css
│ ├── Modal/
│ └── ...
├── features/ # Domain-specific feature modules (page-level or complex features)
│ ├── UserProfile/
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── UserProfile.jsx
│ │ └── userProfileSlice.js
│ └── ...
├── hooks/ # Reusable custom React hooks
├── layouts/ # Layout components (e.g., DashboardLayout, AuthLayout)
├── pages/ # Page-level components routed by React Router
│ ├── Home.jsx
│ ├── Login.jsx
│ └── NotFound.jsx
├── services/ # API calls and data fetching logic
│ └── apiClient.js
├── store/ # Redux or state management logic
│ ├── index.js
│ └── userSlice.js
├── utils/ # Utility functions and helpers
├── App.jsx # Root React component
├── index.js # Entry point rendering <App />
└── setupTests.js # Test setup configuration
3. Folder Structure Explained
a) assets/
Contains all static files such as images, icons, fonts, and global styles. Keeping these separate avoids cluttering component folders and eases asset management.
b) components/
Houses reusable UI components that are generic enough to be used in multiple features or pages — for example, buttons, modals, inputs.
Each component gets its own folder with:
-
The main JSX file
-
Associated styles (CSS or styled-components)
-
Unit tests
This approach encapsulates component code and related files, easing maintenance.
c) features/
This is a crucial folder containing feature modules — a pattern inspired by “feature-based” organization. Each feature folder groups components, hooks, and state logic relevant only to that feature.
For example, UserProfile/ contains UI subcomponents, feature-specific hooks, and Redux slice files. This enables:
-
Clear domain boundaries
-
Easier scalability
-
Isolated testing and development
d) hooks/
Reusable custom React hooks used across the application, such as form handlers, debounced effects, or API hooks.
// Example: useDebounce.js
import { useEffect, useState } from 'react';
export function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => setDebouncedValue(value), delay);
return () => clearTimeout(handler);
}, [value, delay]);
return debouncedValue;
}
e) layouts/
Layouts define the structural frame for pages (e.g., navigation bars, footers, sidebars). They wrap page components to enforce consistent UI patterns.
// Example: DashboardLayout.jsx
export default function DashboardLayout({ children }) {
return (
<div>
<Sidebar />
<main>{children}</main>
</div>
);
}
f) pages/
Top-level components corresponding to routes. They compose features and components to form complete views.
g) services/
Handles external communications — API clients, request interceptors, WebSocket connections, etc.
// apiClient.js example using Axios
import axios from 'axios';
const apiClient = axios.create({
baseURL: process.env.REACT_APP_API_URL,
timeout: 10000,
});
export default apiClient;
h) store/
Contains Redux slices or other global state logic. Using Redux Toolkit is encouraged for concise, scalable state management.
i) utils/
Utility functions like formatters, validators, or generic helpers shared across the app.
4. Example Component With Folder Structure
Consider a reusable button:
src/components/Button/
├── Button.jsx
├── Button.css
└── Button.test.jsx
Button.jsx
import React from 'react';
import './Button.css';
export default function Button({ label, onClick, disabled }) {
return (
<button className="btn" onClick={onClick} disabled={disabled}>
{label}
</button>
);
}
5. Benefits of This Structure
-
Scalability: Adding new features requires creating isolated folders, minimizing merge conflicts.
-
Clarity: Developers quickly find relevant code with domain-centric organization.
-
Maintainability: Encapsulated components and features ease refactoring and testing.
-
Team Collaboration: Clear boundaries support parallel development by multiple engineers.
The way you organize your React codebase has profound effects on your team’s productivity and product quality. At Skye8, adopting a feature-based folder structure combined with component encapsulation has empowered our developers to build scalable and maintainable applications that grow with business needs.
For your next React project, invest time upfront to define a clear folder structure. Your future self—and your team—will thank you.
Comments (0)
Leave a Comment
Be the first to comment on this article!