Adopting a formatter is a one-day job that regularly turns into a two-week mess. Almost every case comes down to the same seven mistakes.
A repo-wide reformat rewrites nearly every line. Every branch that predates it conflicts on every file it touches. Merge or close open pull requests first, announce a freeze window of a few hours, land the reformat, then have everyone rebase. Doing this on a Friday afternoon with fifteen branches open is how teams end up reverting the formatter entirely.
After the reformat, git blame attributes every line to whoever ran the formatter. The fix takes two minutes: put the reformat commit's SHA in a .git-blame-ignore-revs file, commit it, and run git config blame.ignoreRevsFile .git-blame-ignore-revs. Major forges honour the same file. Skipping this makes archaeology painful for years.
A CI job that runs the formatter in write mode and pushes the result creates commits nobody reviewed, can trigger build loops, and hides the fact that contributors do not have the hook installed. CI should run prettier --check ., ruff format --check . or cargo fmt --check and fail with a message naming the exact command to run locally.
Formatters change their output between minor releases. If one developer has Prettier 3.3 and CI has 3.4, files ping-pong between two formattings and every pull request touches unrelated lines. Pin the exact version in package.json or pyproject.toml, commit the lockfile, and use the same pinned version in the pre-commit config and in CI.
Style rules in a linter that disagree with the formatter produce an unwinnable loop. In ESLint, remove stylistic rules and let the formatter own layout entirely — eslint-config-prettier exists precisely to turn them off. In Python, disable the line-length and quote rules that duplicate the formatter's job. The linter's remit is correctness; the formatter's is layout, and they should not overlap.
The value of a formatter is that the discussion ends. A config file with twenty overrides restarts it. Take the defaults, change at most print width and quote style if the team genuinely cares, and write down that no further options will be added. Every option you add is a decision someone will want to relitigate.
Generated code, vendored dependencies, test fixtures whose exact bytes matter, and snapshot files all break when reformatted. Set up .prettierignore, .dprintignore or the equivalent exclude list before the first run, and always include the build output directory, node_modules, and any directory produced by a code generator. Reformatting a fixture that a test compares byte-for-byte produces a failure that looks like a logic bug.
--check to see the blast radius..git-blame-ignore-revs in the very next commit.