Prettier Integration
Prettier enforces consistent formatting so code review focuses on behavior, not semicolons and line breaks.
Recipe
Quick-reference recipe card - copy-paste ready.
npm install -D prettier eslint-config-prettier// .prettierrc
{
"semi": true,
"singleQuote": false,
"trailingComma": "all",
"printWidth": 100
}{
"scripts": {
"format": "prettier --write .",
"format:check": "prettier --check ."
}
}When to reach for this:
- Formatting debates slow down PRs.
- You want ESLint to handle logic, Prettier to handle style.
- Contributors use different editors but one output style.
Working Example
// eslint.config.js
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
import eslintConfigPrettier from "eslint-config-prettier";
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommended,
eslintConfigPrettier,
{ ignores: ["dist/**"] }
);// package.json
{
"scripts": {
"lint": "eslint .",
"format": "prettier --write .",
"format:check": "prettier --check ."
},
"devDependencies": {
"prettier": "^3.4.0",
"eslint-config-prettier": "^9.1.0",
"husky": "^9.1.0",
"lint-staged": "^15.2.0"
}
}// lint-staged.config.js
export default {
"*.{ts,json,md}": ["prettier --write"],
"*.ts": ["eslint --fix"],
};npx husky init
echo "npx lint-staged" > .husky/pre-commitWhat this demonstrates:
eslint-config-prettierdisables ESLint stylistic rules that fight Prettier.lint-stagedformats only staged files on commit.format:checkruns in CI without modifying files.
Deep Dive
How It Works
- Prettier parses and reprints code with deterministic rules.
- ESLint runs after Prettier in pre-commit to catch logic issues on formatted code.
- Editor "format on save" calls Prettier via VS Code/Cursor extension.
- CI uses
--checkto fail PRs with unformatted diffs.
VS Code Settings (committed or documented)
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
}TypeScript Notes
- Prettier does not typecheck; pair with
tsc --noEmitin CI. - JSON and Markdown in repos benefit from Prettier too - include in
formatscript.
Gotchas
- ESLint stylistic plugins with Prettier - Duplicate formatting fights. Fix: use
eslint-config-prettier, remove stylistic ESLint plugins. - Formatting entire repo in one PR - Noisy git blame. Fix: adopt Prettier early; use one-time format commit with
.git-blame-ignore-revs. - Husky skipped with
--no-verify- Bad code can still land. Fix: enforceformat:checkandlintin CI regardless of hooks. - Different Prettier versions locally vs CI - Lock Prettier in
devDependencies; usenpm ci. - Generated files formatted - Swagger output churns every build. Fix: add
dist/,openapi.jsonto.prettierignore.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| ESLint stylistic only | No Prettier in org policy | Team already standardized on Prettier |
| Biome | Want lint+format one tool | Ecosystem plugins expect ESLint |
| EditorConfig alone | Basic indentation only | TypeScript needs full formatter |
FAQs
Does Prettier replace ESLint?
No. Prettier formats; ESLint catches unused vars, promise misuse, and import boundaries.
Should CI run format:check or format?
format:check in CI (read-only). Developers run format or rely on pre-commit hooks locally.
How do I ignore a file?
Add paths to .prettierignore (same syntax as .gitignore).
Can NestJS and Express projects share Prettier config?
Yes. Root .prettierrc applies across monorepo workspaces unless overridden.
What about YAML and Dockerfile?
Prettier supports YAML; Dockerfiles need a plugin or separate linter. Prioritize TS/JSON/MD first.
Is lint-staged required?
No, but it keeps commits fast. CI format:check is the real gate.
How do I fix a large unformatted codebase?
One PR: npm run format, add CI check, optionally .git-blame-ignore-revs for the format SHA.
Does prettier-eslint make sense?
Rarely with flat config. Prefer eslint-config-prettier disable list instead of running Prettier inside ESLint.
Should markdown docs be formatted?
Yes if docs live in repo - consistent wrapping helps diffs in site/ and README files.
How do monorepos run format?
Root script: "format:check": "prettier --check ." with ignores for dist/ in each package.
Related
- Linting Basics - ESLint flat config foundation
- Linting Best Practices - zero-warning and CI policy
- Typecheck in CI - separate gate from formatting
Stack versions: This page was written for Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5, and NestJS 11.