NodeJSFormatting with Prettier

Formatting with Prettier

Prettier is an opinionated code formatter: it takes your code, throws away most of your formatting, and reprints it in a single consistent style — indentation, quotes, line length, trailing commas, spacing, line breaks. The point isn't that its style is objectively best; it's that the style is automatic and uniform, so formatting stops being something anyone writes, reviews, or argues about. It pairs with ESLint (which handles code quality) — Prettier owns appearance. This page covers what Prettier does, the few options, running it, integrating it with ESLint without conflicts, and enforcing it in your workflow.

What Prettier does

JS
// Before — inconsistent spacing, quotes, and line breaks:
const user={name:"Ada",roles:['admin',"editor"],active:true}
function greet( name ){return "hi "+name}

// After 'prettier --write' — one canonical style, every time:
const user = { name: 'Ada', roles: ['admin', 'editor'], active: true }
function greet(name) {
  return 'hi ' + name
}
Prettier reprints your code in one canonical style — it parses to an AST and re-emits, so the result is fully consistent
Prettier doesn't *tweak* your formatting — it **discards and regenerates** it. Internally it parses your code into an abstract syntax tree (so it understands structure, not just text) and then **re-prints** that tree using its own rules, wrapping lines at the configured width and normalizing quotes, semicolons, indentation, and spacing. Because the output depends only on the code's *meaning* and Prettier's rules — not on how you happened to type it — everyone's code comes out identical. It supports JS, TS, JSX, CSS, HTML, JSON, Markdown, YAML, and more, so one tool formats your whole repo. The trade-off is intentional: Prettier is **opinionated** and exposes few options, which is precisely what ends formatting debates.
The handful of options

.prettierrc

JSON
{
  "semi": false,           // no semicolons
  "singleQuote": true,     // 'single' instead of "double"
  "trailingComma": "all",  // trailing commas everywhere they're valid
  "printWidth": 100,       // wrap lines past 100 chars
  "tabWidth": 2,
  "arrowParens": "always"  // (x) => x  rather than  x => x
}

.prettierignore

Bash
dist
build
coverage
package-lock.json
Prettier exposes deliberately few options — pick a handful, commit `.prettierrc`, and stop debating style
Prettier offers **deliberately few** configuration options — semicolons on/off, single vs double quotes, print width, tab width, trailing commas, arrow-parens — because every option is a thing teams *could* argue about, and limiting them is the whole philosophy. Set your handful of preferences once in a **`.prettierrc`** committed to the repo so the entire team (and CI) formats identically, and add a **`.prettierignore`** (same syntax as `.gitignore`) to skip generated output, lock files, and vendored code. Then stop tuning it. The biggest mistake teams make is bikeshedding the config; the value is in *consistency and automation*, not in the specific choices, so pick reasonable defaults, agree quickly, and move on.
Running Prettier

package.json scripts

JSON
{
  "scripts": {
    "format": "prettier --write .",   // reformat every file in place
    "format:check": "prettier --check ."  // verify formatting (use in CI; fails if not formatted)
  }
}
`--write` reformats files; `--check` only verifies — but the real win is format-on-save in your editor
Two commands cover the basics: **`prettier --write .`** reformats every supported file in place (run it once across the repo to adopt Prettier, then it's idempotent), and **`prettier --check .`** *verifies* formatting without changing anything and exits non-zero if any file isn't formatted — ideal as a **CI gate**. But the experience that makes Prettier feel effortless is **format-on-save** in your editor (via the Prettier extension): you write code however you like and it snaps into the canonical style the instant you save, so formatting becomes invisible. Combine editor format-on-save for daily work, a [pre-commit hook](/nodejs/husky-lint-staged) to guarantee committed code is formatted, and `--check` in CI as the final backstop.
Prettier + ESLint without conflicts

Bash
npm install --save-dev eslint-config-prettier

eslint.config.js

JS
import js from '@eslint/js'
import prettier from 'eslint-config-prettier'

export default [
  js.configs.recommended,
  // ...your rules...
  prettier,   // LAST — turns OFF all ESLint formatting rules that would fight Prettier
]
Add `eslint-config-prettier` (last) so ESLint stops enforcing formatting — otherwise the two tools fight over your code
ESLint also has *formatting* rules (`indent`, `quotes`, `semi`), and if those stay enabled alongside Prettier the two tools **conflict**: ESLint flags or "fixes" code into a style Prettier then reformats differently, producing an endless tug-of-war and confusing errors. The clean solution is **`eslint-config-prettier`**: add it as the **last** entry in your ESLint config and it **disables** every ESLint rule that overlaps with formatting, leaving ESLint to enforce *code quality* only and Prettier to own *appearance* exclusively. (The older `eslint-plugin-prettier` approach runs Prettier *as* an ESLint rule, but it's slower and noisier; most teams now keep the tools separate and just use `eslint-config-prettier` to disarm the overlap.) Clear division of labor, no conflicts: ESLint finds bugs, Prettier makes it pretty.
Next
Make these checks run automatically before every commit: [Git Hooks (Husky & lint-staged)](/nodejs/husky-lint-staged).