React Folder Structure
An overview of the recommended folder structure for scalable React applications.
Separation of concerns isn't about splitting up tech layers, it's about focusing on what matters most: user outcomes.
Why Feature-Based Structure
When organizing code, simplicity should guide every decision. While countless architectural patterns exist, from flat structures to atomic design, feature-sliced architectures to micro-frontends, the feature-based (modular) approach strikes the best balance for most teams.
The beauty of organizing code by features is that it mirrors how we think about products.
Instead of spreading authentication logic across folders such as /pages
, /widgets
and /containers
, or debating which layer a file belongs to, nearly all authentication-related code is grouped together in an /auth
module.
This co-location makes it easier for developers to find what they need and focus on building features.
A Balanced Approach
Other patterns have their place. Flat structures work for tiny projects. Atomic design excels for component libraries. Feature-sliced architecture suits enterprise applications. But feature-based organization adapts to most scenarios without the overhead of complex rules or rigid hierarchies.
The goal isn't architectural purity, it's building software that teams can understand and maintain. When your folder structure reflects the features users care about, everyone can navigate the codebase intuitively.
Implementing Feature-Based Structure in Next.js
This guide focuses on the application architecture, using Next.js as an example. If you're interested in learning more about monorepo structures in general, you can refer to the Turborepo documentation here
Here’s how you can adopt a feature-oriented architecture in a Next.js project, but the core ideas can be applied to any framework. Most feature-based structures divide the codebase into three main layers:
- Routing (handled by the
app
directory in this example) - Shared
- Features

1. Routing - Understanding the Routing Layer
The routing layer sits at the top level of your Next.js application and directly maps to your application's URL structure. In this architecture, the routing folders contain only the essential files needed for Next.js routing to function.

Key Components:
posts/
- Handles all post-related routespage.tsx
- The main posts page component[postId]/
- Dynamic route for individual post pagesusers/
- Manages user-related routes
The routing layer is intentionally thin. Each folder contains minimal code, primarily serving as an entry point that connects the URL structure to your feature modules.
2. Shared - Your Application's Foundation
The shared folder contains all the common code that's used across multiple features throughout your application.

Structure Breakdown:
config/
- Application-wide configuration files (feature flags)consts/
- Global constants (enums, status codes, default values, magic numbers)components/
- Reusable UI components used across different features (modals, cards)lib/
- Utility functions and third-party library configurations (API clients, formatters)hooks/
- Custom React hooks that provide common functionality (useDebounce, useLocalStorage)
3. Features - Vertical Slices of Functionality
The features folder is where the magic happens. Each feature represents a complete vertical slice of your application, containing everything needed to deliver a specific piece of business functionality.

Feature Structure: Each feature (users, posts, comments) maintains its own internal organization:
consts/
- Feature-specific constantscomponents/
- UI components that are only used within this featurelib/
- Utility functions specific to this feature's domain logichooks/
- Custom hooks that manage the stateful logic for this feature (you may not always need this folder, only create custom hooks here if the feature logic starts to become complex)
4. Putting It All Together
Let's review everything we've covered so far to get a comprehensive overview of the entire project structure.

Traditional approaches organize by technical concern (all components together, all utilities together). Feature-based architecture organizes by business domain. This means:
- Locality of Behavior - Everything related to "posts" lives in the posts feature. Need to understand how posts work? Look in one place.
- Independent Development - Teams can work on different features with minimal conflicts and coordination overhead.
- Easier Deletion - When a feature is deprecated, you can delete one folder instead of hunting through dozens of technical folders.
- Scalability - As your app grows to dozens or hundreds of features, the structure remains navigable because each feature is self-contained.
5. Dependency Rules and Best Practices

Dependency Rules:
- Routing depends on Features, Shared - Route handlers import and compose feature components
- Features depend on Shared - Features use common components and utilities
- Shared depends on nothing - Shared code is foundational and has no INTERNAL dependencies
- Features NEVER depend on other Features - This prevents tight coupling
- Features NEVER depend on Routing
Following these rules also makes it easier to decide whether a file belongs in the features or shared folder. Since one feature cannot depend on another, if you have a component used by multiple features, it’s best to move it to the shared folder instead of keeping it inside any single feature.
When to Break the Rules
No architecture approach is perfect, they’re all just tools to help you. So don’t feel like you must follow these rules strictly. It’s okay to break them when:
- Building a proof of concept where speed matters more than structure
- Dealing with Next.js-specific requirements (like layouts that span features)
- The project is very small and strict organization isn’t needed (like this documentation site)