How should you organize a React project?
Have you ever asked yourself that question when starting a new React app? Whether it’s a tiny side project or a big production app, I’m pretty sure we’ve all wondered: “What’s the best way to structure this so it looks clean and scales well later?”
Well, here’s the truth: There’s no official standard. Since React is just a library, not a full-blown framework, it doesn’t force you into any specific folder structure or project layout.
That’s why in this post, I’ll be sharing what’s worked for me, based on personal experience and a lot of research. Hopefully, it’ll give you a solid starting point to organize your own React projects in a clean and scalable way.
🧠 The Philosophy: Structure Based on Scale
First, let me clarify this:
A React project should be structured based on the size of the app and its complexity. The bigger the project, the more important it becomes to separate concerns, reuse logic, and isolate features.
So, here’s a general structure I recommend for most small-to-medium React projects, with explanations for each folder:
src/
├── assets/
├── components/
├── pages/
├── routes/
├── hooks/
├── services/
├── utils/
├── contexts/
├── styles/
├── App.jsx
├── main.jsx
Let’s go through each of them.
📁 assets/
– Static Files & Media
This folder contains static resources such as:
- Images
- Fonts
- Icons
- Global SCSS/CSS files
Use this for anything that doesn't contain logic, just visual or media assets.
assets/
├── images/
├── fonts/
├── styles/
📁 components/
– Shared UI Components
This is for reusable components like buttons, modals, inputs, etc., that are used across multiple parts of your app.
components/
├── Button/
│ ├── Button.jsx
│ └── Button.module.css
├── Modal/
│ ├── Modal.jsx
│ └── Modal.module.css
📁 pages/
– Route-Level Components
Each file here corresponds to a route in your app. Think of it as the screen-level UI.
This helps separate page layout logic from reusable UI pieces.
pages/
├── Home.jsx
├── Login.jsx
├── PostDetail.jsx
📁 routes/
– Routing Configuration
All your route definitions and React Router
setup can live here. It makes routing centralized and easy to update when your app grows.
routes/
├── AppRoutes.jsx
└── PrivateRoute.jsx
📁 hooks/
– Custom Hooks
If you create your own hooks (which you will!), this is where they live:
hooks/
├── useAuth.js
├── useToggle.js
Tips:
- Keep reusable logic here
- Prefix them with
use
to follow React convention
📁 services/
– External API Logic
Anything related to API calls, database interactions, or third-party integrations goes here. This way, your components stay clean and declarative.
services/
├── api.js
├── postService.js
└── authService.js
📁 utils/
– Utility Functions
Helper functions that don't belong to a specific feature.
utils/
├── formatDate.js
├── validateEmail.js
Tips:
- Keep logic centralized
- Avoid duplication across features
📁 contexts/
- React Context Providers
If you're using React Context API for global state or shared configurations (like theme, auth status, or language settings), it's a good idea to organize them in their own folder.
Each context file typically includes:
- The
createContext()
call - A context provider component
- Any relevant logic or default values
contexts/
├── AuthContext.jsx
├── ThemeContext.jsx
📁 styles/
- Global Styling & Theme Config
While individual component styles can live in Button.module.css or *.scss, this folder is perfect for your global CSS setup, such as:
- Tailwind or SCSS config
- Theme variables
- Reset or normalize files
styles/
├── global.css
├── variables.css
├── tailwind.config.js
📄 App.jsx
& main.jsx
– Entry Points
-
App.jsx
is your main application shell (where routes, providers, and layout go). Example: Vite + React
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
function App() {
const [count, setCount] = useState(0)
return (
<>
<div>
<a href="https://vite.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.jsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
)
}
export default App
-
main.jsx
is the actual root file where React is rendered to the Document Object Model. Example: Vite + React
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'
createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>,
)
🚀 As Your Project Grows...
When things scale even further (teams, business complexity, domains), you can transition to a feature-sliced or domain-driven structure:
src/
├── entities/ // business models like User, Post
├── features/ // login, comment, create post
├── shared/ // shared components, hooks, utils
├── widgets/ // composed UI units (e.g., Header, Sidebar)
├── pages/
├── processes/ // flows (e.g., sign-in flow)
This is inspired by Feature-Sliced Design. Check it out here: https://feature-sliced.design/docs
🧩 Final Thoughts
React gives you freedom, but with freedom comes responsibility.
If you don’t plan your project structure early, you’ll face chaos later.
Start small and flat.
Then, organize by features.
Eventually, evolve into a modular, domain-based architecture.
Whatever the size of your app, the goal is the same:
Readable, maintainable, and scalable code.
Top comments (2)
Great structure tips, Thanks for sharing!
Good one! Thanks for sharing!
Some comments may only be visible to logged-in visitors. Sign in to view all comments.