A well-organized project structure is crucial for code maintainability, easy navigation, and scalability of React applications. In this module, we'll look at best practices for structuring React projects and understand how to organize files and components.
Regardless of whether you use Create React App, Vite, or another tool, the basic structure of a React project usually looks similar:
1my-react-project/
2βββ node_modules/ # Installed dependencies
3βββ public/ # Publicly accessible static files
4βββ src/ # Application source code
5β βββ components/ # Reusable components
6β βββ pages/ # Components representing entire pages
7β βββ assets/ # Assets such as images, fonts, etc.
8β βββ utils/ # Utility functions
9β βββ services/ # Code responsible for API communication
10β βββ hooks/ # Custom React hooks
11β βββ context/ # React contexts
12β βββ App.js # Main application component
13β βββ index.js # Application entry point
14βββ .gitignore # Files ignored by Git
15βββ package.json # Project info and dependencies
16βββ README.md # Project documentationLet's discuss the most important directories and their purposes:
The
src/ directory is the heart of your React application. It contains all the logic, components, and assets. Here's how this directory is typically organized:Contains reusable components that are used in various parts of the application. There are several approaches to structuring components:
1components/
2βββ Button.jsx
3βββ Button.css
4βββ Header.jsx
5βββ Header.css
6βββ Footer.jsx
7βββ Footer.css1components/
2βββ Button/
3β βββ Button.jsx
4β βββ Button.css
5β βββ index.js
6βββ Header/
7β βββ Header.jsx
8β βββ Header.css
9β βββ index.js
10βββ Footer/
11 βββ Footer.jsx
12 βββ Footer.css
13 βββ index.jsUsing
index.js files to export components simplifies imports:1// Instead of:
2import Button from './components/Button/Button';
3
4// You can write:
5import Button from './components/Button';Components representing entire pages or views in the application. In projects with routing, each file in this directory typically corresponds to a specific URL path:
1pages/
2βββ Home/
3β βββ Home.jsx
4β βββ Home.css
5βββ About/
6β βββ About.jsx
7β βββ About.css
8βββ Dashboard/
9 βββ Dashboard.jsx
10 βββ Dashboard.cssContains all static assets used in the application:
1assets/
2βββ images/
3β βββ logo.png
4β βββ background.jpg
5βββ fonts/
6β βββ roboto.ttf
7β βββ open-sans.ttf
8βββ styles/
9 βββ variables.css
10 βββ global.cssUtility functions and tools used throughout the application:
1utils/
2βββ formatDate.js
3βββ validation.js
4βββ helpers.jsCode responsible for communicating with external APIs or services:
1services/
2βββ api.js # Basic API configuration
3βββ userService.js # User-related queries
4βββ productService.js # Product-related queriesCustom React hooks that can be used in multiple places in the application:
1hooks/
2βββ useLocalStorage.js
3βββ useFetch.js
4βββ useForm.jsReact contexts used for managing global state:
1context/
2βββ AuthContext.js
3βββ ThemeContext.js
4βββ CartContext.jsThere are two main approaches to code organization:
Files are grouped by their type (components, hooks, services, etc.).
Files are grouped by feature or part of the application:
1src/
2βββ auth/
3β βββ components/
4β βββ hooks/
5β βββ services/
6β βββ context/
7βββ products/
8β βββ components/
9β βββ hooks/
10β βββ services/
11β βββ utils/
12βββ checkout/
13 βββ components/
14 βββ hooks/
15 βββ services/This structure is more scalable for large projects, especially when multiple people are working on them.
Consistent naming is just as important as directory structure:
Button.jsx, UserProfile.jsx.jsx extension (not required, but helps with identification)useLocalStorage.js, useWindowSize.jsAuthContext.js, ThemeContext.jsapiService.js, formatDate.jsThere are several approaches to organizing styles in React:
1Button/
2βββ Button.jsx
3βββ Button.module.css1Button/
2βββ Button.jsx # Contains styled-components definitions1Button/
2βββ Button.jsx
3βββ Button.scssIn the React cosmic fleet, a well-organized folder structure is like an efficient logistics system on a spaceship - everything has its place and you can quickly find what you need. Here are proven practices for organizing React projects.
Two main approaches to organizing code in React projects:
Files grouped by their technical role - all components together, all hooks together, etc.
1src/
2βββ components/
3β βββ Button/
4β βββ Card/
5β βββ Modal/
6β βββ UserProfile/
7β βββ ProductCard/
8β βββ ShoppingCart/
9βββ hooks/
10β βββ useAuth.js
11β βββ useProducts.js
12β βββ useCart.js
13βββ services/
14β βββ authService.js
15β βββ productService.js
16β βββ cartService.js
17βββ utils/
18 βββ validators.js
19 βββ formatters.jsAdvantages:
Disadvantages:
Files grouped by business feature - all files related to authentication together, all product-related files together, etc.
1src/
2βββ features/
3β βββ auth/
4β β βββ components/
5β β β βββ LoginForm/
6β β β βββ RegisterForm/
7β β β βββ PasswordReset/
8β β βββ hooks/
9β β β βββ useAuth.js
10β β β βββ useSession.js
11β β βββ services/
12β β β βββ authService.js
13β β βββ utils/
14β β β βββ validators.js
15β β βββ index.js
16β β
17β βββ products/
18β β βββ components/
19β β β βββ ProductList/
20β β β βββ ProductCard/
21β β β βββ ProductDetails/
22β β βββ hooks/
23β β β βββ useProducts.js
24β β β βββ useProductFilters.js
25β β βββ services/
26β β β βββ productService.js
27β β βββ index.js
28β β
29β βββ cart/
30β βββ components/
31β β βββ ShoppingCart/
32β β βββ CartItem/
33β β βββ Checkout/
34β βββ hooks/
35β β βββ useCart.js
36β βββ services/
37β β βββ cartService.js
38β βββ index.js
39β
40βββ shared/
41β βββ components/
42β β βββ Button/
43β β βββ Modal/
44β β βββ Card/
45β βββ hooks/
46β β βββ useLocalStorage.js
47β β βββ useDebounce.js
48β βββ utils/
49β βββ formatDate.js
50β βββ formatCurrency.js
51β
52βββ App.jsxAdvantages:
Disadvantages:
Consistent naming is a key element of a well-organized project. In React, the following conventions apply:
1// GOOD - PascalCase
2Button.jsx
3UserProfile.jsx
4ShoppingCart.jsx
5ProductCard.jsx
6
7// BAD - other conventions
8button.jsx
9user-profile.jsx
10shopping_cart.jsxWhy PascalCase?
1// GOOD - camelCase with "use"
2useAuth.js
3useLocalStorage.js
4useWindowSize.js
5useProductFilters.js
6
7// BAD - missing "use" or wrong convention
8Auth.js
9local-storage.js
10WindowSize.jsWhy "use" prefix?
1// GOOD - PascalCase with "Context"
2AuthContext.js
3ThemeContext.js
4CartContext.js
5UserPreferencesContext.js
6
7// BAD - missing "Context" or wrong convention
8auth.js
9theme-context.js
10Cart.js1// GOOD - camelCase
2formatDate.js
3validateEmail.js
4apiService.js
5authService.js
6
7// BAD - other conventions
8FormatDate.js
9validate-email.js
10API_Service.jsPlanning file locations in a project has enormous significance for its readability and scalability.
Feature-based approach:
1features/
2βββ auth/
3β βββ hooks/
4β βββ useAuth.js
5β βββ useSession.js
6βββ products/
7 βββ hooks/
8 βββ useProducts.js
9
10shared/
11βββ hooks/
12 βββ useLocalStorage.js # Shared hook
13 βββ useDebounce.js # Shared hook
14 βββ useFetch.js # Shared hookType-based approach:
1hooks/
2βββ useAuth.js
3βββ useSession.js
4βββ useProducts.js
5βββ useLocalStorage.js
6βββ useDebounce.js
7βββ useFetch.jsFeature-based approach:
1features/
2βββ products/
3β βββ utils/
4β βββ formatPrice.js
5β βββ filterProducts.js
6βββ auth/
7 βββ utils/
8 βββ validatePassword.js
9
10shared/
11βββ utils/
12 βββ formatDate.js # Shared
13 βββ debounce.js # Shared
14 βββ cloneDeep.js # SharedType-based approach:
1utils/
2βββ formatPrice.js
3βββ formatDate.js
4βββ validatePassword.js
5βββ filterProducts.js
6βββ debounce.js
7βββ cloneDeep.jsIf you use TypeScript, you have several options for types:
Option 1: Next to the files that use them:
1components/
2βββ Button/
3 βββ Button.tsx
4 βββ Button.types.ts # Types only for Button
5 βββ Button.styles.ts
6 βββ index.tsOption 2: Centralized types:
1types/
2βββ user.types.ts
3βββ product.types.ts
4βββ cart.types.ts
5βββ api.types.tsOption 3: Hybrid (best):
1features/
2βββ products/
3 βββ components/
4 βββ types/ # Feature-specific types
5 β βββ product.types.ts
6 β βββ filter.types.ts
7 βββ index.ts
8
9shared/
10βββ types/ # Shared types
11 βββ common.types.ts
12 βββ api.types.tsCombining feature-based for main features and type-based for shared resources:
1my-react-app/
2βββ public/
3βββ src/
4β βββ features/ # Main features
5β β βββ auth/
6β β β βββ components/
7β β β β βββ LoginForm/
8β β β β β βββ LoginForm.tsx
9β β β β β βββ LoginForm.styles.ts
10β β β β β βββ LoginForm.test.tsx
11β β β β β βββ index.ts
12β β β β βββ RegisterForm/
13β β β βββ hooks/
14β β β β βββ useAuth.ts
15β β β β βββ useSession.ts
16β β β βββ services/
17β β β β βββ authService.ts
18β β β βββ types/
19β β β β βββ auth.types.ts
20β β β βββ index.ts
21β β β
22β β βββ products/
23β β β βββ components/
24β β β β βββ ProductList/
25β β β β βββ ProductCard/
26β β β β βββ ProductFilters/
27β β β βββ hooks/
28β β β β βββ useProducts.ts
29β β β β βββ useProductFilters.ts
30β β β βββ services/
31β β β β βββ productService.ts
32β β β βββ types/
33β β β β βββ product.types.ts
34β β β βββ index.ts
35β β β
36β β βββ cart/
37β β βββ [similar structure]
38β β
39β βββ shared/ # Shared resources
40β β βββ components/
41β β β βββ Button/
42β β β β βββ Button.tsx
43β β β β βββ Button.styles.ts
44β β β β βββ Button.test.tsx
45β β β β βββ index.ts
46β β β βββ Modal/
47β β β βββ Card/
48β β β βββ Layout/
49β β β
50β β βββ hooks/
51β β β βββ useLocalStorage.ts
52β β β βββ useDebounce.ts
53β β β βββ useFetch.ts
54β β β
55β β βββ utils/
56β β β βββ formatDate.ts
57β β β βββ validators.ts
58β β β βββ helpers.ts
59β β β
60β β βββ types/
61β β β βββ common.types.ts
62β β β βββ api.types.ts
63β β β
64β β βββ constants/
65β β βββ routes.ts
66β β βββ config.ts
67β β
68β βββ layouts/ # Layout components
69β β βββ MainLayout/
70β β βββ AuthLayout/
71β β βββ DashboardLayout/
72β β
73β βββ pages/ # Page components (for routing)
74β β βββ HomePage/
75β β βββ ProductsPage/
76β β βββ ProductDetailPage/
77β β βββ CartPage/
78β β
79β βββ context/ # Global contexts
80β β βββ AuthContext.tsx
81β β βββ ThemeContext.tsx
82β β βββ CartContext.tsx
83β β
84β βββ router/ # Routing configuration
85β β βββ routes.tsx
86β β βββ ProtectedRoute.tsx
87β β
88β βββ styles/ # Global styles
89β β βββ globals.css
90β β βββ variables.css
91β β βββ reset.css
92β β
93β βββ App.tsx
94β βββ index.tsx
95β
96βββ .eslintrc.js
97βββ .prettierrc
98βββ tsconfig.json
99βββ package.json
100βββ README.md1// GOOD - 3 levels
2src/features/products/components/
3
4// BAD - too deep
5src/modules/ecommerce/features/products/ui/components/1// components/Button/index.ts
2export { default } from './Button';
3export * from './Button.types';
4
5// Usage
6import Button from './components/Button'; // readable
7// instead of
8import Button from './components/Button/Button'; // verbose1Button/
2βββ Button.tsx # Component
3βββ Button.styles.ts # Styles
4βββ Button.test.tsx # Tests
5βββ Button.types.ts # Types
6βββ index.ts # ExportStart simple - Don't over-engineer a complex structure at the beginning of a project. For a small application, type-based may suffice; only later refactor to feature-based as the project grows.
Refactor when needed - Adapt the structure as the project develops. If a folder has more than 10-15 files, consider splitting it.
Keep components small - Components should be small and focused on a single task. If a component has more than 200-300 lines, consider splitting it.
Group related files - Keep files that are closely related together. If you always edit two files together, they should probably be in the same folder.
Document - Add README.md to main directories to explain their purpose and structure.
Consistency above all - Choose one style (feature-based or type-based) and stick to it throughout the project. The worst thing is mixing styles.
1// tsconfig.json or jsconfig.json
2{
3 "compilerOptions": {
4 "baseUrl": "src",
5 "paths": {
6 "@components/*": ["shared/components/*"],
7 "@features/*": ["features/*"],
8 "@utils/*": ["shared/utils/*"],
9 "@hooks/*": ["shared/hooks/*"]
10 }
11 }
12}
13
14// Usage
15import Button from '@components/Button';
16import { useAuth } from '@features/auth';
17import { formatDate } from '@utils/formatDate';A well-organized project structure greatly facilitates work, especially in large teams and projects. Remember that there is no single "right" structure - the most important thing is that it is consistent, logical for your team, and scalable as the project grows.