Ensuring clean and consistent code is crucial for any Node.js project. This blog dives into a practical approach to achieve that by integrating ESLint with Husky, a popular tool for managing Git hooks. Husky simplifies the process of setting up pre-commit hooks, which are scripts that run automatically before a commit is made. In this case, the pre-commit hook leverages ESLint to perform linting checks on your code. The blog guides you through setting up this workflow, enabling you to automatically catch style and formatting issues before every commit. With this setup, you can streamline your development process and maintain a high level of code quality throughout your project.
Assuming that you already have cloned your Nodejs project, to integrate ESLint with a pre-commit hook using Husky in your Node.js project, follow these steps:
Install Dependencies
You’ll need ESLint, Husky, and lint-staged. You can install them using npm or yarn. Here is how you can do it with npm:
npm install eslint husky lint-staged --save-dev
Initialize ESLint
If you haven’t already set up ESLint, you can initialize it in your project by running:
npx eslint --init
This command will guide you through a series of questions to set up ESLint according to your project’s needs.
You can also run this command directly using 'npm init @eslint/config@latest'.
Need to install the following packages:
@eslint/create-config@1.1.1
Ok to proceed? (y) y
✔ How would you like to use ESLint? · problems
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · react
✔ The React plugin doesn't officially support ESLint v9 yet. What would you like to do? · 9.x
✔ Does your project use TypeScript? · typescript
✔ Where does your code run? · browser
The config that you've selected requires the following dependencies:
eslint@9.x, globals, @eslint/js, typescript-eslint, eslint-plugin-react, @eslint/compat
✔ Would you like to install them now? · No / Yes
✔ Which package manager do you want to use? · npm
☕️Installing...
npm WARN using --force Recommended protections disabled.
Configure Husky
Starting with Husky v7, you need to configure Husky using husky commands and add hooks manually. First, initialize Husky:
npm install --save-dev husky
If you face an error message
npm ERR! ERESOLVE could not resolve
error you’re encountering when installing Husky, then follow Resolving the Conflict:Here are two approaches you can take:
1. Downgrade eslint:
This approach aligns your eslint version with the requirements of eslint-plugin-react.
Run the following command to downgrade eslint to a compatible version (e.g., 8.22.0):npm install --save-dev eslint@8.22.0
2. Use –legacy-peer-deps (Cautionary Approach):
This approach forces the installation but might lead to compatibility issues in the future. Use it with caution if downgrading isn’t feasible.
Run the following command, but be aware of potential risks:npm install --save-dev husky --legacy-peer-deps
After resolving the conflict:
Re-run the original command to install husky:
npm install --save-dev husky
Choosing the Best Approach:
- Downgrading eslint is generally the recommended approach as it ensures compatibility and avoids potential issues. Check the documentation of the other packages in your project to ensure they are compatible with eslint@8.22.0.
- Using –legacy-peer-deps should be a last resort. It might > lead to unexpected behavior or errors if the peer > dependencies are not truly compatible.
Initialize Husky
npx husky init
This will automatically configure Husky and add a basic .husky/pre-commit file (you can customize this later).
- Choose a configuration style (I recommend “JavaScript Standard Style”).
- Select the features you want to enable/disable based on your project’s needs.
This creates an .eslintrc.json
file in your project root, which defines ESLint rules.
cat eslint.config.mjs
import globals from "globals";
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";
import pluginReactConfig from "eslint-plugin-react/configs/recommended.js";
import { fixupConfigRules } from "@eslint/compat";
export default [
{languageOptions: { globals: globals.browser }},
pluginJs.configs.recommended,
...tseslint.configs.recommended,
...fixupConfigRules(pluginReactConfig),
];
Add Pre-commit Script (Optional):
It’s time to create Husky Pre-commit Hook. In your package.json, add a husky section under scripts:
{
"scripts": {
"precommit": "eslint ."
}
}
This tells Husky to run eslint . (lint all files) before every git commit.
So, your final package.json will look like:
{
"devDependencies": {
"@eslint/compat": "^1.0.1",
"@eslint/js": "^9.3.0",
"eslint": "^8.22.0",
"eslint-plugin-react": "^7.34.1",
"globals": "^15.2.0",
"husky": "^9.0.11",
"lint-staged": "^15.2.2",
"typescript-eslint": "^7.9.0"
},
"scripts": {
"prepare": "husky"
"precommit": "eslint ."
}
}
Test Pre-commit Hook
- Create a file (e.g., test.js) with intentional linting errors (like missing semicolons).
- Try to commit your changes. Husky should prevent the commit and display ESLint errors.
Conclusion
By following these steps, you ensure that your code is linted before every commit, maintaining code quality and consistency. If there are any linting errors, the commit will be blocked until they are resolved.