The Complete Guide to Code Formatting
Auto-formatting removes an entire class of code review noise and keeps diffs focused on logic. This guide covers how Prettier works under the hood and how to wire up auto-formatting so you never think about it again.
Why code formatting matters
Every time a developer opens a file, their brain spends cycles parsing the visual structure — indentation, line breaks, spacing — before they can reason about the logic. Inconsistent formatting increases that cognitive load on every single read.
Beyond readability, consistent formatting eliminates an entire category of code review noise. No more "add a semicolon here" or "we use single quotes" comments. Reviews focus on logic and design instead of whitespace.
Clean formatting also produces smaller diffs. When one developer reformats a file as part of an unrelated change, the diff becomes impossible to review. If formatting is enforced automatically, diffs show only meaningful changes.
Prettier: the opinionated formatter
Prettier was created by James Long in 2017 with a radical premise: stop configuring your formatter. Most style decisions don't matter — what matters is that everyone on the team makes the same ones.
Unlike linters that flag violations and leave fixing to you, Prettier parses your code into an AST (abstract syntax tree) and reprints it from scratch. The original formatting is thrown away entirely. This means Prettier's output is deterministic — the same code always produces the same result, regardless of what it looked like before.
Prettier supports JavaScript, TypeScript, CSS, HTML, JSON, Markdown, YAML, GraphQL, and more via plugins. The options it does expose are intentionally limited:
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": false,
"trailingComma": "all"
}
That's roughly the full list. The philosophy is: pick defaults once, move on, and never argue about formatting again.
Prettier vs ESLint vs Biome
These tools solve different problems and are often confused:
- Prettier handles formatting only — whitespace, line breaks, semicolons, quote style. It doesn't know whether your code is correct.
- ESLint handles code quality — unused variables,
no-console, accessibility rules, import ordering. It can flag problems Prettier doesn't care about. - Biome does both formatting and linting in a single tool, written in Rust. It's 20-100x faster than Prettier + ESLint and requires less configuration.
The most common setup today is Prettier for formatting + ESLint for linting, with ESLint's formatting rules disabled (via eslint-config-prettier). If you're starting a new project and want fewer moving parts, Biome is worth evaluating — one tool, one config, sub-second runs on large codebases.
Setting up auto-formatting
The goal is to make formatting invisible. Developers should never manually run a formatter.
Editor integration — In VS Code, install the Prettier extension and enable format-on-save:
{
"editor.defaultFormatter": "esbenp.prettier-io",
"editor.formatOnSave": true
}
Pre-commit hooks — Catch anything the editor missed. Use husky + lint-staged to format only staged files:
{
"lint-staged": {
"*.{js,ts,css,json,md}": "prettier --write"
}
}
CI checks — Run prettier --check . in your pipeline. It exits non-zero if any file isn't formatted, preventing unformatted code from reaching main.
Config files — .prettierrc at the repo root holds your options. .prettierignore excludes generated files, dist/, node_modules/, and anything else you don't control.
Minification: the opposite of formatting
Formatting makes code readable. Minification makes it small. Minifiers strip whitespace, remove comments, and (for JavaScript) shorten variable names and apply dead-code elimination.
Common tools: Terser for JavaScript, cssnano for CSS, esbuild and swc for both (and they're extremely fast). Most bundlers — Vite, webpack, Rollup — run minification automatically for production builds.
This tool supports basic CSS and JS minification for quick one-off tasks — paste code in, get the compressed output, copy it out. For production assets, always use your build pipeline instead.
Troubleshooting
Prettier changed too many lines in my commit — You likely formatted a file that was never Prettier-formatted before. Run prettier --write . once across the entire repo in a dedicated commit, then all future diffs will be minimal.
Prettier conflicts with ESLint — Install eslint-config-prettier and add it as the last item in your ESLint extends array. It disables every ESLint rule that overlaps with Prettier. Never run both tools' formatting rules simultaneously.
Formatting looks different after upgrading Prettier — Prettier intentionally changes formatting between major versions to improve output. Pin your Prettier version in package.json (exact version, no ^), and upgrade deliberately with a single reformatting commit.
I need to skip formatting for a specific block — Use a // prettier-ignore comment on the line before the code you want left alone. For Markdown, use <!-- prettier-ignore -->. For entire files, add the path to .prettierignore.
Prettier breaks my template literal / embedded HTML — Prettier sometimes reformats tagged template literals unexpectedly. Use // prettier-ignore above the statement, or for embedded languages, check if a Prettier plugin (like prettier-plugin-embed) handles your specific syntax.