Frontend Development
How to Structure a React Project for a Real World Application
By Abid Ali · Published · Updated
A practical folder layout for a React and Next.js app: where pages, components, data, and shared helpers belong, with a real project as the example.

A React project structure is a set of places for routes, interface pieces, data, and helpers. The folders should answer a question a teammate actually asks: where does this change go? If the answer is "somewhere under src," the layout is not doing its job.
Digital Dialogue, a public Next.js site, uses a layout that has already been through that question. The repository root holds config. Application code sits in src:
src/
app/ routes and layouts
components/ interface pieces
lib/ shared helpers, including metadata
types/ shared TypeScript types
constants/ fixed values
styles/ CSS that is not inside a componentThat is a folder structure for a react app, not a theory diagram. Routes stay in the next.js app directory. A post card, a navbar, and a table of contents live under components, grouped by what they render (PostCard, ShareButtons, tools). Helpers that more than one route needs, such as src/lib/metadata.ts, stay out of the route file.
What each folder is for
Routes. In the next.js app directory, page.tsx and layout.tsx decide the URL and the shell. A route file should load data and render a few components. When a page file starts owning form state, fetch logic, and markup for five sections, move the sections out.
Components. A component folder organization follows the screen, not the framework. Meme Tap's interface is a search field, a row of category chips, and a grid of sound buttons with favourite, download, and share actions. Those are three components even if they ship on one page. The sound button is reused for trending, search results, and favourites, so it does not belong inside the home page file.
Data. Copy, records, and image paths change more often than the layout. On this portfolio, project facts sit in data/, and long HTML concepts sit in content/. The components read those records. Editing a tagline does not require opening a layout component.
Lib. Pure helpers go here: metadata builders, validation, formatting. If a function does not render anything, it does not need to live beside JSX.
A layout that stays readable
Use this shape for a product that will still be edited in a year:
app/ routes only
components/ shared UI
forms/
media/
data/ records the UI renders
lib/ helpers with no markup
content/ long-form copy, when it is not in a CMS
public/ static filesName a file after what it renders or what it returns. PostCard is clear. Utils2 is not. Colocate a component's small helper next to it when nothing else uses that helper. Promote the helper to lib on the second use, not before.
Decisions that keep the tree small
- One component, one reason to open the file. A card that also fetches, sorts, and owns a modal is three units.
- Do not mirror the URL tree inside
componentsunless a feature is large enough to own its own screens. Prematurefeatures/blog/components/cards/itemsfolders hide a 40-line component. - Server data loading stays in the route. Client state stays in the component that needs it. Mixing both in a single "container" file was a Pages Router habit. In the app directory, the page can load data and pass plain props down.
- Types that cross a boundary (a post, a project, a form payload) live in one module. Local prop types can sit in the component file.
Digital Dialogue's components/tools/ folder is the feature case. Calculators share fields and a result card, and those files sit together because they change together. The navbar does not live in that folder. Same rule, applied in both directions.
What to check on a new repo
Open the home route and count how many concerns it owns. If the file renders the page, fetches the content, and formats the dates, split formatting into lib and the repeated block into components. Then follow one edit from the content source to the pixel. On a soundboard, that path is: sound record, sound button, grid on the page. On a blog, it is: CMS entry or markdown file, metadata helper, post card. If that path crosses more than three folders, the react project structure is probably deeper than the product.
Questions
- Should every component live in one folder?
- No. Group components by the interface they belong to, and keep route files thin. A single components folder is fine at the start, then split it when a feature has its own screens, state, and helpers.
- Where should content and copy live?
- Keep copy, project records, and other data outside the components that render them. A data or content folder can change without rewriting the UI.
- Does the Next.js app directory replace a components folder?
- No. The next.js app directory holds routes, layouts, and loading states. Reusable interface pieces still belong in a components folder so more than one route can use them.
Next in the reading path: CSS Grid vs. Flexbox: Practical Examples