React Setup with Prettier and ESLint

Jan 22, 2020

Create React App Prettier ESLint

Here is a quick guide for getting set up with a basic react app with eslint and prettier. No frills or fluff, just the basic steps. In this guide we’ll be using the Airbnb ESLint config which enforces the Airbnb JavaScript Style Guide. Another popular option is to use the Google ESLint config which enforces the Google JavaScript Style Guide. To use this instead, replace every instance of airbnb with google (in the installation and the .eslintrc file).

Remember, linters are supposed to work for you. So if you run into any linting rules that annoy you or anyone on your team, turn them off! The easiest way to disable them is by adding "rule-name": 0 or "rule-name": off to the "rules" field of your .eslintrc.

Installation

To setup your new react app, we will be using the wonderful package create-react-app. First, open a terminal run these commands to install all of the packages you will need:

npx create-react-app app-name
cd app-name
npm i -D eslint eslint-config-airbnb eslint-config-prettier eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-prettier eslint-plugin-react eslint-plugin-react-hooks prettier

Setup ESLint

  1. Add an .eslintignore file in the root with /src/serviceWorker.js as the only line

  2. Remove the "eslintConfig" field from your package.json

  3. Add an .eslintrc file to the root with the following:

{
  "env": {
    "browser": true,
    "es6": true,
    "mocha": true,
    "jest": true
  },
  "extends": ["airbnb", "prettier", "prettier/react"],
  "globals": {
    "Atomics": "readonly",
    "SharedArrayBuffer": "readonly",
    "window": true,
    "document": true,
    "localStorage": true,
    "FormData": true,
    "FileReader": true,
    "Blob": true,
    "navigator": true
  },
  "parser": "babel-eslint",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 2020,
    "sourceType": "module"
  },
  "plugins": ["react", "prettier", "react-hooks"],
  "rules": {
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn",
    "react/jsx-filename-extension": [
      1,
      {
        "extensions": [".js", ".jsx"]
      }
    ],
    "import/imports-first": ["error", "absolute-first"],
    "import/newline-after-import": "error",
    "react/prop-types": 0,
    "no-console": 0
  }
}
  1. Add the following script to your package.json for easy linting:
"lint": "eslint src/**/*.{js,jsx}"

Setup prettier

  1. Add a .prettierrc file with the following:
{
  "tabWidth": 2,
  "singleQuote": true
}

In the case of the tab width setting, the default it 2 but sometimes an editor’s defaults can override it if you do not set it manually. If you would like to change any other options to match your liking, checkout the options page on the prettier website

  1. If you would like to easily format your entire project, add the following to the to the "scripts" field of your package.json.
"format": "prettier --write \"src/**/*.{js,jsx,ts,css,less,scss,vue,json,gql,md}\""

This will format all of the filetypes prettier is compatible with in your src directory.

If you would like to add the full default prettierrc (with single quotes set to true) here are all of the options:

{
  "printWidth": 80,
  "tabWidth": 2,
  "useTabs": false,
  "semi": true,
  "singleQuote": true,
  "quoteProps": "as-needed",
  "jsxSingleQuote": false,
  "trailingComma": "none",
  "bracketSpacing": true,
  "jsxBracketSameLine": false,
  "arrowParens": "avoid",
  "requirePragma": false,
  "insertPragma": false,
  "proseWrap": "preserve",
  "htmlWhitespaceSensitivity": "css",
  "endOfLine": "auto"
}

Also here’s the prettier config used by the official react repository if you’d like to use something like that instead!

{
  "bracketSpacing": false,
  "singleQuote": true,
  "jsxBracketSameLine": true,
  "trailingComma": "es5",
  "printWidth": 80,
  "parser": "babylon"
}

Add absolute imports

With the release of create-react-app 3 you can now use absolute imports for your components. If you would like to setup absolute imports to your src directory, add a new file called jsconfig.json to the root and paste the following into it:

{
  "compilerOptions": {
    "baseUrl": "src"
  },
  "include": ["src"]
}

Then add the following to your .eslintrc

"settings": {
  "import/resolver": {
    "node": {
      "moduleDirectory": ["node_modules", "src/"]
    }
  }
}

Now you can import files using their path relative to the src directory

import Button from 'components/button';

Bonus script

If you want an easy way to run a clean install if for some reason things stop working, here is another nice script I like to use

"clean-install": "rm -rf node_modules && rm package-lock.json && npm i"