Skip to content

Prettier

Supported languages

  • JavaScript
  • JSX
  • Angular
  • Vue
  • Flow
  • TypeScript
  • CSS, Less, SCSS
  • HTML
  • Ember/Handlebars
  • JSON
  • GraphQL
  • Markdown (GFM + MDX v1)
  • YAML

Setup

  • pnpm add --save-dev prettier
  • .prettierignore - .git, node_modules are ignored by default.
  • Prettier uses cosmiconfig, and thus the following config files are supported
    • prettier - key in package.json
    • .prettierrc - json/yaml format
    • .prettierrc.json, .prettierrc.yml, .prettierrc.yaml, .prettierrc.json5
    • .prettierrc.js, prettier.config.js - with export default
    • .prettierrc.mjs, prettier.config.mjs - with export default
    • .prettierrc.cjs, prettier.config.cjs - with module.exports
    • .prettierrc.toml
  • JSON schema to validate prettier config can be found at https://json.schemastore.org/prettierrc.
  • pnpm exec prettier . --write - format all files in directory.
  • pnpm exec prettier . --check - check if files are formatted. Useful in CI pipelines.

    Returns the following exit codes

    • 0 - everything formatted properly
    • 1 - something wasn't formatted properly
    • 2 - something wrong with prettier

Performance

For performance, provide the path to .prettierrc, .prettierignore file in the CLI. This avoids prettier to do the lookup.

  • pnpm exec prettier . --write --config path/to/.prettierrc --ignore-path .prettierignore .gitignore

Cache

Prettier stores the cache in ./node_modules/.cache/prettier/.prettier-cache (controlled by --cache-location). Files are formatted only when one of the following is changed

  • Prettier version
  • Options
  • Node.js version
  • --cache-strategy metadata - like timestamps. This is faster.
  • --cache-strategy content (default) - git clone does not track modification times, therefore this is the default.

ESLint

  • pnpm add --save-dev eslint-config-prettier
  • In .eslintrc add
    1
    2
    3
    4
    5
    6
    {
    "extends": [
        "other configs",
        "prettier"
    ]
    }
    
  • Or in eslint.config.js add
    1
    2
    3
    4
    5
    6
    7
    import someConfig from 'some-config';
    import eslintConfigPrettier from 'eslint-config-prettier';
    
    export default [
    someConfig,
    eslintConfigPrettier,
    ];
    

Usage with linters

Disable linting use line ranges, rather than disabling next line.

For instance, linting for next line can be disabled in ESLint as shown below

// eslint-disable-next-line no-eval
const result = safeToEval ? eval(input) : fallback(input);

But the problem is prettier might move the expression to a new line and the comment would no longer be valid.

1
2
3
// eslint-disable-next-line no-eval
const result =
  safeToEval ? eval(input) : fallback(input);

Git hooks

1
2
3
4
pnpm add --save-dev husky lint-staged
pnpm exec husky install
npm pkg set scripts.prepare="husky install"
pnpm exec husky add .husky/pre-commit "pnpm exec lint-staged"

In package.json

1
2
3
4
5
{
  "lint-staged": {
    "**/*": "prettier --write --ignore-unknown"
  }
}

pre-commit

Add the following in .pre-commit-config.yaml

- repo: https://github.com/pre-commit/mirrors-prettier
  rev: "" # Use the sha / tag you want to point at
  hooks:
    - id: prettier
      # If using prettier plugins, define them here
      additional_dependencies:
      - prettier@2.1.2
      - '@prettier/plugin-xml@0.12.0'
      # To limit what files are passed to 'prettier'
      types_or: [css, javascript]

Ignore code

Use comment prettier-ignore to exclude the next node in the abstract syntax tree from formatting.

To disable a range of code (only to be used at the top, like autogenerated files or TOC)

1
2
3
<!-- prettier-ignore-start -->
code
<!-- prettier-ignore-end -->

Plugins

To create plugins see https://prettier.io/docs/en/plugins.

Options

{

  "printWidth": 80,          // just a hint, the final value can be higher/lower
  "tabWidth": 2,
  "useTabs": false,
  "semi": true,              // use semicolons at end of line
  "singleQuote": false,      // JSX quotes ignore this option
  "quoteProps": "as-needed", // quote property names only when needed
  "jsxSingleQuote": false,
  "trailingComma": "all",    // add them whenever possible
  "bracketSpacing": true,    // add space between brackets
  "bracketSameLine": false,  // if false, put '>' of a multi-line HTML at new line
  "arrowParens": "always",   // add parenthesis to single parameter arrow function
  "parser": ...,             // Specify which parse to use. Use with a file extension
                             // to configure parser per file.
  "singleAttributePerLine": false // enforce single attribute per line in HTML, Vue, JSX
}

Add * text=auto eol=lf to .gitattributes to ensure lf is used in the repo.

Override options

Overriding configuration for file extensions

{
  "overrides": [
    {
      "files": "*.test.js",
      "options": {
        "semi": true
      }
    },
    {
      "files": ["*.html", "legacy/**/*.js"],
      "options": {
        "tabWidth": 4
      }
    }
  ]
}

Sharing config

Publish a module that exports a configuration object and reference it in package.json.

1
2
3
{
  "prettier": "@company/prettier-config"
}

A better approach is to use .prettierrc.js as that allows to modify the config

1
2
3
4
5
6
import companyPrettierConfig from '@company/prettier-config';

export default {
  ...companyPrettierConfig,
  semi: false,
};


Last update: November 21, 2023
Created: November 21, 2023