Linting, Formatting, and Pre-commit Setup in NextJS

Mario Gunawan
5 min readSep 11, 2022

this tutorial also includes my preferred Lint / Formatting setup

With the rising use of NextJS, in this article I want to share you my 3 favorite tools to make your codebase cleaner and healthier. I will also share my preferred setups from each of this tools.

Eslint

for the course of this tutorial, you can swap yarn add --dev with npm install --save-dev

Eslint is the most popular linter for javascript projects. Despite its popularity, eslint receives a lot of hate due to its notoriety while using in a personal project. Despite that, eslint is really useful for your codebase in the long run, especially if you modify the configuration to suit your own needs.

To use eslint in nextjs, install these 2 dependencies:

yarn add --dev eslint
yarn add --dev eslint-config-next

After installing dependencies, create .eslintrc.json in your base directory and add those configuration:

{
"extends": ["next/core-web-vitals", "eslint:recommended"],
// Using the unused imports package to autofix unused imports
"plugins": ["unused-imports"], "globals": {
"JSX": "readonly"
}
}

the “extends” array is a set of predetermined rules that have already been set by nextjs/eslint. You can read more about rules here. Then, to run the linter, type this in the terminal:

npx next lint --fix

The fix flag is to auto-fix the files that have violation(s). Some violation can be auto-fixed, some have to be done manually. To make linting easier, add this in your package.json scripts

// package.json
{
...
"scripts" : {
...
"lint": "next lint --fix"
}
...
}

Then try running yarn lint or npm run lint , the output should be the same.

If there is an error, your output should be like this

Violation on line 17:7 in _app.tsx

In every error, you will be provided with the source file of that violation, the lines:column of that error, and the rules that it violates, pretty neat right? The rules that the above image violating is no-unused-vars and there might be a lot of rules that you violates if you’re first setting up. If there are rules that you didn’t like in eslint, you can remove that rules by specifying it in the rules object in .eslintrc.json. Example of rules object in eslint:

{
...
"rules": {
"no-duplicate-case": "off", // this will turn off a rule
"no-unused-vars": "warn", // this will notify violation but not output error
"no-func-assign" : "error" // this will notify violation and outputs error
}
}

You can read more about rules here.

I also like to add the eslint-plugin-unused-import as it helps me with auto-fixing unused imports. Run yarn add --dev eslint-plugin-unused-imports then add this line to your .eslintrc.json :

// .eslintrc.json
{
...
"plugins": ["unused-imports"],
"rules": {
"unused-imports/no-unused-imports": "error"
}
...
}

Now, if you run yarn lint again it will auto fix unused imports, something that I tend to forget.

Prettier

Prettier is a code formatter that helps your code to be cleaner in case you there are codes that aren’t abiding the rules you’ve set. Prettier comes with its own default configuration, but in here I’ll share my configuration as well and why I change some of its default configuration.

Now you might ask, what is the difference between prettier and eslint? Eslint will help to show you where the error might be and prettier will help to format your code to be cleaner. So if there’s an error, prettier will not call you out, and if your code is dirty, eslint will not call you out (well, some rules might, but let’s leave it at that).

To start, add prettier and to your project:

yarn add --dev prettier 
yarn add --dev eslint-config-prettier

The second modules is to connect prettier with eslint. And then add this to your configuration files:

// package.json
{
...
"scripts": {
...
"format:all": "prettier --write ."
}
}
// .eslintrc.json
{
"extends": [... , "prettier"],
...
}

And then try running yarn format:all It should try to format all files in your directory. You may specify in which directory you want to use by modifying the --write flag. In this scenario, “.” means everything in this directory (except for hidden files). Try changing the . to src/* and see that it will only format the source folder.

Now, when your codebase is large, then formatting all files might not be a good solution. If you’re using macOS or ubuntu or similar unix system, you can add this to scripts to only format the files you’ve changed in git staging:

"format:staged": "prettier --write $(git diff --staged --name-only --diff-filter d | xargs)"

To modify prettier default configuration, create .prettierrc file in your base directory and add this configuration:

{
"trailingComma": "none",
"tabWidth": 2,
"semi": true,
"singleQuote": false,
"printWidth": 80
}

Well, this is my personal configuration, you may change it as you like. You can see more about prettier configuration here.

Also, like .gitignore , you can create .prettierignore to ignore some files. My .prettierignore looks like this:

.prettierignore
public/
.gitignore
.husky/

Husky

Husky helps you to install pre-commit hooks. Pre-commit hooks means that every time you do git commit, there will be some actions that will run to ensure that your code is good to be commited. Combined with the knowledges earlier, adding linting and formatting to a pre-commit hooks will help us to lint and format whenever we want to add changes and it’ll help because it stops the commit if there’s a violation that cannot be autofixed by eslint. On another note, husky can also be used for various things like testing before commits, logging, testing builds, etc.

To install it, run:

yarn add --dev husky# create a prepare script that will be run
# when you run `yarn install`
npm set-script prepare "husky install"
yarn prepare
# create the pre-commit hook, change yarn format:staged
# to yarn format:all if it's not working
npx husky add .husky/pre-commit "yarn format:staged\nyarn lint"

Now, every time you commits a change, it will format and lint your files! If somehow your pre-commit is not working, change the content of .husky/pre-commit file into this:

... // configurations, might be different on different machineyarn format:staged
yarn lint

That’s it! All done. I hope this helps you if you’re new into nextjs / programming with npm. Any suggestions to make this article to be a better one will be appreciated. Thanks for reading!

--

--

Mario Gunawan

I'm a passionate mobile / web developer. Writing articles about software development, mainly about flutter and react.