Pre-commit hook setup with Husky and lint-staged. Use when configuring git hooks.
This skill inherits all available tools. When active, it can use any tool Claude has access to.
This skill covers pre-commit hook configuration with Husky and lint-staged.
Use this skill when:
FAIL FAST - Catch issues before they enter the repository. Pre-commit hooks are the first line of defense.
npm install -D husky lint-staged
npx husky init
project/
├── .husky/
│ ├── _/
│ │ └── husky.sh
│ └── pre-commit
├── package.json
└── ...
{
"scripts": {
"prepare": "husky"
},
"lint-staged": {
"*.{ts,tsx}": [
"biome check --write",
"biome format --write"
],
"*.{js,jsx}": [
"biome check --write",
"biome format --write"
],
"*.{json,md}": [
"biome format --write"
]
}
}
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
npm run type-check
{
"lint-staged": {
"*.ts": "command"
}
}
{
"lint-staged": {
"*.ts": [
"biome check --write",
"biome format --write"
]
}
}
{
"lint-staged": {
"src/**/*.ts": "biome check --write",
"*.{json,md}": "biome format --write",
"!dist/**": "biome check"
}
}
{
"lint-staged": {
"*.{ts,tsx,js,jsx}": [
"biome check --write --no-errors-on-unmatched"
],
"*.{json,md}": [
"biome format --write --no-errors-on-unmatched"
]
}
}
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
npm run type-check
{
"lint-staged": {
"*.{ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{js,jsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md,css}": [
"prettier --write"
]
}
}
{
"lint-staged": {
"*.ts": [
"biome check --write",
"vitest related --run"
]
}
}
# .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
# Skip hooks for CI commits
if [ "$SKIP_HOOKS" = "1" ]; then
exit 0
fi
npx lint-staged
npm run type-check
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
# Only run on feature branches
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [ "$BRANCH" = "main" ]; then
echo "Running full validation on main..."
npm run validate
else
npx lint-staged
fi
# .husky/commit-msg
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx commitlint --edit $1
npm install -D @commitlint/cli @commitlint/config-conventional
// commitlint.config.js
export default {
extends: ['@commitlint/config-conventional'],
};
# .husky/pre-push
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run validate
npm run test:coverage
# Reinstall hooks
npx husky install
# Make hook executable
chmod +x .husky/pre-commit
# Skip hooks for one commit
git commit --no-verify -m "WIP: skip hooks"
SKIP_HOOKS=1 git commit -m "Skip hooks"
# Not recommended for regular use!
# Verbose output
npx lint-staged --debug
# Use cross-platform shebang
#!/usr/bin/env sh
# Or use node for complex scripts
#!/usr/bin/env node
# .github/workflows/ci.yml
- name: Install dependencies
run: npm ci
# npm ci runs "prepare" script which installs husky
# CI environments typically don't need hooks
# npm ci doesn't run prepare by default in CI
{
"lint-staged": {
"*.{ts,tsx}": [
"biome check --write --no-errors-on-unmatched"
]
}
}
Avoid: