With the release of Next.js 16 and the latest ESLint updates, setting up a clean and consistent development workflow has become even smoother. In this article, we’ll walk through how to configure ESLint, Prettier, Husky, and lint-staged in a Next.js 16 project to maintain high code quality and ensure a seamless developer experience.
Why Use ESLint, Prettier, Husky, and lint-staged?
Maintaining clean and consistent code is crucial in any project, and that’s where these tools come in:
ESLint: helps catch common bugs and enforces coding standards, keeping your codebase error-free and consistent.
Prettier: takes care of formatting automatically, so your code always looks neat and follows a uniform style.
Husky: lets you run scripts (like linting or formatting) before committing changes, ensuring only clean code gets pushed.
lint-staged: works alongside Husky to run these checks only on files that are staged for commit — making the process faster and more efficient.
Step 1: Create a Next.js Project
create a new Next.js project by running the following command:
npx create-next-app@latest
On installation, you’ll see the following prompts:
What is your project named? next-app
Would you like to use TypeScript? No / Yes  --- Yes 
Would you like to use ESLint? No / Yes --- Yes
Would you like to use Tailwind CSS? No / Yes --- Yes
Would you like to use `src/` directory? No / Yes --- Yes
Would you like to use App Router? (recommended) No / Yes --- Yes
Would you like to customize the default import alias (@/*)? No / Yes --- No
What import alias would you like configured? @/*
Once you complete the setup prompts, create-next-app will automatically generate a new folder using your chosen project name and initialize the project structure inside it.
Step 2: Install Dependencies
npm install --save-dev eslint eslint-config-next eslint-config-prettier husky prettier lint-staged
Step 3: Create Prettier Configurations
Create an Prettier configuration file (prettier.config.js) and a Prettier ignore file (.prettierignore):
prettier.config.js:
The prettier.config.js file defines your Prettier formatting rules — it’s where you set your code style preferences to keep your project clean and consistent.
module.exports = {
  semi: true,
  singleQuote: true,
  trailingComma: 'es5',
  tabWidth: 2,
  printWidth: 80,
};
semi: true – Ensures semicolons are added at the end of every statement for cleaner syntax.
singleQuote: true – Uses single quotes (' ') instead of double quotes (" ").
trailingComma: 'es5' – Adds trailing commas where valid in ES5 (like in objects, arrays, etc.) to make code diffs cleaner.
tabWidth: 2 – Sets indentation to 2 spaces for consistent and readable code.
printWidth: 80 – Wraps lines that exceed 80 characters to maintain readability.
.prettierignore
The .prettierignore file tells Prettier which files or folders to skip during code formatting.
It works just like a .gitignore file — you can list specific files, directories, or file patterns that you don’t want Prettier to format.
.next
.cache
package-lock.json
public
node_modules
next-env.d.ts
next.config.ts
yarn.lock
Step 4: Create ESLint Configurations
Create an ESLint configuration file (eslint.config.mjs) :
eslint.config.mjs
The eslint.config.mjs file defines rules and settings for ESLint, a tool that helps you find and fix problems in your JavaScript or TypeScript code.
import { defineConfig, globalIgnores } from 'eslint/config';
import nextVitals from 'eslint-config-next/core-web-vitals';
import prettier from 'eslint-config-prettier/flat';
const eslintConfig = defineConfig([
  ...nextVitals,
  prettier,
  {
    rules: {
      // Add custom rules
    },
  },
  globalIgnores([
    '.next/**',
    'out/**',
    'build/**',
    'next-env.d.ts',
    'node_modules/**',
  ]),
]);
export default eslintConfig;
defineConfig – Used to define ESLint configuration in a structured way.
globalIgnores – Specifies files and folders ESLint should ignore.
nextVitals – Imports Next.js Core Web Vitals rules for better performance and accessibility.
...nextVitals – Loads Next.js-specific ESLint settings focused on performance, accessibility, and best practices.
prettier – Ensures that Prettier’s formatting rules override ESLint’s style-related rules to prevent conflicts.
rules – A section where you can add custom ESLint rules to enforce specific coding styles.
globalIgnores([...]) - Excludes specific files and folders from linting to improve performance and avoid unnecessary warnings:
Step 5: Create Husky Configurations
Create an Husky configuration file (.huskyrc):
.huskyrc
The .huskyrc file is used to configure Git hooks with the help of Husky — a tool that makes it easy to manage and automate Git hooks in your project.
Git hooks are scripts that run automatically at specific stages of the Git workflow, such as before committing (pre-commit) or before pushing (pre-push), helping enforce code quality and consistency.
{
    "hooks": {
      "pre-commit": "lint-staged"
    }
}
I have defined a single Git hook: pre-commit. This hook is set to run the lint-staged command before each commit. Here’s a breakdown:
pre-commit: This is the name of the Git hook. It corresponds to the hook that runs just before a commit is made.
lint-staged: This is the command that will be executed when the pre-commit hook is triggered. lint-staged is a tool that runs linters (code style checkers, etc.) on files that are staged for the commit.
And to initialize the our pre-commit hooks run:
npx husky init
Step 6: Add Scripts to package.json
Add scripts to your package.json:
"scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "eslint .",
    "lint:fix": "eslint . --fix",
    "format": "prettier --write .",
    "check-format": "prettier --check .",
    "check-types": "tsc --pretty --noEmit",
    "prepare": "husky"
  },
Conclusion:
By setting up ESLint, Prettier, Husky, and lint-staged in your Next.js project, you ensure a consistent code style and catch potential issues early in the development process. This leads to cleaner code and a more efficient and collaborative development workflow. Happy coding with Next.js!
 

 
    
Top comments (0)