Set up a Next.js project with ESLint, Prettier, Husky, and Lint Staged

Published on Feb 13, 2022

5 min read

NEXTJS

Working on a large codebase, having a consistent style guide is important. Inconsistencies can occur by using single quotes instead of double quotes, tabs instead of spaces, etc.

A pre-commit hook can address this problem. Before making a new commit, a pre-commit hook can check for types in TypeScript files, run a lint test, use prettier to format files, etc. All of this is possible by using:

  • ESLint
  • Prettier
  • Husky
  • Lint Staged

I'll share my personal and minimal configuration that I have recently started using for Next.js projects in this post.

Setting up a new Next.js project

🔗

Creating a new Next.js project with TypeScript enabled is done by running the following command from a terminal:

npx create-next-app@latest --typescript
# After the project directory is created
# Navigate inside it
cd next-typescript-config

After the project directory generated, navigate inside it.

The --typescript flag prepares the Next.js app with all the configuration required to enable and use TypeScript. In addition, it comes with a tsconfig.json file:

1{
2 "compilerOptions": {
3 "target": "es5",
4 "lib": ["dom", "dom.iterable", "esnext"],
5 "allowJs": true,
6 "skipLibCheck": true,
7 "strict": true,
8 "forceConsistentCasingInFileNames": true,
9 "noEmit": true,
10 "esModuleInterop": true,
11 "module": "esnext",
12 "moduleResolution": "node",
13 "resolveJsonModule": true,
14 "isolatedModules": true,
15 "jsx": "preserve",
16 "incremental": true
17 },
18 "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
19 "exclude": ["node_modules"]
20}

The flag also installs the required dependencies and type definitions installed as devDependencies found in the package.json file.

ESLint is already set up

🔗

Linting is a technique to check the code for syntax errors. It also allows checking for code style issues. All the checking happens based on the defined set of rules and plugins.

Since Next.js version 11, it comes with ESLint integration out-of-the-box. This means that Next.js installs devDependencies like eslint and eslint-config-next and creates an eslintrc.json file. Next.js uses the next lint command to catch ESLint errors.

The eslint-config-plugin by Next.js team contains pre-defined set of rules. You do not have to define them explicitly. These rules include some common and best practices in React ecosystem.

For example, the eslint-config-plugin uses eslint-plugin-react-hooks and eslint-plugin-react as dependencies, and the recommended set of rules from both these packages are already included. This takes care of installing the standard eslint packages for React apps in the Next.js app and then manually adding them as plugins.

Next.js ESLint plugin also includes best practices around Core Web Vitals and accessibility.

Setting up Prettier

🔗

Prettier is a code formatter that ensures that all the code files follow a consistent styling. If you are into Web development, chances are you are already using it.

ESLint rules in Next.js already come with some code formatting rules. To override them and initiate your personal prettier config, start by installing the following devDependencies:

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

To do Prettier work with ESLint, add "prettier" to the extends and the plugins array in the .eslintrc.json file.

1{
2 "extends": ["next/core-web-vitals", "prettier"],
3 "plugins": ["prettier"]
4}

In the extends array, make sure prettier is the last item so that when you define your Prettier configuration that takes precedence over other configurations that may have their way of formatting code.

You can also define the rules in this file. For example, whenever there is a code formatting issue with any of the files in my Next.js app, I like it to be exposed as a warning rather than an error.

1{
2 "extends": ["next", "next/core-web-vitals", "prettier"],
3 "plugins": ["prettier"],
4 "rules": {
5 "prettier/prettier": "warn",
6 "no-console": "warn"
7 }
8}

Create a new file .prettierrc and add a custom Prettier configuration:

1{
2 "singleQuote": true,
3 "trailingComma": "none",
4 "arrowParens": "avoid",
5 "proseWrap": "preserve",
6 "quoteProps": "as-needed",
7 "bracketSameLine": false,
8 "bracketSpacing": true,
9 "tabWidth": 2
10}

Also, add a .prettierignore file to ignore formatting on certain directories and files:

1.next
2.cache
3package-lock.json
4public
5node_modules
6next-env.d.ts
7next.config.ts
8yarn.lock

Installing Husky

🔗

Husky is a utility that allows linting and testing when committing the code.

To set it up, initially, install the package as a dev dependency:

yarn add --dev husky

To enable Husky run:

yarn husky install

In the next step, I will configure Husky's pre-commit hook after setting up lint-staged.

Setting up Lint Staged

🔗

The lint-staged package allows linting staged git files. It also checks for the changed files instead of the whole source code.

You can configure lint-staged to not lint files in markdown or json format. You can also separate ESLint checks based on a file's extension.

Create a .lintstagedrc.js file at the root of the Next.js app and add the following snippet:

1module.exports = {
2 // Type check TypeScript files
3 '**/*.(ts|tsx)': () => 'yarn tsc --noEmit',
4
5 // Lint & Prettify TS and JS files
6 '**/*.(ts|tsx|js)': filenames => [
7 `yarn eslint ${filenames.join(' ')}`,
8 `yarn prettier --write ${filenames.join(' ')}`
9 ],
10
11 // Prettify only Markdown and JSON files
12 '**/*.(md|json)': filenames => `yarn prettier --write ${filenames.join(' ')}`
13};

After setting up the lint-staged configuration, open the /.husky/pre-commit file and add the following pre-commit hook:

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
# Add the following
yarn lint-staged
# If using npm, remove above and uncomment below
# npm run lint-staged

To test it, I have modified the /pages/_app.tsx file and removed the reference of AppProps. This will return a type error when committing this file:

ss1

Conclusion

🔗

That's all for setting up ESLint, Prettier, Husky, and Lint Staged with a minimal configuration. You can expand the configuration for any tools as per your needs or modify the pre-commit hook.


More Posts

Browse all posts

Aman Mittal author

I'm a software developer and a technical writer. In this blog, I write about Technical writing, Node.js, React Native and Expo.

Currently, working at Expo. Previously, I've worked as a Developer Advocate, and Senior Content Developer with companies like Draftbit, Vercel and Crowdbotics.


Copyright ©  2019-2022 Aman Mittal · All Rights Reserved.