DEV Community

Cover image for How to Structure a React Project in 2025: Clean, Scalable, and Practical
Nathan Chung for AlgoSync

Posted on

How to Structure a React Project in 2025: Clean, Scalable, and Practical

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
Enter fullscreen mode Exit fullscreen mode

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/
Enter fullscreen mode Exit fullscreen mode

📁 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
Enter fullscreen mode Exit fullscreen mode

📁 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
Enter fullscreen mode Exit fullscreen mode

📁 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
Enter fullscreen mode Exit fullscreen mode

📁 hooks/ – Custom Hooks

If you create your own hooks (which you will!), this is where they live:

hooks/
├── useAuth.js
├── useToggle.js
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

📁 utils/ – Utility Functions

Helper functions that don't belong to a specific feature.

utils/
├── formatDate.js
├── validateEmail.js
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

📁 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
Enter fullscreen mode Exit fullscreen mode

📄 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
Enter fullscreen mode Exit fullscreen mode
  • 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>,
)
Enter fullscreen mode Exit fullscreen mode

🚀 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)

Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
ciphernutz profile image
Ciphernutz

Great structure tips, Thanks for sharing!

Collapse
 
abhinavshinoy90 profile image
Abhinav Shinoy

Good one! Thanks for sharing!

Some comments may only be visible to logged-in visitors. Sign in to view all comments.