This is a scalable Next.js project folder structure designed for large-scale e-commerce applications. It ensures modularity, maintainability, and ease of scaling as the application grows, with clear separations between business logic, UI components, state management, and routing.
/src
/assets
/components
/features
/pages
/layouts
/providers
/services
/hooks
/context
/utils
/config
/types
/store
/routes
/tests
/api
/i18n
This folder holds static resources such as images, fonts, styles, icons, and any other non-JS assets.
- Examples:
logo.svg
,icons/
,images/
,fonts/
,styles/
Contains reusable UI components. The Atomic Design approach can be used to organize components into atoms, molecules, organisms, and templates. This structure allows for building small, reusable components that can be combined into more complex components.
-
Structure Example:
/components /atoms Button.tsx LazyLoadPhoto.tsx /molecules MainNavbar.tsx SocialLogin.tsx /organisms Header.tsx Footer.tsx /common /form Form.tsx FormWrapper.tsx InputWrapper.tsx /loader ButtonLoader.tsx
atoms
: Small, independent components (buttons, inputs, icons) used across the application.molecules
: More complex components that combine multiple atoms (e.g., aNavbar
combiningLogo
,SearchInput
, andButtons
).organisms
: Larger UI components that include molecules and atoms (e.g., aHeader
combiningNavbar
andCartIcon
).common
: Utility components shared across different UI elements (e.g.,FormWrapper
,ButtonLoader
).
Feature-based folders for specific business logic. Each feature folder can contain its own components, services, hooks, and context, making it easy to scale or modify features independently.
-
Structure Example:
/features /cart CartCard.tsx CartDetails.tsx /product ProductCard.tsx ProductDetails.tsx
- Feature-specific hooks, components, and context should live here. For example, the cart feature might have its own logic for adding/removing items from the cart, and the product feature could have product-specific hooks or services.
This folder contains the main page components corresponding to the app's routes. Each page imports components or features and represents a unique screen/view in the application.
- Examples:
Home.tsx (page)
,ProductDetails.tsx (page)
,Cart.tsx (page)
Layouts define the overall structure of different pages, such as headers, footers, sidebars, and wrappers.
- Examples:
MainLayout.tsx (layout)
,AuthLayout.tsx (layout)
,AdminLayout.tsx (layout)
This folder holds global providers for third-party libraries or application-wide contexts, such as ThemeProvider
or AuthProvider
.
- Examples:
ThemeProvider.tsx
,AuthProvider.tsx
Contains API services and other shared business logic. This is where you make your API calls or interact with the backend, currently we are avoiding actions
folder under `app/actions.
- Examples:
authService.ts
,productService.ts
,orderService.ts
This folder contains custom React hooks used across the app. For feature-specific hooks, those should live within the respective feature folder.
- Examples:
useAuth.ts
,useFetch.ts
,useDebounce.ts
For global state management using React's Context API or third-party state management like Redux.
- Examples: AuthContext.ts
, CartContext.ts
Contains reusable utility functions and helper modules used throughout the application.
- Examples:
dateFormat.ts
,mathUtils.ts
,storage.ts
Holds configuration files like environment settings, constants, or route configuration.
- Examples:
constants.ts
,routes.ts
,appConfig.ts
Contains TypeScript type definitions and interfaces. This folder is essential for maintaining type safety across your project.
- Examples:
product.d.ts
,user.d.ts
,cart.d.ts
For Redux Toolkit or other centralized state management libraries. This folder contains the store configuration and slices.
-
Structure Example:
/store /slices cartSlice.ts productSlice.ts userSlice.ts store.ts
-
Example of
cartSlice.ts
:// store/slices/cartSlice.ts import { createSlice } from "@reduxjs/toolkit"; const cartSlice = createSlice({ name: "cart", initialState: { items: [], }, reducers: { addItem: (state, action) => { state.items.push(action.payload); }, removeItem: (state, action) => { state.items = state.items.filter( (item) => item.id !== action.payload.id ); }, }, }); export const { addItem, removeItem } = cartSlice.actions; export default cartSlice.reducer;
-
Example of
productSlice.ts
:// store/slices/productSlice.ts import { createSlice } from "@reduxjs/toolkit"; const productSlice = createSlice({ name: "product", initialState: { products: [], }, reducers: { setProducts: (state, action) => { state.products = action.payload; }, }, }); export const { setProducts } = productSlice.actions; export default productSlice.reducer;
-
Example of
userSlice.ts
:// store/slices/userSlice.ts import { createSlice } from "@reduxjs/toolkit"; const userSlice = createSlice({ name: "user", initialState: { userInfo: null, }, reducers: { setUserInfo: (state, action) => { state.userInfo = action.payload; }, clearUserInfo: (state) => { state.userInfo = null; }, }, }); export const { setUserInfo, clearUserInfo } = userSlice.actions; export default userSlice.reducer;
-
Example of
store.ts
:// store/store.ts import { configureStore } from "@reduxjs/toolkit"; import cartReducer from "./slices/cartSlice"; import productReducer from "./slices/productSlice"; import userReducer from "./slices/userSlice"; const store = configureStore({ reducer: { cart: cartReducer, product: productReducer, user: userReducer, }, }); export default store;
-
Contains the React Router configuration, where each route is defined. It can include logic for protected routes, lazy loading, and route-based layouts.
- Structure Example:
/routes
AppRouter.tsx
ProtectedRoute.tsx
-
Example of
AppRouter.tsx
:// routes/AppRouter.tsx import React from "react"; import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; import HomePage from "../pages/Home"; import ProductDetails from "../pages/ProductDetails"; import Cart from "../pages/Cart"; import routes from "../config/routes"; const AppRouter = () => ( <Router> <Switch> <Route exact path={routes.HOME} component={HomePage} /> <Route path={routes.PRODUCT_DETAILS} component={ProductDetails} /> <Route path={routes.CART} component={Cart} /> </Switch> </Router> ); export default AppRouter;
Unit, integration, and end-to-end tests. This folder can also include testing utilities and mock data.
- Structure Example:
/tests /unit cart.test.ts product.test.ts /integration appIntegration.test.ts
Contains API-related logic, including Axios setup, request interceptors, and global error handling.
- Examples:
axiosInstance.ts
,requestInterceptors.ts
For internationalization and localization files, including locale data and translations.
- Examples:
en.json
,fr.json
,bn.json
- Use
PascalCase
for React components:ProductCard.tsx
- Use
camelCase
for hooks, utilities, and services:useFetch.ts
,authService.ts
- Group related files together when appropriate:
/components /Button Button.tsx Button.css Button.test.ts
- Feature-Based Structure: Each domain or feature gets its own folder, making the project more scalable.
- Reusable Components: Common UI components are stored in
/components
and follow Atomic Design patterns for reuse. - Modular Layouts: Organizing pages and layouts separately promotes clean, modular design.
- Separation of Concerns: Business logic, UI, and data fetching are separated for maintainability.
- State Management: Centralized state management (like Redux) is organized in
/store
for scalability.