DEV Community

Harish Kumar
Harish Kumar

Posted on

Automating Code Quality: Git Hooks, Husky, and Lint-Staged for Streamlined Linting & Formatting

Maintaining clean, consistent code across a development team can be challenging. Despite coding guidelines, code quality can vary, especially in collaborative environments. Automated code linting and formatting help ensure that all code adheres to established quality and style standards, making the code easier to read, maintain, and scale. However, running these tools manually can be cumbersome and error-prone.

This is where Git Hooks, Husky, and Lint-Staged come in. Together, these tools allow you to automate linting and formatting every time a commit is made, ensuring only clean, high-quality code reaches the main repository. In this article, we’ll explore how to set up Husky and Lint-Staged to harness the power of Git Hooks and automate code quality checks at the commit stage.

👉 Download eBook - JavaScript: from ES2015 to ES2023


Understanding Git Hooks: The Basics

Git Hooks are scripts that trigger actions at various stages of a Git workflow. These scripts can be used to enforce standards by executing commands during specific Git events, like pre-commit (before a commit is finalized) or pre-push (before code is pushed to a remote repository). Pre-commit hooks are especially useful for enforcing code quality checks, as they run before code is committed, allowing developers to catch and fix issues early in the process.

Some common use cases for Git Hooks include:

  • Running tests to prevent broken code from being committed.
  • Enforcing proper commit message conventions.
  • Running linters to ensure code consistency and adherence to standards.

Introduction to Husky and How It Simplifies Git Hooks

While Git Hooks can be configured manually, this setup can be complex and may not integrate well across different environments. Husky simplifies this process by allowing developers to manage Git Hooks easily within a project. It abstracts away the manual configuration, offering a reliable and scalable way to add Git Hooks to projects.

Husky works by letting you define Git Hooks in your project’s package.json file, which makes setup and maintenance easier for all contributors. Here’s a quick look at how to add Husky to a project.


What is Lint-Staged and How It Complements Husky?

Lint-Staged is a tool that optimizes code linting and formatting by running these tasks only on staged files, rather than the entire codebase. This improves efficiency, especially in larger projects where linting the entire codebase would take too much time during each commit.

Using Lint-Staged with Husky enables a seamless workflow:

  1. Lint-Staged processes only the files that are currently staged for a commit.
  2. If any issues are found, the commit is halted until they’re resolved.
  3. This combination prevents low-quality code from entering the codebase while keeping the process fast.

With this setup, Husky manages the hook itself, while Lint-Staged determines which files need linting or formatting, optimizing the workflow for performance.


Setting Up Husky and Lint-Staged to Automate Linting and Formatting

Here’s a step-by-step guide to implementing Husky and Lint-Staged in a JavaScript or Node.js project.

Step 1: Install Husky

Start by installing Husky as a development dependency:

npm install husky --save-dev
Enter fullscreen mode Exit fullscreen mode

Next, initialize Husky in the project:

npx husky install
Enter fullscreen mode Exit fullscreen mode

This command creates a .husky directory where Git Hooks are stored. You can now set up specific Git Hooks, such as a pre-commit hook.

Step 2: Set Up the Pre-Commit Hook

To set up a pre-commit hook, use the following command:

npx husky add .husky/pre-commit "npm test"
Enter fullscreen mode Exit fullscreen mode

This command adds a pre-commit hook that will run npm test before each commit. You can replace npm test with other commands, like linting or formatting.

Step 3: Install Lint-Staged

Install Lint-Staged as a development dependency:

npm install lint-staged --save-dev
Enter fullscreen mode Exit fullscreen mode

Step 4: Configure Lint-Staged in package.json

In your package.json, add a lint-staged configuration. Here’s an example setup to run ESLint and Prettier:

{
  "lint-staged": {
    "*.js": ["eslint --fix", "prettier --write"]
  }
}
Enter fullscreen mode Exit fullscreen mode

This configuration applies ESLint and Prettier to any staged .js files, automatically fixing any linting or formatting issues before they are committed.

Step 5: Link Lint-Staged with Husky

Finally, update the Husky pre-commit hook to use Lint-Staged:

npx husky add .husky/pre-commit "npx lint-staged"
Enter fullscreen mode Exit fullscreen mode

Now, every time you stage and commit code, Husky triggers Lint-Staged to lint and format only the staged files, ensuring that only clean, consistent code is committed.


Example Workflow: A Pre-commit Check for Code Quality

Let’s walk through an example workflow that enforces code quality during the commit process:

  1. Stage Files: You add changes to the staging area with git add.
  2. Attempt Commit: You run git commit, which triggers the Husky pre-commit hook.
  3. Lint-Staged in Action: Lint-Staged runs, identifying only the staged files for linting or formatting tasks.
  4. Fix and Commit: If there are any linting or formatting issues, the commit fails. You then review and fix the issues before reattempting the commit.

This workflow ensures code consistency at the commit stage without any manual intervention.


Troubleshooting Common Issues

Issue 1: Permission Errors with Git Hooks

On some systems, Husky’s Git Hooks may encounter permission errors. Run the following command to ensure the .husky directory has the correct permissions:

chmod ug+x .husky/*
Enter fullscreen mode Exit fullscreen mode

Issue 2: Lint-Staged Not Running as Expected

If Lint-Staged isn’t running correctly, check your package.json configuration for syntax errors. Ensure you’re specifying the correct file extensions for linting (e.g., *.js).

Issue 3: Husky Hooks Not Triggering

Make sure that Husky is installed and initialized. Running npx husky install can help resolve setup issues if the hooks aren’t triggering correctly.


Benefits and Best Practices

Key Benefits

  • Consistent Code Quality: Ensures all committed code meets linting and formatting standards.
  • Improved Team Productivity: Reduces manual checks and code review time spent on formatting.
  • Streamlined Workflow: Automates code checks, reducing the chances of low-quality code in the codebase.

Best Practices

  • Run Tests on pre-push: While linting on pre-commit is effective, running tests on pre-push can further enforce code quality.
  • Avoid Overly Strict Rules: Ensure that linting and formatting rules are agreed upon to avoid developer friction.
  • Use a .lintstagedrc File: For more complex configurations, consider a separate .lintstagedrc file for Lint-Staged setup.

Conclusion: Streamlining Code Quality with Automation

Automating code quality checks with Git Hooks, Husky, and Lint-Staged helps streamline development workflows by catching issues early in the commit process. This setup ensures that only well-linted and properly formatted code makes it to the codebase, saving time and improving overall code quality. By integrating these tools, you empower your development team to focus on building features rather than worrying about formatting and style.


👉 Download eBook - JavaScript: from ES2015 to ES2023

javascript-from-es2015-to-es2023

Top comments (0)