Guides

How to Use Husky with npm to Manage Git Hooks

Managing Git hooks manually can quickly become tedious and error-prone—especially in fast-moving JavaScript or Node.js projects. That’s where Husky offers a powerful advantage. It allows developers to automate Git hooks using familiar tools like npm and package.json.

With Husky, teams can integrate pre-commit linting, testing, and formatting directly into the Git lifecycle. This ensures clean, consistent commits and catches errors early—before they hit the main branch.

This guide explains how to use Husky with npm to streamline your Git workflow, enforce standards, and reduce friction across development environments.

What Is Husky and Why Use It with Git Hooks?

Husky is a tool that automates Git hooks in JavaScript and TypeScript projects. It helps enforce code standards before changes are committed or pushed. Developers use it to prevent bad code from entering a shared repository.

Git hooks are scripts that run automatically on specific Git events like pre-commit, commit-msg, or pre-push. By default, they exist in .git/hooks and require manual scripting. Husky abstracts this and allows developers to manage hooks with familiar tools like npm and package.json.

Husky is commonly used to run linters, formatters, tests, or validate commit messages. This ensures consistency in a codebase, especially in large or collaborative projects. Without Husky, maintaining hook logic across team members becomes error-prone and fragmented.

How Do Git Hooks Work in a Git Project?

Git hooks are executable scripts triggered during Git lifecycle events. These include pre-commit, prepare-commit-msg, commit-msg, post-commit, pre-push, among others. Each hook has a specific trigger and must be placed in .git/hooks.

Hooks are not version-controlled by default. This makes them unsuitable for team workflows unless manually synchronized. For example, if one developer writes a pre-commit hook to run ESLint, no one else on the team benefits unless the hook is manually shared.

Husky solves this by moving the hook logic into the project directory and storing it under version control. This ensures consistency across all machines using the same repository.

How Does Husky Simplify Git Hook Management?

Husky creates a .husky/ directory in your project where all hooks live. It connects each Git hook with an executable shell script that can run any command. The setup is simple and integrates directly into your development workflow using npm scripts.

Unlike native Git hooks, Husky-managed hooks are portable. You commit them into your repository, and they work out of the box for every developer. You don’t need extra tooling or manual steps.

For example, a pre-commit hook with Husky can run npm test or eslint . with just a few lines. Husky reduces friction by using shell scripts instead of Node-specific configurations, so it’s compatible with any command-line tool.

What Are the Prerequisites to Use Husky with npm?

You need an active Git repository and Node.js installed. Husky supports Node.js v12.13.0 and later, but using the latest LTS version is recommended. You also need npm or yarn, depending on your project setup.

Ensure your project is already initialized with Git using git init. Without Git, Husky won’t be able to install hooks or link them correctly.

Also, check for write permissions in the repo folder, especially in enterprise environments with locked-down permissions. Husky installs hooks directly into .git/hooks, so OS-level restrictions can cause silent failures.

How to Install Husky in a Project Using npm?

To start, install Husky as a development dependency:

npm install husky --save-dev

Then run:

npx husky install

This command creates a .husky/ directory and sets up a prepare script. You should add this prepare script to your package.json so Husky is re-installed automatically after every npm install:

"scripts": {
"prepare": "husky install"
}

Once installed, you can add hooks using the npx husky add command. The added scripts are tracked by Git, making them consistent for the whole team.

How to Configure Husky to Manage Git Hooks?

Husky creates a separate shell script for each hook inside the .husky/ directory. You can manually edit these scripts or create them using CLI commands. Each script file is linked to a Git hook.

For example, to create a pre-commit hook that runs tests:

npx husky add .husky/pre-commit "npm test"

This creates a .husky/pre-commit file with an executable script. Husky automatically links it to Git’s pre-commit lifecycle event. The command inside the file (npm test) is executed whenever you try to commit.

You can chain multiple commands using shell syntax. For example:

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run lint && npm run test

This allows conditional execution. The commit proceeds only if both commands succeed.

How to Use Husky with Lint-Staged for Efficient Hook Tasks?

Running tools on every file can be slow. lint-staged helps by running linters or formatters only on staged files. It’s often used with Husky for performance and precision.

First, install lint-staged:

npm install lint-staged --save-dev

Then configure a pre-commit hook to use it:

npx husky add .husky/pre-commit "npx lint-staged"

Define the lint-staged config in package.json:

"lint-staged": {
"*.js": "eslint --fix",
"*.ts": "eslint --fix"
}

Now, when you stage files and run git commit, only those files are linted. This reduces execution time and avoids touching unrelated code.

How to Handle Hook Errors and Debugging in Husky?

If a hook fails (non-zero exit code), Git aborts the operation. This is intentional and prevents faulty code from progressing. For example, if npm test fails in a pre-commit hook, the commit won’t happen.

To debug, use set -x inside the hook script. This prints each command before execution:

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
set -x

npm test

Also, make sure your hook scripts have the correct permissions. Use chmod +x on each .husky/* file if execution fails.

If you need to bypass hooks temporarily, use:

git commit --no-verify

But this should be used cautiously and never in CI pipelines.

How to Remove or Disable a Git Hook Created by Husky?

To remove a hook, delete its script from .husky/. For example:

rm .husky/pre-commit

To disable all hooks temporarily, comment out the husky install line in the prepare script or use Git’s native override:

HUSKY=0 git commit

To uninstall Husky entirely:

npm uninstall husky

And remove .husky/ and related scripts manually.

What Are Best Practices for Using Husky in Teams?

Version control the .husky/ directory to ensure consistent hook behavior across machines. Include it in your main branch and enforce code reviews on hook changes.

Document what each hook does in a README or a hooks.md file. This reduces confusion and helps onboard new developers.

Make sure all hook scripts are compatible with Unix and Windows shells. Avoid OS-specific commands or use cross-platform tools like cross-env.

Set executable permissions in Git to avoid silent failures on clone:

git update-index --add --chmod=+x .husky/*

What Are Common Mistakes When Using Husky with npm?

One frequent mistake is forgetting to run npx husky install after installation. This breaks the link between Git and the .husky/ directory.

Another issue is omitting the prepare script. Without it, Husky won’t re-install hooks on npm install, especially on CI environments.

Also, some developers forget that Husky scripts are shell scripts. This causes syntax errors if you write Node.js-style code instead of shell commands.

Finally, permissions issues are common on Windows and CI environments. Always verify file execution rights and avoid relying on global settings.

How to Use Husky in CI/CD Environments?

In CI/CD pipelines, hooks aren’t triggered automatically. If you want hooks to run in CI, you must call them manually in your pipeline scripts.

For example, in a GitHub Actions workflow:

- name: Run Pre-commit Hook
run: .husky/pre-commit

Also ensure that the .husky/ directory is executable and not ignored during CI builds. Add explicit chmod +x steps if needed.

In some setups, you might want to bypass hooks to speed up deployments:

HUSKY_SKIP_HOOKS=1 git push

This is useful for controlled automation, but shouldn’t be standard.

How to Upgrade from Husky v4 to v9 (or Latest)?

Husky v5+ changed its architecture. It no longer uses husky.config.js or modifies .git/hooks directly. Instead, it uses a .husky/ directory and shell scripts.

To migrate:

  1. Uninstall older Husky: npm uninstall husky
  2. Remove legacy config: delete husky.config.js or old hook files
  3. Reinstall the latest: npm install husky --save-dev
  4. Initialize: npx husky install
  5. Create hooks using npx husky add

Avoid manually editing .git/hooks—the new system maintains better isolation and control.

Husky vs Other Git Hook Managers: What Are the Differences?

ToolHook Type SupportConfig FormatLanguageVersion ControlledEase of Use
HuskyAll Git hooksShell + CLIAnyHigh
LefthookAll Git hooksYAMLAnyMedium
Pre-commitPython-focusedYAMLMostly PythonLow (for JS)
Simple-git-hooksPre-commit onlypackage.jsonJavaScriptHigh

Husky is preferred in JavaScript/TypeScript environments due to tight npm integration and simplicity.

Real-World Examples: How Developers Use Husky

Frontend teams often use Husky to run eslint and prettier on pre-commit. This ensures all staged code follows style guides.

Backend teams integrate Husky with test runners like Jest to prevent buggy commits. A failing test cancels the commit operation.

Monorepo setups use Husky in combination with tools like Lerna or Nx. It ensures that only affected packages are validated on each commit or push, improving performance and maintaining consistency.

Conclusion

Using Husky with npm transforms how developers handle Git hooks. It enables consistent JavaScript Git workflows by automating essential tasks like linting, testing, and formatting during commit or push events.

By version-controlling hooks, teams reduce manual setup and avoid configuration drift. Whether you’re maintaining a large codebase or contributing to a team project, managing Git hooks with Husky ensures code quality and speeds up development.

With minimal setup and strong community support, Husky remains one of the most efficient tools to automate Git hooks in Node.js projects.

Furqan

Well. I've been working for the past three years as a web designer and developer. I have successfully created websites for small to medium sized companies as part of my freelance career. During that time I've also completed my bachelor's in Information Technology.

Recent Posts

MiniMax-M1 vs GPT-4o vs Claude 3 Opus vs LLaMA 3 Benchmarks

MiniMax-M1 is a new open-weight large language model (456 B parameters, ~46 B active) built with hybrid…

June 22, 2025

How to Use Lefthook with npm to Manage Git Hooks

Git hooks help teams enforce code quality by automating checks at key stages like commits…

June 22, 2025

Lefthook vs Husky: Which Git Hooks Tool is Better? [2025]

Choosing the right Git hooks manager directly impacts code quality, developer experience, and CI/CD performance.…

June 22, 2025

Llama 3.1 vs GPT-4 Benchmarks

We evaluated the performance of Llama 3.1 vs GPT-4 models on over 150 benchmark datasets…

July 24, 2024

Transforming Manufacturing with Industrial IoT Solutions and Machine Learning

The manufacturing industry is undergoing a significant transformation with the advent of Industrial IoT Solutions.…

July 6, 2024

How can IT Professionals use ChatGPT?

If you're reading this, you must have heard the buzz about ChatGPT and its incredible…

September 2, 2023