Setting up a Next.js Project with Essential Best practices
8 mins read
#nextjs
#developer-experience
#tools
Introduction
Setting up a Next.js project isn’t just about installing dependencies, it’s about creating a maintainable, high-quality foundation. In this guide, we’ll cover a proven setup for essential tools like Prettier, ESLint, Husky, and Commitlint to ensure consistency, catch issues early, and improve team workflows, helping you stay organized and productive.
Project Setup
Start by creating a new Next.js project:
Name your project when prompted, and select Yes
for ESLint setup.
After the prompts, create-next-app
creates a folder named after your project and installs the required dependencies.
Engine locking
Ensuring consistent Node.js versions across environments is essential for predictable functionality in both development and production. Specify the supported Node.js version in your package.json
:
At the time of writing this, Next.js requires Node.js version
18.18.x
or later.
Second, add a .npmrc
file next to package.json
. This .npmrc
configuration enforces the Node.js version specified in package.json
, preventing incompatible Node.js versions from being used.
The engine-strict
setting tells your package manager to stop with an error on unsupported versions. This looks like:
Let’s create our first commit:
Ignore the commit message structure for now, since we will be talking about it later on in this guide. Or jump directly to it Commitlint.
ESLint
ESLint already comes installed and pre-configured when creating a new Next.js project.
Let’s add a bit of extra configuration to make it stricter than the default settings. If you disagree with any of the rules it sets, no need to worry, it’s very easy to disable any of them manually. Use .eslintrc.json
in the root directory to configure these additional rules.
Next, we will add eslint-plugin-tailwindcss
for linting our tailwind classes (check for correct order, check for contradicting classnames…).
Then update your .eslintrc.json
file:
Let’s commit our changes
Prettier
Prettier is an opinionated code formatter that automatically formats our files based on a predefined set of rules.
It is only used during development, so I’ll add it as a devDependency
:
Next, create a config file .prettierrc
with the following content:
For the full configuration reference, check out the official documentation.
Next, create a .prettierignore
file that lists the different directories/files we don’t want prettier to format:
Add the following scripts to format files manually or check formatting status in CI environments:
You can now run:
Tailwind CSS
In order to automatically sort tailwind classes following the class order recommended by the tailwind team, we will be adding a new plugin to prettier called prettier-plugin-tailwindcss
:
And then update your .prettierrc
file and add plugins
property to it:
Sort imports
Next up, we will be adding @ianvs/prettier-plugin-sort-imports
to our prettier config , this will allow us to sort import declarations using RegEX order.
First, install it as a devDependency
:
Then, update your .prettierrc
file to be as follows:
Let’s commit our changes
Git Hooks
Git hooks are scripts triggered at various stages in the Git workflow, ideal for enforcing code quality checks.
Husky 🐶
We are going to use a tool called husky.
Husky is a tool that makes it easier to use Git hooks, it provides a unified interface for managing hooks.
Install husky:
husky init
command:
The init
command is the new and recommended way of setting up husky in your project. It creates a pre-commit
script in .husky/
and updates the prepare
script in your package.json
.
Adding a New Hook:
Adding a new hook is as simple as creating a file, but first, delete the existing hook (.husky/pre-commit
) since we will be adding our own later on.
Add a pre-push
hook for building code:
Commitlint
As you may have noticed from the previous commit messages, they follow a specific standard we call Conventional Commits, which is a lightweight convention on top of commit messages.
For more details, see Why Use Conventional Commits.
Now to ensure that our commit messages follow this standard, we will use a tool called commitlint, which acts as a linter for commit messages.
Install commitlint:
Configure commitlint to use conventional config:
Since we want to lint our commit messages before they are created we will use Husky’s commit-msg
hook.
Let’s test the hook by commiting something that doesn’t follow the rules, you should see something like this if everything works.
Lint staged
Lint staged optimizes Git workflows by running linters on only staged files, improving speed and ensuring relevant files are checked before commiting.
Install lint staged.
Then create a new file in the root of your project and name it .lintstagedrc.js
and paste the following code to it.
The configuration above tells lint-staged
to run next lint --fix
and prettier --write
on files that match the specified patterns.
Finally, let’s add our pre-commit
hook so that this runs everytime before creating a new commit.
Let’s commit our changes
VS Code setup
I chose VS code for this guide since it is the most used editor out there, I use neovim btw…
Extensions
Make sure you have these extensions installed:
These VS Code extensions streamline code formatting, linting, and Tailwind utility usage directly in your editor.
Workspace Settings
After configuring ESLint and prettier, it is time to make VS Code use them automatically. To do this first create .vscode
directory in the root of your project and then add settings.json
file and paste the following content to it.
This will tell VS Code to use the Prettier extension as the default formatter and automatically format your files every time you save.
Recap
To summarise this whole article, here are some keypoints to keep in mind:
- A solid setup accelerates software development, allowing you to focus more on business goals.
- In team environments, these tools ensure consistency and uniformity, making collaboration smoother and more efficient.
That was it for me, PEACE ✌️.