In modern software development, maintaining code quality isn't just a nice to have it's a essential. As teams grow and codebases expand, ensuring consistent code standards, preventing bugs, and maintaining a clean commit history becomes increasingly challenging. Enter Husky, a powerful tool that acts as your project's quality gatekeeper by leveraging Git hooks.
Setting Up Husky
Installation
First, let's install Husky in your project:
npm install --save-dev husky
npx husky init
This creates a .husky directory in your project root with a sample pre-commit hook. Unlike the old .git/hooks directory, this folder is version-controlled and shared with your team.
Basic Configuration
After initialization, you'll have a structure like this:
your-project/
├── .husky/
│ ├── pre-commit
│ ├── pre-push
│ └── commit-msg
├── package.json
└── ...
Each file in .husky corresponds to a Git hook.
Building Your Quality Automation Stack
1. Prettier: Consistent Code Formatting
Prettier is an opinionated code formatter that enforces consistent style across your codebase. No more debates about tabs vs. spaces or where to place semicolons.
Installation:
npm install --save-dev prettier
Configuration (.prettierrc):
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 80,
"tabWidth": 2
}
Integrate with Husky:
Create or update .husky/pre-commit:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx prettier --write --ignore-unknown "**/*"
Now every commit will be automatically formatted!
2. ESLint: Catch Bugs Before They Happen
ESLint analyzes your JavaScript/TypeScript code for potential errors, bad practices, and style violations.
Installation:
npm install --save-dev eslint
npx eslint --init
Sample Configuration (.eslintrc.json):
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"no-console": "warn",
"no-unused-vars": "error",
"prefer-const": "error"
}
}
Integrate with Husky:
Update .husky/pre-commit:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
# Run ESLint on staged files
npx eslint . --ext .js,.jsx,.ts,.tsx --fix
# Run Prettier
npx prettier --write --ignore-unknown "**/*"
# Stage any fixes
git add -A
3. lint-staged: Optimize Your Workflow
Running linters on your entire codebase before every commit is slow and unnecessary. lint-staged runs linters only on staged files, dramatically improving performance.
Installation:
npm install --save-dev lint-staged
Configuration (in package.json):
{
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,css,scss,md}": [
"prettier --write"
]
}
}
Update .husky/pre-commit:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
This is the sweet spot: fast, efficient, and only touches relevant files.
4. TypeScript Type Checking
For TypeScript projects, add type checking to your pre-commit hook:
{
"lint-staged": {
"*.{ts,tsx}": [
"tsc --noEmit",
"eslint --fix",
"prettier --write"
]
}
}
Conclusion
Husky and automated quality checks aren't about being pedantic, they're about making your team more efficient, your code more reliable, and your releases more confident. By catching issues early, you shift quality left in your development process, reducing bugs, improving collaboration, and ultimately shipping better software.
The initial setup might seem like extra work, but the return on investment is immediate. Your team will spend less time in code review bike-shedding about formatting, less time debugging preventable issues, and more time building features that matter.
Start small, add tools incrementally, and watch your code quality and team productivity soar.
Top comments (0)