React Component Folder Structure Best Practices

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.js

Example 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.

React Component Folder Structure

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.jsx

Example 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.

React Component Folder Structure Best Practices

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.jsx

Example 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.

Folder Structure Best Practices React for Component

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.jsx

Example 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:

Leave a Comment

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.