Skip to content

Upgrading Husky from v8 to v9

Posted on:October 9, 2025 at 12:39 PM

Yancy Min (https://unsplash.com/@yancymin?utm_source=templater_proxy&utm_medium=referral) on Unsplash

Table of contents

Open Table of contents

TL;DR

If your project is already on Husky v8, upgrading to v9 mainly involves updating the package, ensuring your hook scripts follow the new .husky/ directory structure, and removing deprecated configurations from package.json.

Note: I am using npm as package manager in this example but the steps are the same for other package managers as well.

# Quick upgrade steps
$ npm install husky@^9 --save-dev
$ npx husky

# Remove old package.json hook configs if any, and create new hook files
$ rm -rf .husky/pre-commit .husky/pre-push .husky/commit-msg
$ echo "npm run lint-staged" > .husky/pre-commit
$ echo "npm test" > .husky/pre-push
$ echo "npm run commitlint" > .husky/commit-msg
$ chmod +x .husky/*
# the scripts that we are executing in the hooks should be avaialble in package.json scripts

Key Benefits: Improved Performance, Smaller Footprint, Better Shell Script Handling, Modern Architecture.

Introduction

Husky is the go-to tool for managing Git hooks in JavaScript and TypeScript projects. It allows teams to automate code checks (linting, testing, formatting) before commits or pushes, helping maintain clean and consistent repositories.

Why upgrade?

Here are the key benefits of moving from v8 to v9:

  • Improved Performance — v9 offers faster hook execution
  • Smaller Footprint — Reduced installation size. Just 2 kB (📦 gzipped) with no dependencies
  • Better Shell Script Handling — More reliable script execution. no more crashing due to different shell implementations
  • Modern Architecture — Aligned with current best practices

Migration Steps

1. Update Husky

$ npm install husky@^9 --save-dev
$ npx husky --version  # Verify installation

2. Update package.json

Remove the old husky configuration and update the prepare script:

{
  "scripts": {
    "prepare": "husky",
    "lint-staged": "lint-staged",
    "test": "test",
    "commitlint": "commitlint"
  }
  // Remove any "husky" object with hooks
}

3. Create Hook Files

Replace old JSON configuration with individual script files:

$ echo "npm run lint-staged" > .husky/pre-commit
$ echo "npm test" > .husky/pre-push
$ echo "npm run commitlint --edit \$1" > .husky/commit-msg
$ chmod +x .husky/*

4. Test Your Setup

$ git commit -m "test: husky v9 migration"

If hooks run successfully, you’re done!

Before vs After

Husky v8 (Old):

{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "pre-push": "npm test"
    }
  }
}

Husky v9 (New):

# .husky/pre-commit
npm run lint-staged

# .husky/pre-push
npm test

Key Changes:

  • No more JSON configuration in package.json
  • Individual script files in .husky/ directory
  • Simpler and more maintainable

Troubleshooting

IssueFix
Hooks not runningRun npx husky and chmod +x .husky/*
Permission deniedchmod +x .husky/*
Old config still loadedRemove "husky" object from package.json

Conclusion

Upgrading Husky from version 8 to version 9 is straightforward and brings performance improvements, a smaller footprint, and improved reliability. The new file-based approach is cleaner and easier to maintain than the old JSON configuration.

The migration takes just a few minutes but ensures your project stays modern and compatible with current JavaScript tooling standards.