React Project Structure

React does not enforce a folder structure. You can organise your files however you want. That flexibility is useful, but it can be confusing when you are starting out. This page shows a practical structure that works well for most projects.

What Vite scaffolds

When you run:

npm create vite@latest my-app -- --template react
cd my-app

You get this structure:

my-app/
├── public/          # static files served as-is (favicon, robots.txt)
├── src/
│   ├── assets/      # images and other files imported by components
│   ├── App.jsx      # root component
│   ├── App.css
│   ├── main.jsx     # entry point (calls createRoot)
│   └── index.css
├── index.html
├── package.json
└── vite.config.js

This is fine for a small project or a quick demo. Once you have more than a handful of components, you will want to add some structure inside src/.

A practical structure for small to medium apps

src/
├── assets/          # images, fonts, icons
├── components/      # shared, reusable UI components
├── hooks/           # custom hooks
├── pages/           # top-level page components (one per route)
├── utils/           # pure utility functions (formatDate, truncate, etc.)
├── App.jsx
└── main.jsx

Each folder has one clear job:

  • assets: static files that your components import directly
  • components: buttons, cards, modals, navbars; anything used in more than one place
  • hooks: your custom hooks (files starting with use)
  • pages: one component per route; these compose smaller components into a full screen
  • utils: helper functions that do not depend on React (date formatting, string manipulation, API request helpers)

The components folder

For a small number of components, a flat list is fine:

components/
├── Button.jsx
├── Button.module.css
├── Card.jsx
├── Card.module.css
└── Navbar.jsx

When a component has multiple files (JSX, CSS, tests), a component folder keeps things tidy:

components/
├── Button/
│   ├── Button.jsx
│   ├── Button.module.css
│   └── index.js
├── Card/
│   ├── Card.jsx
│   └── Card.module.css
└── Navbar/
    └── Navbar.jsx

The index.js file re-exports the component so import paths stay clean:

// components/Button/index.js
export { default } from './Button';

With that in place, you import the component the same way regardless of whether it is in a folder or a flat file:

import Button from '../components/Button';

Pages vs components

Pages (sometimes called views or screens) are top-level components that correspond to a route. They pull smaller components together to form a complete screen.

Components are reusable pieces that do not know which route they are on. A Card component does not care whether it appears on the home page or a dashboard. A HomePage component does know that it is the home page.

A rough rule: if a component is only used in one route and contains route-specific logic, put it in pages/. If it could be used anywhere, put it in components/.

Feature-based structure for larger apps

Once a project grows past around ten components, grouping by feature rather than by type becomes easier to navigate. Instead of scrolling through a long components folder to find everything related to authentication, it is all in one place.

src/
├── features/
│   ├── auth/
│   │   ├── LoginForm.jsx
│   │   ├── useAuth.js
│   │   └── authUtils.js
│   ├── dashboard/
│   │   ├── Dashboard.jsx
│   │   └── DashboardCard.jsx
│   └── profile/
│       ├── ProfilePage.jsx
│       └── ProfileForm.jsx
├── components/      # truly shared components used across features
├── App.jsx
└── main.jsx

Each feature folder contains everything that feature needs: components, hooks, utilities. Shared components that are used across multiple features still live in components/.

Naming conventions

Consistent naming makes it easier to find files.

  • Component files: PascalCase (Button.jsx, UserCard.jsx)
  • Hook files: camelCase starting with use (useAuth.js, useFetch.js)
  • Utility files: camelCase (formatDate.js, api.js)
  • CSS Module files: match the component name (Button.module.css)

Keep it simple until you need more

A project with five components does not need feature folders or a utils/ directory. Start with a flat components/ folder inside src/. Reorganise when finding files takes more effort than it should.

The best structure is one that the people working on the project can navigate without thinking about it.