Creating a Sane ESLint Config

Jan 24, 2020

5 min read

If you’ve spent any amount of time configuring ESLint — the most widely used linting tool for JavaScript — you’ll know you can easily get lost in it.

But there are also formatters like Prettier, which are excellent but often fight with linters.

I strongly believe that a solid linting setup con save you tons of time and catch many bugs much sooner. The first time you save a file and it auto-formats like this, you'll see how powerful it is:

GIF showing linting / formatting tools fixing code automatically

After much trial and error, I’ve put together and setup I use for every project and published it for easier use.

1. Set Up Your Project

Make a new directory for your linting config and run either yarn init -y or npm init -y to create a package.json.

When publishing an ESLint config, all we need to export is an ESLint config object.

So let's make an index.js file with the following content:

1module.exports = {
2
3}

And then install ES Lint:

1yarn add eslint
2# or
3npm install --save eslint

2. Find a setup to use as a base

Instead of hand-picking every linter rule, I would strongly suggest finding an existing config and extending it.

I would strongly recommend using React's official eslint-config-react-app, but if you want to find more options you can check out this repo..

For many years, I was a strong advocate for the AirBNB linting config, but recently I realized I'd been turning off many of their opinionated rules.

I finally removed it after reading Dan Abramov’s advice on the topic:

Don’t assume that whatever you or something somebody else added to your lint config a year ago is a “best practice”. Question it and look for answers. Don’t let anyone tell you you’re not smart enough to pick your lint rules.

If you do prefer more rules, then more power to you! But if you find they're getting in your way and not helping catch bugs, it might be time to part ways.

In case you do go with a different config (and you use React), make sure to include this jsx accessibility plugin. Even if your primary focus isn't accessibility, I believe every project should have this by default even if it the rules seem frustrating at first.

Once you have your base, update your index.js:

1module.exports = {
2 extends: ['react-app'] // or whatever you chose as your base config
3}

3. Add Your Formatter

Now that we have our linter set up to catch code-related bugs, we're going to use Prettier to consistently format our code.

First add these packages:

1yarn add prettier eslint-config-prettier eslint-plugin-prettier
2# or
3npm install --save prettier eslint-config-prettier eslint-plugin-prettier

Here's what we've added:

  • prettier - Used to run the formatting
  • eslint-config-prettier - Turns off ESLint formatting rules that would conflict with Prettier
  • eslint-plugin-prettier - Allows your ESLint config to run prettier

While the setup is a bit cumbersome, this will allow you to just use ESLint to lint and format your code and keep you from having to use Prettier separately.

Now, update your index.js again:

1module.exports = {
2 extends: [
3 'react-app', // or whatever you chose as your base config
4 'plugin:prettier/recommended', // this will stop Prettier and ESLint from fighting over fixes
5 'prettier/react', // optionally include this if you use React
6 ],
7 'plugins': ['prettier'],
8 'rules': {
9 // make Prettier return errors
10 'prettier/prettier': [
11 'error',
12 {
13 // Optional Prettier config changes
14 trailingComma: 'es5',
15 singleQuote: true,
16 printWidth: 80,
17 },
18 ],
19 }
20}

4. Publishing

To publish this config, you'll need to update a few things in your package.json:

1{
2 // must start with "eslint-config" for other people to include it
3 "name": "eslint-config-my-cool-config",
4 // this must be increased every time you publish
5 "version": "1.0.0",
6 // this tells node where to find the main module when it's installed
7 "main": "index.js",
8}

Then, make sure you have an account with NPM and follow their guide to publish a package.

Once it's successful, you should be able to go to any Javascript project using NPM and run:

1yarn add eslint-config-my-cool-config
2# or
3npm install --save eslint-config-my-cool-config

And then extend your own config by making a .eslintrc file in the root of your project:

1{
2 // don't include the `eslint-config-` part when extending
3 "extends": ["my-cool-config"]
4}

5. Super Charge Your Text Editor

If you aren't sold on the benefits of all this setup yet, this is where you'll start to see how helpful this is.

Your text editor should have an official ESLint integration, but for this example we're going to set it up in VS Code.

Install the VSCode ESLint extension and then open the command pallette (cmd / ctrl + shift + p) and type settings json and select Open Settings (JSON).

At the end of the settings JSON, add this:

1"editor.codeActionsOnSave": {
2 "source.fixAll.eslint": true
3},

Now when you save a file it should automatically run eslint fixes, which also include our Prettier formatting and save you hours of headache in the future.

Finally, don't forget that if you end up changing your mind about any rules, you can always override them in your .eslintrc project's config file:

1{
2 // don't include the `eslint-config-` part when extending
3 "extends": ["my-cool-config"],
4 "rules": {
5 // 0 turns the rule off, 1 emits a console warning and 2 throws an error
6 "overly-opinionated-rule": 0
7 }
8}

Or change them in your custom config package (just remember you'll have to publish it afterward):

1{
2 "extends": ["base-config"],
3 "rules": {
4 "overly-opinionated-rule": 0
5 }
6}