Automating Code Formatting with Prettier & Husky has become a staple for teams that want faster, cleaner, and more consistent codebases. In 2026, the trend has shifted from manual formatting and ad‑hoc linting to fully integrated CI pipelines that run formatting checks on every commit, enforce style guidelines, and even auto‑fix issues before they reach the main branch. This guide walks you through setting up a modern, end‑to‑end system that hooks Prettier and Husky into Git and your CI environment so that linting, formatting, and commit hooks run automatically, saving time and reducing bugs.
Why This Setup Matters in 2026
Software teams now expect continuous feedback from tools that can catch stylistic inconsistencies, potential bugs, and security issues without manual intervention. The combination of Prettier—a opinionated code formatter—and Husky—a Git hook manager—provides a lightweight yet powerful solution. By integrating them into CI pipelines, you eliminate the “it works on my machine” problem and maintain a single source of truth for code style.
- Consistent formatting across JavaScript, TypeScript, React, Vue, and more.
- Immediate feedback during the commit process.
- Automated formatting on pull requests to keep the main branch clean.
- Reduced merge conflicts caused by whitespace and indentation differences.
Step 1: Project Preparation
Before adding any tooling, make sure your repository has a package.json and that you’re using npm or yarn. If your project already relies on eslint or another linter, note the current configuration; we’ll integrate Prettier to work alongside it.
npm init -y
npm install --save-dev eslint prettier husky lint-staged
With these packages installed, we can configure each one.
Configure ESLint (Optional but Recommended)
If your project already uses ESLint, add the eslint-config-prettier package to disable any formatting rules that conflict with Prettier:
npm install --save-dev eslint-config-prettier
In your .eslintrc.json or .eslintrc.js, extend the Prettier configuration:
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"prettier"
]
Set Up Prettier
Prettier doesn’t need a lot of configuration to get started. Create a .prettierrc file:
{
"singleQuote": true,
"trailingComma": "es5",
"printWidth": 100,
"tabWidth": 2
}
For TypeScript projects, you might also want a .prettierignore file to skip generated files.
Step 2: Integrate Husky
Husky replaces the older pre-commit or pre-push hook scripts with a simple configuration in package.json. First, enable Husky and set up the prepare script so that it runs automatically when installing dependencies:
"scripts": {
"prepare": "husky install"
}
Run npm run prepare once to create the .husky directory.
Create a Pre‑Commit Hook
The goal of the pre‑commit hook is to run lint-staged, which will only format staged files, keeping the commit fast. Add the following to .husky/pre-commit:
# husky - start
npx lint-staged
Make the file executable:
chmod +x .husky/pre-commit
Configure lint-staged
In package.json, add a lint-staged section that tells the tool to run Prettier (and optionally ESLint) on staged files before committing:
"lint-staged": {
"*.{js,jsx,ts,tsx,json,css,md}": [
"prettier --write",
"eslint --fix",
"git add"
]
}
Now, whenever you run git commit, staged files will automatically be formatted, linted, and re‑added to the commit, ensuring the main branch never receives unformatted code.
Step 3: Adding CI Checks
Even though the local pre‑commit hook ensures consistency, a CI pipeline is the safety net that guarantees every pull request passes the same tests. Here’s a quick example using GitHub Actions, but you can adapt it for GitLab CI, CircleCI, or any other platform.
GitHub Actions Workflow
Create a file at .github/workflows/ci.yml:
name: CI
on:
push:
branches:
- main
pull_request:
jobs:
lint-format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20
- run: npm ci
- name: Check formatting
run: npx prettier --check .
- name: Run ESLint
run: npx eslint . --max-warnings 0
This workflow checks that all files comply with Prettier formatting and that ESLint finds no warnings or errors. If either step fails, the PR will be marked as failing, prompting the author to fix the issues before merging.
Optional: Auto‑Format on PRs
Some teams prefer automatically formatting the code in PRs rather than making developers run npm run format. You can add a step that uses actions/checkout with a write token and pushes the changes back to the PR branch. This is more advanced and should be used cautiously to avoid merge conflicts.
Step 4: Testing the Pipeline
To verify that everything works as expected:
- Make a change that violates Prettier or ESLint rules.
- Run
git addandgit commit. The pre‑commit hook should auto‑format the file and commit the changes. - Create a pull request and observe the CI job. It should pass if the formatting is correct.
- Try a commit that deliberately fails Prettier checks (e.g., an intentional line break). The pre‑commit hook should block the commit.
Common Pitfalls and How to Fix Them
Even with a solid setup, you might run into issues. Here are some troubleshooting tips.
ESLint and Prettier Conflict
When both tools are enabled, ESLint may report formatting issues that Prettier already fixes. The eslint-config-prettier package turns off conflicting rules, but you might still need to add eslint-plugin-prettier to run Prettier as an ESLint rule. That way, ESLint can report formatting errors as linting errors during CI.
Large Repositories and Slow Hooks
Running Prettier on thousands of files during a pre‑commit hook can be slow. Use lint-staged to limit formatting to only staged files. For CI, consider caching dependencies and using --cache options in ESLint to speed up runs.
Non‑Git Workflow (e.g., Mercurial)
Husky and lint-staged rely on Git. If you’re using a different VCS, you’ll need to write custom hook scripts that mimic the behavior. Most CI platforms, however, still use Git for pipelines, so the CI part remains useful.
Scaling the Setup for Large Teams
Once the core pipeline is in place, you can add more granular controls:
- Pre‑push Hooks – catch formatting errors before they hit the remote repository.
- Use
prettier-plugin-tailwindcssto automatically sort Tailwind classes. - Integrate with
semantic-releaseto manage version bumps automatically when the CI passes. - Leverage
commitlintto enforce conventional commit messages, ensuring a clean changelog.
Best Practices for 2026
1. Keep the configuration lightweight. Avoid over‑configuring Prettier unless necessary.
2. Run npm ci in CI instead of npm install to guarantee reproducible builds.
3. Store all formatting rules in a single .prettierrc and reference it across projects.
4. Use --cache flags where possible to speed up linting.
5. Periodically audit the pipeline to ensure new dependencies do not break formatting or linting.
Future Directions: AI‑Assisted Formatting
2026 sees the emergence of AI‑driven code formatting suggestions that adapt to project style over time. While Prettier remains rule‑based, you can integrate openai-code-format or similar tools as a secondary check in CI. This hybrid approach ensures consistency while embracing the flexibility that AI offers. Keep an eye on these tools, but always verify that any AI output passes through your existing lint and test suites before merging.
Conclusion
Automating code formatting with Prettier & Husky, coupled with a robust CI pipeline, transforms the way teams write, review, and ship code. By ensuring that every commit is automatically formatted, linted, and validated, developers can focus on building features rather than fighting style inconsistencies. This setup not only speeds up the development process but also elevates code quality, making it easier to maintain large codebases in 2026 and beyond.
