Clean ⢠Professional
A well-structured React project is like a well-organized workspace ā it saves time, reduces bugs, and makes collaboration easier. Whether youāre building a small app or a large-scale enterprise project, following clean architecture and consistent coding standards ensures your code remains maintainable, scalable, and easy to understand.
A good project structure helps you:
Poor structure, on the other hand, can make even small projects messy and difficult to maintain as they grow.
Hereās a commonly used, scalable folder structure for modern React projects:
src/
āāā assets/ # Images, icons, fonts, videos
āāā components/ # Reusable UI components (Buttons, Inputs, Cards)
āāā pages/ # Page-level components (Home, About, Dashboard)
āāā hooks/ # Custom React Hooks (useAuth, useFetch)
āāā context/ # Context API files (ThemeContext, AuthContext)
āāā store/ # Redux, Zustand, or Recoil state management
āāā services/ # API calls and external services
āāā utils/ # Helper functions and utilities
āāā styles/ # Global CSS, SCSS, or styled-components themes
āāā routes/ # App routing configuration
āāā constants/ # App-wide constants and config variables
āāā App.js # Root component
āāā index.js # Entry point for ReactDOM.render
āāā setupTests.js # Jest/RTL configuration
components/ ā Contains small, reusable building blocks like Button, Navbar, or Modalpages/ ā Represents full-page views like HomePage, LoginPage, or ProfilePagehooks/ ā Stores reusable custom hooks such as useForm or useFetchservices/ ā Central place for API logic using Axios or Fetchcontext/ ā Defines global app contexts (e.g., Theme, Auth)store/ ā Manages state if using Redux Toolkit or Zustandutils/ ā Contains helper functions (e.g., formatDate, validateEmail)styles/ ā Centralized styling for consistent UI themesUserProfile.jsuseAuth.jsuser-icon.svgAPI_BASE_URLExample:
// Good
function UserCard() {}
// Bad
function user_card() {}
Instead of having one massive components folder, group related files by feature or domain.
src/
āāā features/
āāā auth/
ā āāā LoginPage.jsx
ā āāā RegisterPage.jsx
ā āāā AuthContext.js
ā āāā authService.js
āāā dashboard/
ā āāā DashboardPage.jsx
ā āāā ChartWidget.jsx
ā āāā dashboardService.js
This makes it easier to maintain large applications as each feature is self-contained.
Maintaining consistency in your code style helps teams write clean, readable, and error-free code.
Here are some key standards to follow:
Install and configure ESLint and Prettier to automatically format and lint your code.
Example (ESLint + Prettier setup):
npm install eslint prettier eslint-config-prettier eslint-plugin-react --save-dev
Then create a .eslintrc.json file:
{
"extends": ["react-app", "prettier"],
"plugins": ["react"],
"rules": {
"react/prop-types": "off",
"no-unused-vars": "warn"
}
}
here,
Each component should handle one responsibility.
Avoid:
function Dashboard() {
// Handles API calls, rendering charts, managing modals, etc.
}
Instead, split logic:
function Dashboard() {
return (
<><DashboardHeader />
<UserStats />
<RecentActivities />
</>
);
}
Example:
// Good
const [userData, setUserData] = useState([]);
// Bad
const [a, b] = useState([]);
Keep data fetching and business logic separate from UI rendering.
Mixing logic inside components:
function UserList() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetchUsers().then(setUsers);
}, []);
return users.map(u => <p>{u.name}</p>);
}
Better approach:
// useUsers.js
export function useUsers() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetchUsers().then(setUsers);
}, []);
return users;
}
// UserList.jsx
import { useUsers } from "../hooks/useUsers";
function UserList() {
const users = useUsers();
return users.map(u => <p>{u.name}</p>);
}
Use PropTypes or TypeScript for validating props and ensuring type safety.
import PropTypes from "prop-types";
function UserCard({ name, age }) {
return <div>{name} ā {age}</div>;
}
UserCard.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number
};
or with TypeScript:
type UserCardProps = {
name: string;
age?: number;
};
const UserCard = ({ name, age }: UserCardProps) => (
<div>{name} ā {age}</div>
);
Use:
git commit often and write clear messages)src/
āāā api/
ā āāā axiosInstance.js
āāā components/
ā āāā Button.jsx
ā āāā Card.jsx
ā āāā Modal.jsx
āāā context/
ā āāā AuthContext.js
āāā hooks/
ā āāā useAuth.js
ā āāā useFetch.js
āāā pages/
ā āāā Home.jsx
ā āāā Login.jsx
ā āāā Dashboard.jsx
āāā store/
ā āāā index.js
āāā styles/
ā āāā globals.css
ā āāā variables.scss
āāā utils/
āāā formatDate.js
| Practice | Benefit |
|---|---|
| Organized folder structure | Easy navigation and scalability |
| ESLint + Prettier | Consistent and clean code |
| Small, focused components | Reusable and testable |
| Separation of logic and UI | Better maintainability |
| Type checking | Fewer runtime errors |
| Documentation & Git | Easier collaboration |