Team Code Consistency: Automate Formatting with Pre-commit Hooks
Picture this: Five developers working on the same React project. Alice uses tabs, Bob prefers spaces. Charlie adds semicolons everywhere, while Diana never uses them. Every pull request becomes a nightmare of formatting changes, making actual code changes hard to spot. Code reviews turn into style debates instead of focusing on logic.
Sound familiar?
This is where automated pre-commit hooks save the day. In this guide, you'll learn how to set up a system that enforces consistent code style across your entire team—automatically. No more style debates, no more formatting-only commits, no more messy diffs.
The Team Collaboration Problem
When multiple developers work on the same repository, inconsistencies creep in:
❌ Different code styles - Each developer has their own preferences
❌ Messy git diffs - Formatting changes obscure actual logic changes
❌ Slow code reviews - Reviewers waste time on style instead of logic
❌ Merge conflicts - Unnecessary conflicts from whitespace differences
❌ Wasted time - Endless debates about tabs vs spaces, semicolons, etc.
The Solution: Automated Pre-commit Hooks
We'll set up a workflow that:
✅ Enforces one consistent style - No matter who commits
✅ Runs automatically - Zero manual effort required
✅ Catches issues early - Before code reaches the repository
✅ Works for everyone - Same rules, same results, every time
✅ Speeds up reviews - Clean diffs show only meaningful changes
The secret? Combining Prettier (formatting), ESLint (code quality), lint-staged (performance), and Husky (automation) into a pre-commit hook that runs before every commit—for every team member.
Prerequisites
This guide uses a Vite + React + TypeScript project, but the concepts apply to any JavaScript/TypeScript team project.
Step 1: Create Your Project
Start with a fresh Vite project:
1npm create vite@latest my-project -- --template react-ts
2cd my-project
3npm installOptionally, run npm run dev to verify everything works.
Step 2: Initialize Git Repository
Initialize Git and create your initial commit:
1git init
2git add .
3git commit -m "initial commit"Team tip: Having an initial commit makes it easier to test your pre-commit hooks and ensures everyone starts from the same baseline.
Step 3: Install Prettier
This is where consistency begins. Install Prettier with an exact version:
1npm install --save-dev --save-exact prettierWhy --save-exact is critical for teams: Different Prettier versions can format code differently. Without pinning the exact version, Alice on v2.8.0 might format code one way, while Bob on v3.0.0 formats it differently. Result? Endless reformatting commits. The --save-exact flag prevents this by ensuring your entire team uses the identical version.
Configure Prettier (Essential for Teams)
Create a .prettierrc file in your project root to define your team's style:
1{
2 "semi": true,
3 "trailingComma": "es5",
4 "singleQuote": true,
5 "tabWidth": 2,
6 "printWidth": 80
7}Team benefit: No more arguing about style preferences. These rules become the single source of truth for your entire team. Everyone's code looks the same, regardless of personal preferences.
Create a .prettierignore file to exclude files:
node_modules/
dist/
build/
package-lock.json
pnpm-lock.yaml
Integrate Prettier with ESLint
Prevent conflicts between ESLint and Prettier:
1npm install --save-dev eslint-config-prettier eslint-plugin-prettierUpdate your eslint.config.js:
1const eslintPluginPrettierRecommended = require('eslint-plugin-prettier/recommended');
2
3module.exports = [
4 // Any other config imports go at the top
5 eslintPluginPrettierRecommended,
6];Team benefit: Your linter and formatter work together, not against each other. No more "ESLint wants semicolons but Prettier removes them" confusion.
Read more: Prettier + ESLint integration
Step 4: Install lint-staged
Here's the performance trick: lint-staged only processes files that are staged for commit.
1npm install --save-dev lint-stagedAdd the configuration to your package.json:
1{
2 "lint-staged": {
3 "*.{js,jsx,ts,tsx}": "eslint --fix",
4 "**/*": "prettier --write --ignore-unknown"
5 }
6}Team benefit: Pre-commit hooks stay fast even in large codebases. When Sarah commits her one-file change, only that file gets checked—not the entire 500-file repository. This keeps your team productive and prevents "the pre-commit hook is too slow" complaints.
Step 5: Install and Configure Husky
Husky makes Git hooks work reliably for everyone on your team:
1npm install --save-dev husky
2npx husky initThe husky init command creates a .husky directory with a sample pre-commit hook.
Configure the Pre-commit Hook
Open .husky/pre-commit and replace its content with:
1npx lint-stagedAlternative approach (using npm scripts):
Add a script to package.json:
1{
2 "scripts": {
3 "lint-staged": "lint-staged"
4 }
5}Then use this in .husky/pre-commit:
1npm run lint-stagedTeam benefit: This hook runs automatically for every team member after they clone the repo and run npm install. No manual setup, no "I forgot to configure it" excuses. Everyone gets the same protection.
Step 6: Commit Your Setup
Save your team's new workflow:
1git add .
2git commit -m "chore: add and setup prettier, lint-staged, and husky"Team milestone: Push this to your repository. From now on, every team member who clones the repo and runs npm install will automatically have the pre-commit hooks set up. Zero configuration required.
Step 7: Test Your Pre-commit Hook
Let's verify the team workflow works! Create a file with intentionally messy code:
src/Test.tsx
1const x= 1
2console.log(x)
3
4Stage and commit the file:
1git add src/Test.tsx
2git commit -m "test: run pre-commit hook"What Happens
You'll see output from lint-staged showing:
- ESLint checking the file
- Prettier formatting the file
- The commit proceeding with formatted code
Check src/Test.tsx and you'll see it's now properly formatted:
1const x = 1;
2console.log(x);This is what happens for every developer, every commit, automatically. Alice's messy code gets formatted. Bob's inconsistent style gets fixed. Charlie's code follows the same rules. No manual intervention needed.
The Team Workflow in Action
Here's what your team's daily workflow looks like now:
New Developer Joins
- Clone the repository
- Run
npm install - Pre-commit hooks automatically installed via Husky
- They're immediately following team standards
Developer Makes Changes
- Write code in their preferred style (messy or clean)
- Stage files:
git add . - Attempt to commit:
git commit -m "feat: add feature" - Pre-commit hook runs automatically
- Code is formatted and linted
- Commit succeeds with clean code
Code Review
- Reviewer opens pull request
- Git diff shows only meaningful changes
- No formatting noise to distract from logic
- Reviews are faster and more focused
- Fewer "please fix formatting" comments
The Results
- ✅ 100% consistent code style across the entire team
- ✅ Clean git history with no formatting-only commits
- ✅ Faster code reviews focused on logic, not style
- ✅ Fewer merge conflicts from whitespace differences
- ✅ Better onboarding for new team members
- ✅ Zero manual formatting required
Team Configuration Tips
Share Your Setup
Commit these files to version control:
.prettierrc- Your team's formatting rules.prettierignore- Files to exclude.eslintrcoreslint.config.js- Linting rules.husky/directory - Git hookspackage.jsonwith lint-staged config
Document for Your Team
Add this to your README.md:
1## Development Setup
2
31. Clone the repository
42. Run `npm install`
53. Pre-commit hooks will automatically format and lint your code
6
7That's it! The pre-commit hook ensures all committed code follows our team standards.Different Package Managers
Your team might use different package managers like pnpm, and yarn. This setup works with all of them.
Important: Choose one package manager for your team and stick with it to avoid lock file conflicts.
What's Next?
This guide covered pre-commit hooks for team code consistency. But there's more you can automate for collaborative projects:
- Commit message validation using commitlint—ensure everyone follows conventional commit standards
- Pre-push checks to run tests before pushing—prevent broken code from reaching the remote
- Branch naming enforcement—maintain consistent branch naming across your team
- Protected branch prevention—stop accidental commits to
mainormaster
Stay tuned for upcoming guides on these team collaboration topics!
Summary
You've successfully set up a team-wide code consistency system:
✅ Prettier - Automatic, consistent code formatting
✅ ESLint - Shared code quality standards
✅ lint-staged - Fast pre-commit checks
✅ Husky - Automatic setup for all team members
Now your team can focus on building features, not debating code style.
Key Team Benefits
For Individual Developers:
- Write code in any style, it gets formatted automatically
- No manual formatting required
- Clear feedback on code issues before committing
For Code Reviewers:
- Clean diffs showing only meaningful changes
- Faster reviews focused on logic
- No more "please fix formatting" comments
For Team Leads:
- Consistent code quality across the entire team
- Reduced technical debt from style inconsistencies
- Smoother onboarding for new developers
For The Codebase:
- Professional, consistent appearance
- Easier to maintain and understand
- Fewer merge conflicts
References
- Vite Documentation
- Prettier Documentation
- Prettier + ESLint Integration
- lint-staged Repository
- Husky Documentation
Building a development team? Share this guide with them! Got questions about team workflow automation? Just reach out. 🚀
