Configure ESLint, Prettier, Husky, lint-staged Properly for Next.js
If you choosed TypeScript
and ESLint
during Next.js CLI, then this article is for you to setup Prettier, Husky, lint-staged properly to proceed ahead and great project structure. If you work with other developer or want to maintain the project in future, then this is a must-do for Next.js project
Packages Install
npm install -D eslint eslint-config-next eslint-config-prettier eslint-plugin-prettier prettier prettier-plugin-tailwindcss eslint-plugin-tailwindcss @typescript-eslint/eslint-plugin @typescript-eslint/parser husky lint-staged
eslint
: The pluggable linting utility for JavaScript and JSX. ESLint is an open source project that helps you find and fix problems with your JavaScript code.eslint-config-next
: This package provides an ESLint configuration optimized for Next.js projects, ensuring adherence to Next.js best practices and conventions.eslint-config-prettier
: Disables ESLint rules that conflict with Prettier formatting, allowing Prettier to handle all code style concerns without interference.eslint-plugin-prettier
: Integrates Prettier into ESLint as a rule, enabling code to be automatically formatted by Prettier whenever ESLint runs.prettier
: A code formatter that enforces a consistent style by parsing and reformatting code according to predefined rules, ensuring readability across different projects.prettier-plugin-tailwindcss
: A Prettier plugin that automatically organizes Tailwind CSS class names in a consistent order according to Tailwind's recommendation.eslint-plugin-tailwindcss
: A ESLint plugin that automatically organizes Tailwind CSS class names in a consistent order according to Tailwind's recommendation and many more.@typescript-eslint/eslint-plugin
: Provides a set of ESLint rules specific to TypeScript, helping to catch and enforce best practices in TypeScript codebases.@typescript-eslint/parser
: An ESLint parser that allows ESLint to parse TypeScript code, enabling linting for TypeScript files.husky
: A tool that enables Git hooks, allowing commands like linting, testing, or formatting to run automatically at key stages of Git workflows, such as before committing.lint-staged
: A tool that runs linters or formatters on only the staged files in Git, ensuring that only the modified files are processed before a commit.
ESLint Config File
ESLint version > 9.0 support eslint.config.js
, So eslint.config.mjs
:
import prettier from "eslint-plugin-prettier";
import tailwindcss from "eslint-plugin-tailwindcss";
import globals from "globals";
import tsParser from "@typescript-eslint/parser";
import path from "node:path";
import { fileURLToPath } from "node:url";
import js from "@eslint/js";
import { FlatCompat } from "@eslint/eslintrc";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});
const eslintConfig = [
...compat.extends(
"next/core-web-vitals",
"next/typescript",
"eslint:recommended",
"plugin:@next/next/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
"plugin:tailwindcss/recommended",
),
{
plugins: {
prettier,
tailwindcss,
},
languageOptions: {
globals: {
...globals.browser,
...globals.node,
},
parser: tsParser,
ecmaVersion: 12,
sourceType: "module",
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
},
rules: {
"@typescript-eslint/no-explicit-any": "off",
"react/react-in-jsx-scope": "off",
"prettier/prettier": [
"error",
{
endOfLine: "auto",
},
],
},
},
];
export default eslintConfig;
Previous: eslintrc.json
:
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"next/core-web-vitals",
"next/typescript",
"eslint:recommended",
"plugin:@next/next/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
"plugin:tailwindcss/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"prettier"
],
"rules": {
"@typescript-eslint/no-explicit-any": "off",
"prettier/prettier": [
"error",
{
"endOfLine": "auto"
}
],
"react/react-in-jsx-scope": "off"
}
}
Prettier Config File
Newer: prettier.config.mjs
:
// prettier.config.js, .prettierrc.js, prettier.config.mjs, or .prettierrc.mjs
/**
* @see https://prettier.io/docs/en/configuration.html
* @type {import("prettier").Config}
*/
const config = {
trailingComma: "es5",
tabWidth: 2,
semi: true,
singleQuote: false,
bracketSpacing: true,
arrowParens: "always",
jsxSingleQuote: false,
bracketSameLine: false,
endOfLine: "lf",
plugins: ["prettier-plugin-tailwindcss"],
printWidth: 80,
experimentalTernaries: false,
tailwindConfig: "tailwind.config.ts",
tailwindEntryPoint: "tailwind.config.ts",
quoteProps: "as-needed",
proseWrap: "always",
htmlWhitespaceSensitivity: "css",
embeddedLanguageFormatting: "auto",
useTabs: false,
requirePragma: false,
insertPragma: false,
vueIndentScriptAndStyle: false,
singleAttributePerLine: true,
};
export default config;
prettierrc.json
:
{
"printWidth": 80,
"useTabs": false,
"tabWidth": 2,
"trailingComma": "es5",
"semi": true,
"singleQuote": false,
"bracketSpacing": true,
"arrowParens": "always",
"jsxSingleQuote": false,
"bracketSameLine": false,
"endOfLine": "lf",
"plugins": ["prettier-plugin-tailwindcss"]
}
Husky Configurations
Husky
has been installed before during installations.
npx husky init
It creates a .husky/
folder where the Git hooks will reside and the .husky
folder contains a file named “pre-commit“.
This will also add a new script in your package.json
file:
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"prepare": "husky",
},
If not added, then please manually add this:
"prepare": "husky",
Add Pre-Commit Hooks:
Add necessary commands to this .husky/pre-commit
file.
npx lint-staged
This will configure Husky.
Lint-staged Configurations
Next, configure lint-staged
in your package.json
same block as scripts
to specify that ESLint and Prettier should run only on staged files. Add the following configuration:
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix './src/**/*.{js,jsx,ts,tsx}'",
"prettier --write './src/**/*.{js,jsx,ts,tsx,css}'"
]
}
This configuration ensures that ESLint will fix any linting issues, and Prettier will format files before they are committed.
Update package.json
Scripts
Add these to your scripts list of package.json
:
"format": "prettier --check './src/**/*.{js,jsx,ts,tsx,css}'",
"format:fix": "prettier --write './src/**/*.{js,jsx,ts,tsx,css}'",
"lint:fix": "eslint --fix './src/**/*.{js,jsx,ts,tsx}'"
Now the script section of package.json
will look like:
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"prepare": "husky",
"format": "prettier --check './src/**/*.{js,jsx,ts,tsx,css}'",
"format:fix": "prettier --write './src/**/*.{js,jsx,ts,tsx,css}'",
"lint:fix": "eslint --fix './src/**/*.{js,jsx,ts,tsx}'"
},
Conclusion
This article offers a detailed setup guide for integrating Prettier, Husky, and lint-staged into a Next.js project using TypeScript and ESLint. It provides step-by-step instructions on installing the required packages, configuring ESLint and Prettier, setting up Husky for Git hooks, and configuring lint-staged to maintain code quality before committing changes. Furthermore, it updates project scripts for formatting and linting, ensuring a consistent and maintainable codebase when collaborating with other developers.
Subscribe to my newsletter
Read articles from J.A. Shezan directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
J.A. Shezan
J.A. Shezan
Shezan loves technology who is currently studying Computer Science and Engineering. He codes frontend & backend of a website. He also does penetration testing on web apps.