We recently standardized on Husky across our platform team's ~50 service repositories, replacing a mix of ad-hoc scripts, pre-commit frameworks, and IDE-based hooks. The goal was to enforce consistent commit linting and automated formatting before any code reaches CI. The implementation was straightforward, but the operational learnings were significant.
Our base configuration is minimal, focusing on commit message linting with `commitlint` and code formatting with `prettier`. We enforce this via a shared npm package that teams install as a dev dependency.
```json
// package.json excerpt in our shared config
{
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
"pre-commit": "pretty-quick --staged"
}
}
}
```
The primary challenge wasn't the tool itself, but managing its presence across dozens of autonomous teams. We learned that simply adding `husky` and a config isn't enough. The hooks must be installed via `husky install`, which we automated in a `postinstall` script. However, this caused issues in Docker build contexts and for engineers who use `--ignore-scripts`. We moved the installation trigger to an npm `prepare` script, which runs after `npm install` but not during CI container builds, as CI typically runs with `npm ci` which skips lifecycle scripts.
Another key insight was the performance impact on `git` operations. A `pre-commit` hook that runs linting on the entire project introduces a noticeable delay. We strictly limit hooks to operations on staged files only, as shown with `pretty-quick --staged`. For linting, we opted to run it in CI rather than pre-commit to avoid slowing down the local workflow, accepting that feedback loop is slightly later but more comprehensive.
The most persistent issue was "hook bypassing." Engineers would use `git commit --no-verify` under time pressure, pushing unlinted code. We addressed this by making the CI pipeline a hard gate: it runs the same linting and formatting checks, failing the build and providing clear instructions to run the local hooks. This created the necessary cultural shift—bypassing the hook just meant a slower feedback cycle and a blocked PR.
Ultimately, Husky proved to be an effective lightweight orchestrator, but its success depends entirely on the surrounding process. The hook logic must be fast, the installation must be foolproof, and CI must be the ultimate enforcer. The tool doesn't solve discipline; it just makes disciplined practices the path of least resistance.
—J
—J