How to Organize a Next.js Full Stack Project
Opened this issue ยท 5 comments
Hi there! In this article, I want to show you how I organize my Next.js Full Stack Project.
Folder Structure
First of all, you can take a look at the folder structure below. You can see that src is the root-level application project. Yes! I want to place my code into the src folder.
- src
- backend
- entities
- migrations
- resolvers
- services
- frontend
- components
- services
- pages
- api
- app
- shared
- schemas
- services
- backend
Shared Folder
I often have some code that I want to use for both frontend and backend, such as schemas
for typed-safe API, services
for accessing environment variables or utility functions, ...
With these kinds of code, I want to place them into the shared folder.
Backend Folder
In the backend folder, I want to place my server code, such as:
- entities is for TypeORM entities.
- migrations is for TypeORM migrations.
- resolvers is for resolvers of API schemas.
- services is to place reusable code for resolvers.
Frontend Folder
In the frontend folder, I want to place my client code, such as:
- components is for reusable components
- services is to place reusable code for components and pages.
Pages Folder
pages is the default Next's folder for routing. Inside the pages folder, I have:
- api is for server API handlers.
- app is for the main authenticated app.
Setup Next.js
In this section, I will set up a Next.js application with the folder structure above.
Generate Next.js application
First, I will create a new Next.js application named next-full-stack with the command below.
yarn create next-app next-full-stack
Next, I change the working folder to next-full-stack.
cd next-full-stack
Next, I remove these Next.js default folders.
rm -rf styles pages
Next, I create a new folder named src to store all my code.
mkdir src
Finally, I change the working folder to src to ready for the next steps.
cd src
Create Folders
To organize the folder structure which we have, I will run these command to create the folders.
Create Main Folders
mkdir shared backend frontend pages
Create Shared's Sub Folders
mkdir shared/services shared/schemas
Create Backend's Sub Folders
mkdir backend/entities backend/migrations backend/resolvers backend/services
Create Frontend's Sub Folders
mkdir frontend/components frontend/services
Create Home Page
To create the home page for my project, I'll create a text file named index.tsx
in the pages folder. The file will have the content below.
touch pages/index.tsx
export default function Page() {
return <h1>Hello World!</h1>;
}
Add TypeScript Support
I'd like to work with TypeScript on this project. So I will do these steps to have TypeScript support.
yarn add --dev typescript @types/react @types/node
Run this command to let Next.js create next-env.d.ts
and tsconfig.json
files for TypeScript configuration.
yarn dev
Configure module aliases
Using relative import like this import mod from '../../../mod.ts'
is so ugly. So I will add these lines to tsconfig.json
, section compilerOptions
to make my import code more beautiful.
"baseUrl": "src",
"paths": {
"@backend/*": ["backend/*"],
"@frontend/*": ["frontend/*"],
"@shared/*": ["shared/*"]
}
And my new tsconfig.json
will look like this.
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"baseUrl": "src",
"paths": {
"@backend/*": ["backend/*"],
"@frontend/*": ["frontend/*"],
"@shared/*": ["shared/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
From now on, I can import my child modules with these lines:
import { EnvService } from '@shared/services/env.service.ts'
Or
import { UserService } from '@backend/services/user.service.ts'
Or
import { ApiService } from '@frontend/services/api.service.ts'
Demo: https://next-full-stack-git-issue-1.maxvien.vercel.app/
Source Code
You can find the source code of this tutorial in this branch: https://github.com/maxvien/next-full-stack/tree/issue-1
Now you can create next app with typescript enabled by default via:
yarn create next-app next-full-stack --typescript
Hi @Maxvien! This proposal is definitely a great approach to organising projects in Next.js (enforce cohesion, good discoverability and good understandability of the project). Personally, I like to follow your structure but adding an additional level of grouping within the main categories:
- backend
- modules
- auth
- ...
- shared (reuse across backend modules)
- lib
- utils
- ...
- modules
- frontend
- modules (or pages)
- auth
- Auth.tsx
- components
- hooks
- ...
- auth
- shared (reuse across frontend modules)
- components
- hooks
- ...
- modules (or pages)
- pages
- api
- auth
- ...
- shared (reuse across backend/frontend)
- utils
- core
- ...
Hey @Maxvien, my project was becoming so convoluted and it didn't feel sustainable. Thanks for posting this cause it brought a LOT more clarity to my project. The tsconfig.json
was really the key that brought it all together. The only thing I changed was "client/server" instead of "frontend/backend". Thank you!
@Maxvien I like your approach better
Any One can share for new Next JS 14, App Router