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.
What to read next
- Starting a React Project : how to set up a new project with Vite
- Custom Hooks
: what goes in the
hooks/folder - Functional Components
: how to build the components that go in
components/