Next.js: Best Way to Organize Your Project Structure
Tags: nextjs, react, javascript, webdev
Published: 2024-06-04 03:16:04

Whenever I start a new Next.js project, I search for the best way to organize my file structure, especially when I moved to App Router from Pages Router. There are [app routing folder and file conventions](https://nextjs.org/docs/getting-started/project-structure#app-routing-conventions) every Next.js project would need to follow, but apart from that, there are several ways to organize your project files.

Before showing how I typically structure my projects, I would like to briefly discuss the features [Next.js provides to help organize your project] (https://nextjs.org/docs/app/building-your-application/routing/colocation) and a few common strategies.

- Safe colocation by default
- Private Folders
- Router Groups
- src Directory
- Module Path Aliases

### Safe colocation by default
In the app directory, [nested folder hierarchy](https://nextjs.org/docs/app/building-your-application/routing#route-segments) defines the route structure. However, a route is not publicly accessible until a `page.js` or `route.js` file is added to a route segment. Even when a route is publicly accessible, the content returned by the `page.js` or `route.js` file is sent to the client. This means your project files can be safely colocated inside route segments in the `app` directory without accidentally being routable.
- `/app/settings/page.tsx` -> Routable
- `/app/settings/nav.tsx` -> Not Routable
- `/app/settings/constants.ts` -> Not Routable
- `/app/api/monkeys/route.ts` -> Routable
- `/app/api/monkeys/db.ts` -> Not Routable

### Private Folders
[Private folders](https://nextjs.org/docs/app/building-your-application/routing/colocation#private-folders) can be created by prefixing the folder name with an underscore: `_folderName`. 
This hides the folder and its contents from the routing system.
- `/app/_settings/page.tsx` -> Not Routable

Private folders can be useful for separating UI logic from routing logic and avoiding potential naming conflicts with Next.js file conventions.

### Router Groups
[Route groups](https://nextjs.org/docs/app/building-your-application/routing/colocation#private-folders) can be created by wrapping a folder in parenthesis: `(folderName)`. This indicates the folder is for organizational purposes and should not be included in the route's URL path.
`/app/(admin)/dashboard/page.tsx` routes to `/dashboard`

### src Directory
Next.js allows storing application code in an optional `src` directory. This separates application code from project configuration files as they mostly live at the root of the project. 
I used to ignore the `src` directory since it wasn't the default when creating a Next.js project, but I've been using it recently as I like the separation of root configuration files from the application code.

### Module Path Aliases
Next.js makes it easy to read and maintain imports across deeply nested project files with [Module Path Aliases](https://nextjs.org/docs/app/building-your-application/configuring/absolute-imports-and-module-aliases).
```TS
// Before
import { Button } from '../../../../../../components/button'
 
// After
import { Button } from '@/components/button'
```

## Project Organization Strategies
Next.js is nice enough to provide a few [strategies for organizing your project](https://nextjs.org/docs/app/building-your-application/routing/colocation#project-organization-strategies). 

- Store project files outside of the app
- Store project files in top-level folders inside the app
- Split project files by feature or route

### Store project files outside of the app
Store all application code in shared folders at the root of your project and keep the `app` directory purely for routing purposes. 
```
my-app/
├─ app/
│  ├─ settings/
│  │  ├─ page.tsx
├─ components/
│  ├─ settings.tsx
├─ utils/
│  ├─ server_actions.ts
├─ package.json
├─ README.md
```
I like this approach as this gives you more flexibility on how you want to structure your application code as well as decoupling Next.js file conventions.

### Store project files in top-level folders inside the app
```
my-app/
├─ app/
│  ├─ components/
│  │  ├─ settings.tsx
│  ├─ utils/
│  │  ├─ server_actions.ts
│  ├─ settings/
│  │  ├─ page.tsx
├─ package.json
├─ README.md
```
You'll need to be careful not to add an accidental `page.tsx` or `route.ts` to these top-level folders if you don't want to expose these routes publicly. 

### Split project files by feature or route
Store globally shared application code in the root `app` directory and split more specific application code into the route segments that use them.
```
my-app/
├─ app/
│  ├─ components/
│  ├─ utils/
│  ├─ settings/
|  |  ├─ components/
│  |  ├─ utils/
│  │  ├─ page.tsx
├─ package.json
├─ README.md
```
I've been trying a structure similar to this recently. I find it easy to navigate my code this way. This tightly couples your application code with the routing system. One worry I have is depending on the routing system changes in future updates, there could be potential conflicts when upgrading.

## Conclusion
There is no "right" or "wrong" way when it comes to organizing your files and folders in a Next.js project. As long as the structure is consistent across your project, choose a strategy that works for you and your team.

I'm curious to know how you organize your Next.js projects.