Building Scalable Next.js Applications from Scratch
Next.js has become a go-to framework for building React web applications, thanks to its impressive features like first-class support for various tools and libraries, CSS modules for styling, TypeScript for type safety, image optimization, and more. However, to build scalable applications, it’s essential to structure your Next.js project strategically. In this article, we’ll guide you through setting up a Next.js application from scratch, ensuring it’s scalable and maintainable.
Setting Up a Next.js Project
Let’s start by installing a fresh Next.js project. Run the following command in your terminal:
npx create-next-app nextjs-architecture --typescript
This will create a Next.js boilerplate template called nextjs-architecture
. Make sure to choose --typescript
as a flag, as it allows better type safety, a must-have for modern, scalable, full-stack apps.
Ensuring Engine Compatibility and Stability
When building an app for work, multiple team members are often involved. To ensure consistency, add a .nvmrc
file at the root level of your project and specify the Node.js version you want to use. In this case, we’ll use Node v18:
node 18
Create a new file called npmrc
and add the following code to configure your package manager:
engine-strict=true
Then, add a new key-value pair to your package.json
file:
"engines": {
"node": ">=16"
}
This ensures your project requires Node.js version 16 and above to run and enforces the use of npm as a package manager.
Setting Up Git Version Control
At this point, you have set up some basic boilerplate code for Next.js along with some configuration. Now, let’s add a version control system to work with fellow team members on this project. Create an empty repository on GitHub and name it nextjs-architecture
. Then, push changes to that empty repo using the following command:
git remote add origin https://github.com/your-username/nextjs-architecture.git
git push -u origin master
Engine Locking
Implement engine locking to ensure your project uses the same version across different environments. This makes your project less error-prone and ensures it works as expected in both development and production environments. Add a key called engines
in your package.json
file:
"engines": {
"node": "18.x"
}
Create a config file for npm called .npmrc
at the root level and add the following line:
engine-strict=true
Enforcing Code Formatting Rules
Code formatting is crucial for maintaining code consistency in your project as it scales. To enforce a strict set of code formatting rules, add ESLint to your project. Next.js comes with built-in support for ESLint, so you simply need to configure it. Check for a .eslintrc.json
file at the root level of your project and add the following code:
{
"rules": {
"react/jsx-uses-react": "error",
"no-unused-vars": "warn"
}
}
Install Prettier to provide a consistent coding format for all team members:
npm install prettier
Create two files at the root level: .prettierrc
and .prettierignore
. The .prettierrc
file will contain all the Prettier rules you’re introducing in the project. The .prettierignore
file will contain the names of files and folders you don’t want Prettier to run and analyze.
Structuring Your Next.js Directory
Now, let’s decide how to architect your application code. Next.js doesn’t have an opinion on how you should structure your app, but since it has file-based routing, you should structure your app similarly. Create a directory structure as follows:
app/
components/
utils/
hooks/
...
Setting Up a Custom Layout
In the App Router in Next.js v13 or greater, you already have out-of-the-box support for a layout file. You can put any components that will be shared across the application, such as Navbar, Footer, and others, in this layout file.
Integrating Next.js with Storybook
Next.js pairs nicely with the Storybook library, an essential part of building a modern web application. Install Storybook like so:
npx sb init
Setting Up a Pre-Commit Hook
As your codebase grows, you may have many developers working on it simultaneously. In such cases, it’s essential to enforce a set of rules such as code formatting, single quote vs double quote, linting rules, and more to ensure consistency, streamline collaboration, and prevent errors. To set up a pre-commit hook with Next.js, you need the following tools: ESLint, Husky, lint-staged, and Prettier.
Deploying Your Next.js Application
After you’ve pushed everything to GitHub, the final step would be deploying the Next.js application. You can choose any hosting provider, but we’ll be using Vercel in this demo project, as it’s the most straightforward option for Jamstack applications.
By following these steps, you’ve set up a scalable Next.js application from scratch, ensuring it’s easy to maintain and grow as your project continues to evolve.