Prettier Deep Dive: Opinionated Formatting That Ends Style Debates
Code formatting arguments waste more engineering hours than anyone wants to admit. Tabs or spaces? Semicolons or not? Single quotes or double? Prettier answers all of these questions with a single principle: parse the code, throw away the original formatting, and reprint it according to a fixed set of rules. No discussion needed.
How Prettier works
Prettier does not search-and-replace whitespace. It follows a three-stage pipeline:
- Parse — The source code is parsed into an abstract syntax tree (AST) using language-specific parsers (babel for JS/TS, postcss for CSS, etc.).
- Build IR — The AST is converted into an intermediate representation (IR) of "documents" that describe the logical structure — groups, indents, line breaks, and fills.
- Print — The IR is serialized back to text, fitting within the configured
printWidth. Prettier decides where to break lines based on what fits.
This is why Prettier can reformat code you wrote with zero whitespace and still produce clean, readable output. It does not care what the input looks like.
// Input (messy)
const x={a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8}
// Prettier output (printWidth: 80)
const x = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8 };
// Prettier output (printWidth: 40)
const x = {
a: 1,
b: 2,
c: 3,
d: 4,
e: 5,
f: 6,
g: 7,
h: 8,
};
The same input produces different outputs depending on line width. Prettier finds the most compact layout that stays within bounds.
Supported languages
Prettier handles far more than JavaScript:
- JavaScript / TypeScript — Including JSX and TSX
- CSS / SCSS / Less — Full selector and property formatting
- HTML / Vue / Angular — Template formatting with embedded expressions
- JSON / JSONC — With comment support for JSONC
- Markdown — Wraps prose, formats tables, normalizes lists
- YAML — Consistent indentation and quoting
- GraphQL — Query and schema formatting
- XML / SVG — Via plugins
Community plugins extend support to Java, PHP, Ruby, SQL, Svelte, Astro, and more.
The options that matter
Prettier is deliberately opinionated — it exposes very few options. Here are the ones worth configuring:
printWidth (default: 80)
The line length Prettier aims for. Not a hard limit — Prettier will exceed it when a single token is longer than the width. Most teams use 80 or 100.
{ "printWidth": 100 }
tabWidth (default: 2)
Number of spaces per indentation level. Teams coming from Java or C# often prefer 4.
useTabs (default: false)
Indent with tabs instead of spaces. Set to true if your team prefers tabs — Prettier will handle the rest.
semi (default: true)
Whether to add semicolons at the end of statements. The false camp argues JavaScript's ASI (Automatic Semicolon Insertion) makes them unnecessary. The true camp argues they prevent rare but confusing bugs.
// semi: true
const name = "world";
// semi: false
const name = "world"
singleQuote (default: false)
Use single quotes instead of double quotes in JavaScript. Does not apply to JSX, which always uses double quotes for HTML attribute consistency.
trailingComma (default: "all")
Adds trailing commas wherever valid. This produces cleaner git diffs because adding a new item to an array or object only changes one line instead of two.
// trailingComma: "all"
const colors = [
"red",
"green",
"blue",
];
bracketSpacing (default: true)
Controls spaces inside object literals: { foo: bar } vs {foo: bar}.
Configuration file
Create a .prettierrc in your project root:
{
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"bracketSpacing": true
}
Prettier also reads from prettier.config.js, .prettierrc.yaml, or a "prettier" key in package.json.
Ignoring code
Sometimes Prettier's output is not what you want — typically for carefully aligned tables or ASCII art.
// prettier-ignore
const matrix = [
[1, 0, 0],
[0, 1, 0],
[0, 0, 1],
];
The // prettier-ignore comment tells Prettier to skip the next node entirely.
For entire files, add them to .prettierignore:
dist/
build/
*.min.js
Prettier vs linters
Prettier formats code. ESLint catches bugs and enforces patterns. They are complementary, not competing. Use eslint-config-prettier to disable ESLint rules that conflict with Prettier, then run both:
# Format first, then lint
prettier --write .
eslint --fix .
Or integrate both into your editor's save action so they run automatically.
Editor integration
The fastest way to adopt Prettier is to install the editor extension and enable "format on save." Every time you hit save, the file is reformatted. Within a day the muscle memory kicks in and you stop thinking about formatting entirely.
Try our Prettier Formatter to format your code instantly — right in your browser, no upload required.