This guide provides step-by-step instructions to set up Husky with pre-commit hooks, commit message validation, and code quality checks for both frontend and backend projects.
# Navigate to your frontend project
cd your-frontend-project
# Install Husky and related packages
npm install --save-dev husky @commitlint/cli @commitlint/config-conventional lint-staged prettier prettier-plugin-tailwindcss# Initialize Husky
npx husky initAdd the following scripts to your package.json:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint",
"lint:fix": "eslint --fix",
"format": "prettier --write .",
"prepare": "husky",
"type-check": "tsc --pretty --noEmit"
},
"lint-staged": {
"*.{ts,tsx,js,jsx}": ["eslint --fix", "prettier --write"]
}
}Create .commitlintrc.ts in your project root:
import type { UserConfig } from '@commitlint/types';
const commitConfig: UserConfig = {
extends: ['@commitlint/config-conventional'],
};
module.exports = commitConfig;Create .prettierrc in your project root:
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"plugins": ["prettier-plugin-tailwindcss"]
}Note: The prettier-plugin-tailwindcss plugin automatically sorts Tailwind CSS classes according to the recommended class order. Make sure you have a tailwind.config.js file in your project root for the plugin to work properly.
Replace the content of .husky/pre-commit with:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
echo '๐๏ธ๐ท Styling, testing and building your project before committing'
# Check staged files
npx lint-staged ||
(
echo '๐คข๐คฎ๐คข๐คฎ Its FOKING RAW - Your styling looks disgusting. ๐คข๐คฎ๐คข๐คฎ
Staged files Check Failed. Run npm run format, add changes and try commit again.';
false;
)
# Check Prettier standards
npm run format ||
(
echo '๐คข๐คฎ๐คข๐คฎ Its FOKING RAW - Your styling looks disgusting. ๐คข๐คฎ๐คข๐คฎ
Prettier Check Failed. Run npm run format, add changes and try commit again.';
false;
)
# Check ESLint Standards
npm run lint ||
(
echo '๐ค๐๐๐ค Get that weak s**t out of here! ๐ค๐๐๐ค
ESLint Check Failed. Make the required changes listed above, add changes and try to commit again.'
false;
)
# Check tsconfig standards
npm run type-check ||
(
echo '๐คก๐โ๐คก Failed Type check. ๐คก๐โ๐คก
Are you seriously trying to write TypeScript like JavaScript?'
false;
)
echo '๐ค๐ค๐ค๐ค... Alright... Code looks good to me... trying to build now. ๐ค๐ค๐ค๐ค'
echo 'โ
โ
โ
โ
You win this time... I am committing this now. โ
โ
โ
โ
'Create .husky/commit-msg with:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx commitlint --config .commitlintrc.ts --edit $1 ||
(
echo 'โ Commit message format is incorrect. Please follow the conventional commit format.';
false;
)chmod +x .husky/pre-commit .husky/commit-msg# Navigate to your backend project
cd your-backend-project
# Install Husky and related packages
npm install --save-dev husky @commitlint/cli @commitlint/config-conventional lint-staged prettier
npm i prettier-plugin-tailwindcss# Initialize Husky
npx husky initAdd the following scripts to your package.json:
{
"scripts": {
"dev": "nodemon src/server.ts",
"build": "tsc",
"start": "node dist/server.js",
"lint": "eslint src/**/*.ts",
"lint:fix": "eslint src/**/*.ts --fix",
"format": "prettier --write src/**/*.ts",
"prepare": "husky",
"type-check": "tsc --noEmit"
},
"lint-staged": {
"src/**/*.{ts,js}": ["eslint --fix", "prettier --write"]
}
}Create .commitlintrc.ts in your project root:
import type { UserConfig } from '@commitlint/types';
const commitConfig: UserConfig = {
extends: ['@commitlint/config-conventional'],
};
module.exports = commitConfig;Create .prettierrc in your project root:
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 80,
"tabWidth": 2,
"useTabs": false
}Replace the content of .husky/pre-commit with:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
echo '๐๏ธ๐ท Styling, testing and building your project before committing'
# Check staged files
npx lint-staged ||
(
echo '๐คข๐คฎ๐คข๐คฎ Its FOKING RAW - Your styling looks disgusting. ๐คข๐คฎ๐คข๐คฎ
Staged files Check Failed. Run npm run format, add changes and try commit again.';
false;
)
# Check Prettier standards
npm run format ||
(
echo '๐คข๐คฎ๐คข๐คฎ Its FOKING RAW - Your styling looks disgusting. ๐คข๐คฎ๐คข๐คฎ
Prettier Check Failed. Run npm run format, add changes and try commit again.';
false;
)
# Check ESLint Standards
npm run lint ||
(
echo '๐ค๐๐๐ค Get that weak s**t out of here! ๐ค๐๐๐ค
ESLint Check Failed. Make the required changes listed above, add changes and try to commit again.'
false;
)
# Check tsconfig standards
npm run type-check ||
(
echo '๐คก๐โ๐คก Failed Type check. ๐คก๐โ๐คก
Are you seriously trying to write TypeScript like JavaScript?'
false;
)
echo '๐ค๐ค๐ค๐ค... Alright... Code looks good to me... trying to build now. ๐ค๐ค๐ค๐ค'
echo 'โ
โ
โ
โ
You win this time... I am committing this now. โ
โ
โ
โ
'Create .husky/commit-msg with:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx commitlint --config .commitlintrc.ts --edit $1 ||
(
echo 'โ Commit message format is incorrect. Please follow the conventional commit format.';
false;
)chmod +x .husky/pre-commit .husky/commit-msg- Make some changes to your code
- Stage the changes:
git add . - Try to commit:
git commit -m "test: testing husky setup"
Try committing with an invalid message:
git commit -m "invalid message"This should fail. Use conventional commit format:
git commit -m "feat: add new feature"
git commit -m "fix: resolve bug in authentication"
git commit -m "docs: update README"feat:- New featuresfix:- Bug fixesdocs:- Documentation changesstyle:- Code style changes (formatting, etc.)refactor:- Code refactoringtest:- Adding or updating testschore:- Maintenance tasks
-
Husky hooks not running:
# Reinstall husky npm uninstall husky npm install --save-dev husky npx husky init -
Permission denied errors:
chmod +x .husky/pre-commit .husky/commit-msg
-
ESLint or Prettier errors:
# Fix linting issues npm run lint:fix # Format code npm run format
-
TypeScript errors:
# Check types npm run type-check
# Skip pre-commit hooks (NOT RECOMMENDED)
git commit -m "emergency fix" --no-verify
# Skip commit message validation (NOT RECOMMENDED)
git commit -m "emergency fix" --no-verify# Update to latest version
npm update husky
# Reinstall hooks
npx husky initIssue: Tailwind classes not being sorted
-
Check if prettier-plugin-tailwindcss is installed:
npm list prettier-plugin-tailwindcss
-
Ensure the plugin is in your .prettierrc:
{ "plugins": ["prettier-plugin-tailwindcss"] } -
Make sure you have tailwind.config.js in your project root:
# If missing, create it npx tailwindcss init -
Test the plugin manually:
# Format a specific file npx prettier --write "src/components/YourComponent.tsx" # Check if classes are being sorted echo '<div className="text-red-500 bg-blue-200 p-4 m-2"></div>' | npx prettier --parser html --stdin-filepath test.html
-
Clear Prettier cache:
npx prettier --cache-location=node_modules/.cache/prettier/.prettier-cache --write .
Issue: Plugin conflicts with other Prettier plugins
Make sure prettier-plugin-tailwindcss is the last plugin in your plugins array:
{
"plugins": ["@trivago/prettier-plugin-sort-imports", "prettier-plugin-tailwindcss"]
}cd your-frontend-project
npm install --save-dev husky @commitlint/cli @commitlint/config-conventional lint-staged prettier
npx husky init
npm i prettier-plugin-tailwindcss
# Then follow configuration steps abovecd your-frontend-project
npm install --save-dev husky @commitlint/cli @commitlint/config-conventional lint-staged prettier prettier-plugin-tailwindcss
npx husky init
# Then follow configuration steps aboveNote: This setup ensures code quality, consistent formatting, and conventional commit messages across your entire project. The hooks will run automatically before each commit, preventing bad code from entering your repository.