When I started building React applications, I didn’t think much about folder structure. I just created a components folder and dumped everything inside.
As the projects grew, I quickly realized this approach made it hard to maintain, scale, and onboard new developers. Searching for a single component felt like digging through a messy closet.
In this tutorial, I’ll share practical folder structure best practices for React components. I’ll also show you full working code examples so you can implement them immediately.
Method 1 – Flat Component Structure (For Small Apps)
When I build small apps (like a personal dashboard or a prototype), I prefer a flat structure. It keeps things simple and avoids over-engineering.
Here’s the structure:
src/
components/
Header.jsx
Footer.jsx
Button.jsx
Card.jsx
App.jsx
index.jsExample Code
components/Header.jsx
import React from "react";
export default function Header() {
return (
<header style={{ background: "#003366", color: "#fff", padding: "1rem" }}>
<h1>My Dashboard</h1>
</header>
);
}components/Footer.jsx
import React from "react";
export default function Footer() {
return (
<footer style={{ background: "#eee", padding: "1rem", textAlign: "center" }}>
<p>© 2025 My Company USA</p>
</footer>
);
}App.jsx
import React from "react";
import Header from "./components/Header";
import Footer from "./components/Footer";
export default function App() {
return (
<div>
<Header />
<main style={{ padding: "2rem" }}>
<h2>Welcome to My Dashboard</h2>
</main>
<Footer />
</div>
);
}You can see the output in the screenshot below.

This method works best for small projects where you don’t expect the codebase to grow beyond a handful of components.
Method 2 – Feature-Based Structure (For Medium Apps)
As soon as I started building medium-sized apps (like an internal HR tool), the flat structure became messy. That’s when I moved to a feature-based structure.
Here’s the structure:
src/
features/
employees/
components/
EmployeeList.jsx
EmployeeCard.jsx
hooks/
useEmployees.js
services/
employeeService.js
reports/
components/
ReportList.jsx
ReportCard.jsx
App.jsxExample Code
features/employees/components/EmployeeList.jsx
import React from "react";
import EmployeeCard from "./EmployeeCard";
import useEmployees from "../hooks/useEmployees";
export default function EmployeeList() {
const employees = useEmployees();
return (
<div>
<h2>Employees</h2>
{employees.map(emp => (
<EmployeeCard key={emp.id} employee={emp} />
))}
</div>
);
}features/employees/components/EmployeeCard.jsx
import React from "react";
export default function EmployeeCard({ employee }) {
return (
<div style={{ border: "1px solid #ccc", margin: "0.5rem", padding: "1rem" }}>
<h3>{employee.name}</h3>
<p>Position: {employee.position}</p>
</div>
);
}features/employees/hooks/useEmployees.js
import { useState, useEffect } from "react";
import { fetchEmployees } from "../services/employeeService";
export default function useEmployees() {
const [employees, setEmployees] = useState([]);
useEffect(() => {
fetchEmployees().then(data => setEmployees(data));
}, []);
return employees;
}features/employees/services/employeeService.js
export async function fetchEmployees() {
// Mock API call for USA employees
return Promise.resolve([
{ id: 1, name: "John Doe", position: "Manager" },
{ id: 2, name: "Jane Smith", position: "Developer" },
]);
}You can see the output in the screenshot below.

This method keeps all related files together (components, hooks, services). It’s much easier to maintain when you have multiple features.
Method 3 – Domain-Driven Structure (For Large Apps)
For enterprise-level apps (like healthcare portals or e-commerce platforms), I use a domain-driven structure. This scales well when you have multiple teams working on different parts of the app.
Here’s the structure:
src/
domains/
auth/
components/
LoginForm.jsx
RegisterForm.jsx
services/
authService.js
products/
components/
ProductList.jsx
ProductCard.jsx
services/
productService.js
hooks/
useProducts.js
cart/
components/
Cart.jsx
services/
cartService.js
shared/
components/
Button.jsx
Modal.jsx
hooks/
useFetch.js
App.jsxExample Code
domains/products/components/ProductList.jsx
import React from "react";
import ProductCard from "./ProductCard";
import useProducts from "../hooks/useProducts";
export default function ProductList() {
const products = useProducts();
return (
<div>
<h2>Products</h2>
<div style={{ display: "flex", gap: "1rem" }}>
{products.map(prod => (
<ProductCard key={prod.id} product={prod} />
))}
</div>
</div>
);
}domains/products/components/ProductCard.jsx
import React from "react";
export default function ProductCard({ product }) {
return (
<div style={{ border: "1px solid #ddd", padding: "1rem" }}>
<h3>{product.name}</h3>
<p>Price: ${product.price}</p>
</div>
);
}domains/products/hooks/useProducts.js
import { useEffect, useState } from "react";
import { fetchProducts } from "../services/productService";
export default function useProducts() {
const [products, setProducts] = useState([]);
useEffect(() => {
fetchProducts().then(data => setProducts(data));
}, []);
return products;
}domains/products/services/productService.js
export async function fetchProducts() {
// Mock API for a US-based store
return Promise.resolve([
{ id: 1, name: "Laptop", price: 1200 },
{ id: 2, name: "Smartphone", price: 800 },
]);
}You can see the output in the screenshot below.

This method is highly scalable. Each domain (auth, products, cart) is self-contained, making it easier for large teams to collaborate.
Method 4 – Hybrid Structure (My Favorite for Real Projects)
In reality, I often use a hybrid approach. Some parts of the app are feature-based, others are domain-driven, and I keep shared utilities separate.
Here’s the structure:
src/
features/
dashboard/
components/
Dashboard.jsx
domains/
users/
components/
UserList.jsx
services/
userService.js
shared/
components/
Loader.jsx
Button.jsx
hooks/
useAuth.js
App.jsxExample Code
features/dashboard/components/Dashboard.jsx
import React from "react";
import UserList from "../../domains/users/components/UserList";
export default function Dashboard() {
return (
<div>
<h2>Admin Dashboard</h2>
<UserList />
</div>
);
}domains/users/components/UserList.jsx
import React, { useEffect, useState } from "react";
import { fetchUsers } from "../services/userService";
export default function UserList() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetchUsers().then(data => setUsers(data));
}, []);
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name} ({user.role})</li>
))}
</ul>
);
}domains/users/services/userService.js
export async function fetchUsers() {
// Mock API with US-based roles
return Promise.resolve([
{ id: 1, name: "Alice Johnson", role: "Admin" },
{ id: 2, name: "Bob Williams", role: "Editor" },
]);
}This method gives me the flexibility to adapt the structure as the project grows.
Final Thoughts
Over the years, I’ve learned that there’s no single “perfect” folder structure for React components. The best choice depends on the size of your project, the team size, and how much you expect the app to grow.
- For small apps, keep it flat.
- For medium apps, use feature-based.
- For large apps, go domain-driven.
- For real-world projects, a hybrid approach is often the most practical.
If you adopt one of these structures from the start, you’ll save yourself countless hours of refactoring later. More importantly, your teammates will thank you for keeping the codebase clean and easy to navigate.
You may also read:
- Build a React Multi-Select Component
- Use componentDidMount in React Functional Components with useEffect
- React Pagination Component Examples
- Ways to Add a React Code Editor Component

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.