DEV Community

Jonathan U
Jonathan U

Posted on • Edited on

Next.js: Best Way to Organize Your Project Structure

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 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 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 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 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 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.

// Before
import { Button } from '../../../../../../components/button'

// After
import { Button } from '@/components/button'
Enter fullscreen mode Exit fullscreen mode

Project Organization Strategies

Next.js is nice enough to provide a few strategies for organizing your project.

  • 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)