Eliminate “Junk” Code and Standardize Commits with the Husky & lint-staged Duo

Git tutorial - IT technology blog
Git tutorial - IT technology blog

The Nightmare of “Fix Bug” and Inconsistent Coding Styles

Opening a Pull Request (PR) only to see messy indentation, single quotes (‘) here and double quotes (“) there is never a pleasant experience. Even worse is checking Git history and finding a series of meaningless commit messages like “fix”, “update”, or even “abcxyz”.

When I first started leading a team of 8, I spent at least 30 minutes every day just reminding people: “Hey, run Prettier,” or “You haven’t run Lint on this yet.” Reviewing logic became a chore because these trivial errors buried all the important changes.

Don’t expect too much from self-discipline, as it often inversely correlates with deadlines. The best way is automation. If the code isn’t up to standard or the commit format is wrong, Git should reject the commit command immediately. This is where Husky and lint-staged shine.

Quick Start: 5-Minute Setup

Below are the steps for a Node.js project (React, Vue, NestJS…). With just a few commands, you’ll have a dedicated “gatekeeper.”

Step 1: Initialize Husky

Husky helps us work with Git hooks without touching complex hidden files.

npx husky init && npm install

This command will create a .husky folder and add a prepare script to your package.json.

Step 2: Install lint-staged

Instead of scanning the entire project (which is very slow), lint-staged only checks the files you just changed.

npm install --save-dev lint-staged

Step 3: Configure Check Rules

Add the following configuration to package.json to define automatic commands:

{
  "scripts": {
    "lint": "eslint . --ext .ts,.tsx",
    "format": "prettier --write"
  },
  "lint-staged": {
    "*.{ts,tsx,js,jsx}": [
      "eslint --fix",
      "prettier --write"
    ]
  }
}

Step 4: Activate the Hook

Open the file .husky/pre-commit and replace the content with:

npx lint-staged

From now on, every time you type git commit, Husky will call lint-staged. It automatically fixes formatting errors and checks linting. If it detects an error that cannot be fixed automatically, it will block the commit process.

Why Use Both Husky and lint-staged?

Many people wonder: “Can’t I just use Husky?”. The answer lies in performance. For a large project with 1,000 files, running lint on everything takes about 2 minutes. With lint-staged, this drops to 2 seconds because it only scans the 2-3 files you just git add-ed. The commit experience feels much smoother.

Advanced: Standardizing Commit Messages

To make your Git history look professional like open-source libraries (e.g., feat: add login), install commitlint.

Quick Setup

npm install --save-dev @commitlint/config-conventional @commitlint/cli

Create Configuration File

Create a commitlint.config.js file in the root directory:

module.exports = { extends: ['@commitlint/config-conventional'] };

Add Message Check Hook

echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg

If you try to commit with the content “done”, Git will throw an error: subject may not be empty. You are forced to write in the correct type: description format.

Practical Experience When Implementing

After applying this toolset to many projects, I’ve drawn 3 important notes:

  • Loosen rules at first: Don’t enable too many strict ESLint rules immediately. Start with Prettier for consistent formatting, then tighten code logic over time.
  • “Bypassing” rights: In case of emergency bug fixes on production, you can use the --no-verify flag to skip checks. However, don’t abuse it.
  • Team synchronization: Remind everyone to run npm install after you update Husky. Otherwise, the hooks won’t work on their machines.

Since adopting this workflow, the number of merge conflicts due to formatting differences in my team has dropped by 80%. Reviewers are also more relaxed because they can focus on programming logic instead of nitpicking every comma.

A Small Tip for You

Want to ensure code pushed to the server always runs correctly? Create a pre-push hook to run Unit Tests:

echo "npm test" > .husky/pre-push

This helps reduce the load on the CI/CD system and ensures you never “break” the shared environment.

Configuring Husky and lint-staged only takes 5 minutes, but the benefits are huge. Try applying it to your personal projects or suggest it to your team at the next meeting!

Share: