Editor’s note: This post was updated on 11 February 2022 to correct any outdated information and add the Prettier vs. ESLint section.
Linting and pretty-printing JavaScript code can help developers catch errors early, make code more legible, and improve overall code quality. However, when using a formatter for pretty-printing and a linter side-by-side, there can be some friction.
For example, the formatter might do something that the linter deems problematic. The linter can then overwrite style changes from the formatter, causing the two to pull in different directions.
To use them together successfully, developers must get them on the same page. In this article, we’ll discuss how to use the popular formatter, Prettier, with the popular linter, ESLint.
We’ll learn how to set them up and use them together on the command line and in Visual Studio Code (VS Code) to automatically fix and format code.
I have seen different methods for tackling how to use them together, but some are hacky solutions because of limitations in code editors. So, I will discuss the pros and cons of some of these, and you can make your own decision on what is best.
In this post, we’ll cover the following:
First, let’s get a clear understanding of what ESLint and Prettier do, and highlight how they differ.
Prettier is an opinionated code formatter for JavaScript and other popular languages. Prettier enforces a consistent format by parsing code and reprinting it with its own rules that take the maximum line length into account, wrapping code when necessary.
This rewriting process prevents developers from introducing any formatting mistakes.
The primary reason Prettier was created was to eliminate debates over code styles. The idea is that Prettier’s style guide is fully automatic. Even if Prettier does not format your code 100% the way you like, it’s worth the sacrifice for the simplicity of the approach.
While a big reason to use Prettier is to avoid configuration altogether, Prettier does support its own configuration file that has a handful of formatting options.
So, why are there any options at all?
It is mostly due to historical reasons. A few were added during Prettier’s infancy to entice more people into using it, a couple of options were added due to demand, and some rules were added for compatibility reasons.
The bottom line is that the development team intends to never add more options from now on; you can read more about this in Prettier’s Option Philosophy.
ESLint is a JavaScript linting utility that was first released in June 2013 and now is by far the number one linting utility.
Linting is a type of static analysis that finds problematic patterns and code that doesn’t adhere to certain style guidelines.
Since JavaScript is a dynamic and loosely-typed language, it is especially prone to developer errors. Without the benefit of a compilation process, JavaScript code typically executes to find syntax or other errors.
However, ESLint enables developers to discover problems with their code without actually executing their code.
The primary reason ESLint was created was to allow developers to create their own linting rules. ESLint has built-in rules that make it useful from the start, but you can add rules specific to your project and whatever flavor of JavaScript you use.
Many people have done the heavy lifting for you by creating shareable configs, which have rulesets for popular JavaScript frameworks and common style guides/coding standards such as Google’s JavaScript Style Guide.
You can find some of these shared configs on npmjs.com by searching for “eslint-config” (the naming convention for shared configs).
ESLint has a pluggable architecture that enables creating plugins, which can add extra capabilities to ESLint, and gives a new baseline to add your own custom rules.
An example of this is eslint-plugin-vue, which is the official plugin for Vue.js. This plugin allows us to lint the <template>
and <script>
sections of .vue
files, as well as Vue code contained in .js
files.
In a dedicated ESLint configuration file, you can manage the rules your project uses and disable any you don’t wish to use. ESLint allows rules to be set as errors or warnings and some errors can be automatically fixed.
In summary, these are the major differences:
ESLint | Prettier | |
---|---|---|
Report code errors | Yes | No |
Automatically fix code errors | Yes | No |
Format code | Yes | Yes |
Configuration options | Yes | Limited |
Add custom rules/options | Yes | No |
Are you still wondering why bother using both?
In a nutshell, you will use Prettier to simplify the formatting of your code and ESLint for catching bugs.
There are two broad categories of linting rules: formatting rules and code-quality rules.
Formatting rules are the rules that affect the style of the code and are not concerned with bugs. For example, the rule no-mixed-spaces-and-tabs
rule in ESLint ensures that only tabs or spaces are used for indentation.
Prettier has a tabs
option for the same thing.
Secondly, the code-quality rules improve code quality and can prevent or catch bugs. For example, the rule no-implicit-globals
in ESLint disallows global scope variables.
Name collisions can occur with global variables created from other scripts, which usually leads to runtime errors or unexpected behavior.
The problem is that the rules of Prettier and ESLint overlap, and we prefer that they don’t!
Generally, we want Prettier to handle the first category and ESLint to handle the second. There are rules that may be difficult to categorize as one or the other; we don’t need to be pedantic about which category they fit into.
Our interest is in ensuring that either Prettier or ESLint perform a particular action and do not bump into one another.
As for the order to run them in, it is generally best to run Prettier before ESLint because Prettier reprints your entire program from scratch. So, if you want to let ESLint in on the formatting act, you should run it after Prettier to prevent the changes from being overwritten.
If you’re not familiar with ESLint and Prettier, let’s cover how you can configure and use them in the next section.
Both ESLint and Prettier are available to download from npm and Yarn. For every project, you must create a package.json
and add them as devDependencies
:
npm install --save-dev eslint npm install --save-dev --save-exact prettier
ESLint starts as a blank slate. It won’t do anything until you create a configuration with some rules. You must put the configuration file, .eslintrc.{js,yml,json}
, into the project directory and you’ll be ready to lint.
You can create the configuration on the command line with the following commands:
npm init @eslint/config # or yarn create @eslint/config
Note that npm init @eslint/config
assumes you have a package.json
file already. If you don’t, you can run npm init
or yarn init
to create one.
This command will lead to a wizard with a series of questions to establish what it is you want to lint, such as module type, framework used, where your code runs, and so on. It will spit out a configuration file and install any related dependencies for you.
If you just want to use the built-in recommended rules, you can simply add eslint.json
like so:
<
{ "extends": "eslint:recommended" }
With a configuration in place, you can run ESLint on any file or directory. For example, here I am linting my src
directory:
npx eslint src # or yarn run eslint src
As you can see in the screenshot above, ESLint outputs a list of problems with the details: location of error (formatted as <line number: character number>
), type (error or warning), a description, and the rule name. You can read ESLint’s Getting Started Guide for more details.
You can also set up a global configuration, but ESLint has deprecated it (discourages it). I still use a global configuration. 🤫
On the other hand, Prettier has a default configuration. It can run without creating a configuration file, so you can begin using it straight away. The recommendation is to use a specific version of Prettier on big projects, otherwise updates may cause changes to files and add noise to your git commits.
You should also use a .prettierignore
file to ignore things that should not be formatted. You can read Prettier’s installation guide for more information.
A typical package.json
will look something like what is below. Here, we target the files in the folders src
and test
for the npm scripts.
I prefer to skip .eslintignore
and .prettierignore
files if possible — simpler is preferable! 😅
{ "name": "basic-project", "version": "1.0.0", "main": "index.js", "scripts": { "lint": "npx eslint src test", "lint:fix": "npm run lint -- --fix", "prettier": "npx prettier src test --check", "prettier:fix": "npm run prettier -- --write", }, "author": "rob o'leary", "license": "ISC", "devDependencies": { "eslint": "^7.25.0", "prettier": "^2.2.1" } }
All the major code editors have extensions for ESLint and Prettier. For VS Code, the official extensions are Prettier – Code formatter and ESLint.
This method is the cleanest and most efficient, and the best recommended to use.
It’s easy to turn off rules that conflict with Prettier in ESLint by using the following configs:
eslint-config-prettier
for JavaScripttslint-config-prettier
for TypeScriptFirst, install the config for JavaScript:
npm install --save-dev eslint-config-prettier
Then, append that config name to the extends
array in your local .stylelintrc.*
ESLint config file. Make sure to put the Prettier config last so it overrides the settings from other configs.
Here is an example .eslintrc.json
:
{ // ... extends: [ // ... 'eslint:recommended', "prettier" // Make sure this is the last ], // ... }
Now, you can run Prettier and ESLint together without any side effects. You can also run Prettier and ESLint one after another like on the command line by defining them as npm scripts. Here is how that looks in a package.json
:
{ "name": "no-worries-setup", "version": "1.0.0", "scripts": { "lint": "npx eslint src test", "lint:fix": "npm run lint -- --fix", "prettier": "npx prettier src test --check", "prettier:fix": "npm run prettier -- --write", "format": "npm run prettier:fix && npm run lint:fix", } // ... }
Now, you can run the npm run format
command to format and fix all your code in one go.
To use with VS code, install the extensions: ESLint, Prettier, and Format Code Action, and update your user settings (settings.json
), as shown below:
{ //... "editor.defaultFormatter": "esbenp.prettier-vscode", "eslint.probe": [ "javascript", "javascriptreact", "vue" ], "editor.formatOnSave": false, // Runs Prettier, then ESLint "editor.codeActionsOnSave": [ "source.formatDocument", "source.fixAll.eslint" ], "vetur.validation.template": false // ... }
First, you need to disable the editor formatting on save (editor.formatOnSave
); we want to handle everything through code actions.
In March 2020 (v1.44), the editor.codeActionsOnSave
property was updated to accept an array of code actions, which permits ordered code actions. If we install the Format Code Action extension, we can make formatting available as a code action.
So now, we can run Prettier and ESLint as code actions in whichever order we like. Sweet!
In this example, we run Prettier first with the action source.formatDocument
(it uses the default formatter), and then we run eslint --fix
with the source.fixAll.eslint
action.
The eslint.probe
property target the languages that ESLint should validate. You can use eslint.validate
if you want to see pop-up messages instead.
If you use the Vetur extension, ensure it does not do its own validation. There is a setting vetur.validation.template
, which you should not enable.
The following applications offer a unified way to run prettier
followed immediately by eslint --fix
on files:
First, install the package. This is just for JavaScript:
npm install --save-dev prettier-eslint
Next, write your own implementation to target your files and run the formatting.
Below is a basic example of formatting a string:
const format = require("prettier-eslint"); // notice, no semicolon in the original text const sourceCode = "const {foo} = bar"; const options = { text: sourceCode, eslintConfig: { parserOptions: { ecmaVersion: 7, }, rules: { semi: ["error", "never"], }, }, prettierOptions: { bracketSpacing: true, }, fallbackPrettierOptions: { singleQuote: false, }, }; const formatted = format(options); // notice no semicolon in the formatted text formatted; // const { foo } = bar
Obviously, this method requires more work to target the files, read the content, and write the output.
To use in VS Code, you can install and use the Prettier ESLint extension.
This is generally not recommended because:
You can use ESLint plugins that let you run Prettier as if it is a linter rule:
First, install the plugin. This is just for JavaScript:
npm install --save-dev eslint-plugin-prettier
Then, append the plugin(s) to the plugins
array in your .stylelintrc.*
file, for example in .eslintrc.json
:
{ "plugins": ["prettier"], "rules": { "prettier/prettier": "error" } }
Wes Bos recommended this method a few years ago. It was probably the best option at the time, but there are more options available now.
To configure for VS Code:
"eslint.alwaysShowStatus": true, "editor.formatOnSave": true, // turn it off for JS and JSX, we will do this via eslint "[javascript, javascriptreact]": { "editor.formatOnSave": false }, // tell the ESLint plugin to run on save "editor.codeActionsOnSave": { "source.fixAll": true }, // Optional BUT IMPORTANT: If you have the prettier extension enabled for other languages like CSS and HTML, turn it off for JS since we are doing it through ESLint already "prettier.disableLanguages": ["javascript", "javascriptreact"],
Prettier and ESLint can be used together very effectively. It requires some configuration, but that should be straightforward after reading this article!
Personally, I love having this setup. It’s great to have some tasks taken off your hands and reclaim some headspace. It will help you to improve your code quality and give you a more legible codebase without manual intervention.
Debugging code is always a tedious task. But the more you understand your errors, the easier it is to fix them.
LogRocket allows you to understand these errors in new and unique ways. Our frontend monitoring solution tracks user engagement with your JavaScript frontends to give you the ability to see exactly what the user did that led to an error.
LogRocket records console logs, page load times, stack traces, slow network requests/responses with headers + bodies, browser metadata, and custom logs. Understanding the impact of your JavaScript code will never be easier!
We show how to use Goxgen to scaffold a full-stack React app. See how to integrate React with Go and modify Goxygen to suit your project requirements.
Express.js is a Node.js framework for creating maintainable and fast backend web applications in JavaScript. In the fast-paced world of […]
Web components are underrated for the performance and ergonomic benefits they provide in vanilla JS. Learn how to nest them in this post.
Angular’s new defer
feature, introduced in Angular 17, can help us optimize the delivery of our apps to end users.
6 Replies to "Using Prettier and ESLint to automate formatting and fixing JavaScript"
thanks for sharing . Help me solve the problem that the vue file cannot be automatically formatted after saving
Hi,thanks for sharing in detailed,But still iam facing overriding issue of prettier with eslint
TSLint has been deprecated as of 2019.
Hi Rob,
this is a rare and great article. Well done, thank you for that.
There is just one detail in your article that makes me wonder, and it’s not explained anywhere:
Why do you suggest using the `–save-exact` option for installing prettier?
Cheers, Roman.
Sorry, just now read about why you suggest using the `–save-exact’ option. Never thought of that. Thanks and never mind!
Prettier makes code terrible because it doesn’t have fine tuning rules. It’s like repairing a smartphone with an axe.
It is enough to have a well-tuned linter and direct hands to make your code perfect.