| name | prettier-husky |
| description | Setup Prettier for code formatting and Husky for Git hooks. Use when initializing a new project or adding code quality automation to existing projects. |
Purpose
Automate code formatting with Prettier and enforce it with Husky Git hooks. Ensures consistent code style across the team and prevents unformatted code from being committed.
When to Use
- Starting a new project
- Adding code formatting to existing project
- Enforcing code style standards
- Automating pre-commit checks
- Setting up team development workflow
Prettier Setup
Installation
npm install --save-dev prettier
yarn add --dev prettier
pnpm add -D prettier
Configuration Files
.prettierrc (JSON)
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"arrowParens": "always",
"endOfLine": "lf"
}
.prettierrc (YAML)
semi: true
trailingComma: es5
singleQuote: true
printWidth: 80
tabWidth: 2
useTabs: false
arrowParens: always
endOfLine: lf
.prettierrc.js
module.exports = {
semi: true,
trailingComma: 'es5',
singleQuote: true,
printWidth: 80,
tabWidth: 2,
useTabs: false,
arrowParens: 'always',
endOfLine: 'lf',
};
prettier.config.js
export default {
semi: true,
trailingComma: 'es5',
singleQuote: true,
printWidth: 80,
tabWidth: 2,
useTabs: false,
arrowParens: 'always',
endOfLine: 'lf',
};
.prettierignore
# Dependencies
node_modules
.pnp
.pnp.js
# Build outputs
dist
build
.next
out
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Environment files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# IDE
.vscode
.idea
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
# Other
coverage
.nyc_output
.cache
Running Prettier
npx prettier --check .
npx prettier --write .
npx prettier --write src/index.js
npx prettier --write src/
npx prettier --write "src/**/*.js"
Husky Setup
Installation
npm install --save-dev husky
yarn add --dev husky
pnpm add -D husky
npx husky init
Git Hooks Location
Husky stores hooks in .husky/ directory:
.husky/
├── pre-commit
├── commit-msg
└── ...
Pre-commit Hook (Format with Prettier)
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx prettier --write .
git add .
Pre-commit Hook (Check Prettier)
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx prettier --check .
Pre-commit Hook (Lint + Format)
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run lint
npx prettier --check .
git add .
Commit-msg Hook (Conventional Commits)
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx commitlint --edit $1
Combined Setup (Prettier + Husky)
Quick Setup Script
npm install --save-dev prettier husky lint-staged
npx husky init
echo "npx lint-staged" > .husky/pre-commit
chmod +x .husky/pre-commit
lint-staged Configuration
Install lint-staged to run Prettier only on staged files:
npm install --save-dev lint-staged
.lintstagedrc (JSON)
{
"*.{js,jsx,ts,tsx}": [
"prettier --write",
"eslint --fix"
],
"*.{json,md,yml,yaml}": [
"prettier --write"
],
"*.{css,scss,less}": [
"prettier --write"
]
}
.lintstagedrc.js
module.exports = {
'*.{js,jsx,ts,tsx}': ['prettier --write', 'eslint --fix'],
'*.{json,md,yml,yaml}': ['prettier --write'],
'*.{css,scss,less}': ['prettier --write'],
};
package.json Configuration
{
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"prettier --write",
"eslint --fix"
],
"*.{json,md,yml,yaml}": [
"prettier --write"
],
"*.{css,scss,less}": [
"prettier --write"
]
}
}
Complete package.json Setup
{
"name": "your-project",
"version": "1.0.0",
"scripts": {
"format": "prettier --write .",
"format:check": "prettier --check .",
"prepare": "husky install"
},
"devDependencies": {
"prettier": "^3.2.5",
"husky": "^9.0.11",
"lint-staged": "^15.2.0"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"prettier --write",
"eslint --fix"
],
"*.{json,md,yml,yaml}": [
"prettier --write"
]
}
}
Common Configurations
React Project
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"arrowParens": "always",
"jsxSingleQuote": false,
"endOfLine": "lf"
}
Vue Project
{
"semi": false,
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"arrowParens": "avoid",
"endOfLine": "lf"
}
TypeScript Project
{
"semi": true,
"trailingComma": "all",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"arrowParens": "always",
"endOfLine": "lf"
}
Python Project (using prettier-plugin-py)
npm install --save-dev prettier prettier-plugin-py
{
"semi": false,
"singleQuote": true,
"printWidth": 88,
"tabWidth": 4,
"useTabs": false,
"plugins": ["prettier-plugin-py"],
"overrides": [
{
"files": "*.py",
"options": {
"parser": "py"
}
}
]
}
Editor Integration
VS Code
Install Prettier extension and add to .vscode/settings.json:
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"prettier.requireConfig": true
}
JetBrains (WebStorm, IntelliJ)
Settings → Languages & Frameworks → JavaScript → Prettier
- Enable Prettier
- Set Prettier package path
- Enable "On code reformat"
Vim/Neovim
" Using coc-prettier
autocmd BufWritePre *.js,*.jsx,*.ts,*.tsx,*.json,*.md CocCommand prettier.formatFile
Common Issues
Husky Not Running
chmod +x .husky/*
npx husky init
git config core.hooksPath .husky
Prettier Not Formatting
npx prettier --version
npx prettier --find-config-path
npx prettier --write --debug file.js
lint-staged Not Running
npx lint-staged --help
npx lint-staged
git diff --name-only --cached
Best Practices
Configuration
- Commit
.prettierrc to version control
- Use
.prettierignore for generated files
- Share config across projects with
prettier-config-* packages
- Use
overrides for different file types
Git Hooks
- Keep hooks fast (run only on staged files with lint-staged)
- Separate concerns (format in pre-commit, validate in pre-push)
- Provide clear error messages
- Allow bypass with
--no-verify when needed
Team Workflow
- Agree on Prettier configuration
- Add setup to onboarding documentation
- Use editor integration for immediate feedback
- Run format check in CI pipeline
CI/CD Integration
GitHub Actions
name: Lint
on: [push, pull_request]
jobs:
prettier:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- run: pnpm install
- run: pnpm run format:check
GitLab CI
lint:
script:
- npm install
- npm run format:check
only:
- merge_requests
- main
Migration Guide
Adding to Existing Project
npm install --save-dev prettier husky lint-staged
npx husky init
echo '{"semi": true, "singleQuote": true}' > .prettierrc
cat > .prettierignore << EOF
node_modules
dist
build
.next
EOF
npx lint-staged init
echo "npx lint-staged" > .husky/pre-commit
chmod +x .husky/pre-commit
npx prettier --write .
git add .
git commit -m "chore: add prettier and husky"
Scripts
setup-prettier-husky.sh
#!/bin/bash
echo "Setting up Prettier and Husky..."
npm install --save-dev prettier husky lint-staged
npx husky init
cat > .prettierrc << 'EOF'
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"arrowParens": "always",
"endOfLine": "lf"
}
EOF
cat > .prettierignore << 'EOF'
node_modules
dist
build
.next
coverage
.env
*.log
EOF
cat > .lintstagedrc << 'EOF'
{
"*.{js,jsx,ts,tsx}": ["prettier --write"],
"*.{json,md,yml,yaml}": ["prettier --write"],
"*.{css,scss,less}": ["prettier --write"]
}
EOF
echo "npx lint-staged" > .husky/pre-commit
chmod +x .husky/pre-commit
npx prettier --write .
echo "Done! Prettier and Husky are configured."
format.js
const { execSync } = require('child_process');
const path = require('path');
const prettier = path.join(
__dirname,
'node_modules',
'.bin',
'prettier'
);
try {
execSync(`${prettier} --write .`, { stdio: 'inherit' });
console.log('Formatted successfully!');
} catch (error) {
console.error('Formatting failed:', error);
process.exit(1);
}