prettier
Prettier is an opinionated code formatter for JavaScript, TypeScript, JSX, JSON, CSS, SCSS, Less, HTML, Vue, Angular, GraphQL, Markdown and YAML. It parses your code and reprints it from scratch under its own line-length-aware rules, which means the whole team gets one style and nobody argues about it in review. It runs on save in editors, in pre-commit hooks, and in CI with a check mode. It formats only; it does not lint for bugs.
The default choice and still the safest one: massive adoption, every editor supports it, and the opinionated model is the whole point. Pick Biome instead only when repo-scale formatting speed is a real problem or you want formatter and linter unified.
Use it if
- You want formatting debates gone from code review and are willing to accept Prettier's choices instead of tuning your own style
- Your repo mixes languages (TS, CSS, Markdown, YAML, JSON) and you want one formatter with one config for all of them
- You need the standard toolchain path: editor extension on save, lint-staged in pre-commit, prettier --check in CI
- You want control over formatting style. Prettier is intentionally near-zero-config; if your team insists on a specific wrapping or brace style, you will fight the tool forever and lose
- You are formatting a very large monorepo and speed matters: Prettier runs on JavaScript and full-repo runs are noticeably slower than Rust-based Biome doing the same job
- You only format JS/TS and already run Biome or deno fmt; adding Prettier just duplicates a tool you have
- Your main languages are outside the built-in list (PHP, Java, Ruby): those need third-party plugins of uneven quality and maintenance
Setup reality
npm install -D prettier plus a .prettierrc and .prettierignore takes five minutes. The annoying parts: the first whole-repo run produces one giant diff commit; formatted output can change between Prettier releases, so pin the exact version or CI checks break on upgrade day; and if you use ESLint you must add eslint-config-prettier to turn off conflicting style rules or the two tools will fight. Editors also need the Prettier extension set as the default formatter per language.
Patterns
Format the whole project from the CLIformat-project
npx prettier --write .Respects .prettierignore and .gitignore; run this once as its own commit so the reformat noise stays out of feature diffs.
Create a .prettierrc configconfig-file
{
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100
}These few options are nearly all you get; that is by design. printWidth is a guideline for the wrapping algorithm, not a hard max line length.
Fail CI when files are not formattedcheck-in-ci
npx prettier --check .
# exits 1 and lists unformatted filesPin the exact prettier version in package.json; a minor upgrade can change output and turn CI red with no code changes.
Ignore files or a single expressionignore-code
# .prettierignore
dist/
coverage/
// in code, skips the next node:
// prettier-ignore
const matrix = [
1, 0,
0, 1,
];prettier-ignore covers exactly the next AST node, so hand-aligned matrices and ASCII tables survive.
Stop ESLint and Prettier from fightingeslint-integration
npm i -D eslint-config-prettier
// eslint.config.js (flat config)
import prettierConfig from 'eslint-config-prettier';
export default [
// ...your configs,
prettierConfig,
];Put it last so it wins; it disables ESLint style rules that conflict. Prefer this over eslint-plugin-prettier, which reruns Prettier inside ESLint and is slower.
Format a string with the Node APIapi-format
import * as prettier from 'prettier';
const formatted = await prettier.format('const x = 1', {
parser: 'babel',
});format() returns a Promise since v3; the sync v2 call sites all need await when you upgrade.
Different options for specific filesper-filetype-overrides
{
"printWidth": 100,
"overrides": [
{
"files": "*.md",
"options": { "proseWrap": "always", "printWidth": 80 }
}
]
}Overrides match by glob and merge onto the base config; this is the sanctioned escape hatch instead of multiple config files.
Format staged files before commitpre-commit-hook
npm i -D husky lint-staged
// package.json
"lint-staged": {
"**/*": "prettier --write --ignore-unknown"
}
// .husky/pre-commit
npx lint-staged--ignore-unknown lets the catch-all glob skip binaries and file types Prettier cannot parse instead of erroring.
Add a language or framework pluginuse-plugin
npm i -D prettier-plugin-tailwindcss
// .prettierrc
{
"plugins": ["prettier-plugin-tailwindcss"]
}Since v3 plugins must be listed explicitly in config; auto-discovery from node_modules was removed.
Format on save in VS Codeeditor-on-save
// .vscode/settings.json
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
}Commit this to the repo so every contributor formats the same way; a per-language block wins if someone has another default formatter.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| @biomejs/biome | npm | You want a much faster Rust formatter plus linter in one binary and mostly write JS/TS/JSON/CSS |
| dprint | npm | You want a pluggable Rust-based formatter with Prettier-compatible plugins and per-plugin config |