146

When I run npx create-react-app ..., a bare-bone React project is being created for me. When I then peek into package.json, there seems to be some evidence of ESLint to be present, as there is this:

"eslintConfig": {
  "extends": "react-app"
},

However, whenever I install ESLint as a dev dependency and configure it -- as I usually do --, VS Code seems to pick it up. In this case, VS Code does not seem to recognize that there is any kind of linter present/configured. This is not super surprising, as ESLint is not a dependency of the React project I just generated -- at least not according to package.json. When I try to run eslint . within the project's root directory, it says "command not found".

I tried to breathe life into this ESLint configuration by expanding it, so now I have this:

"eslintConfig": {
  "extends": ["react-app", "eslint:recommended", "google"],
  "rules": {
    "semi": ["error", "always"],
    "quotes": ["error", "double"]
   }
},

This changes nothing. I manipulated the source code in a way that I know it violates the above configuration, yet, I have not been signaled any wrongdoing.

This leads me to a simple question: Do projects generated by create-react-app come with some kind of ESLint configuration, and, if so, how do I enable and extend it correctly?

As I am being referred to the number one Google hit that comes up when searching "create react app eslint" -- which I have obviously read --, let me clarify what I mean:

ESLint is obviously integrated into Create React App in a different way than it would be if it had been manually added to the project using like so. This is not only evident by the sheer number of people who post about their struggles of getting the two to work together. This is also evident as...

  • ...one cannot run the eslint command in the project root.
  • ...ESLint does not seem to be a dependency within package.json.
  • ...VS Code doesn't pick up that there is ESLint present.
  • ...there is no .eslintrc.* file in the project root.
  • ...etc.

So: How do I go about ESLint in the context of Create React App? For starters: How do I run it? How do I expand it? And why does VS Code not pick it up -- even though it usually notices the presence of ESLint?

Ismael Padilla
  • 5,246
  • 4
  • 23
  • 35
typeduke
  • 6,494
  • 6
  • 25
  • 34
  • 5
    This seems like a vscode linter configuration issue. I would review/play with the package settings. I see warnings in Atom automatically (with my properly configured linter settings I already have set up). If you want to see what CRA does under the hood, you can run `yarn eject`. Also, `eslint SOMETHING` only works if you have eslint installed globally. Try `yarn eslint src` or `npx eslint src`. If you're interested in customizing your ESLint config with CRA, check out my blog post: https://medium.com/hackernoon/a-simple-linter-setup-finally-d908877fa09 – JBallin Jan 07 '20 at 18:02
  • _How is ESLint integrated into Create React App?_ – It's via `react-scripts` in `package.json`. Try for example [`npm ls eslint`](https://stackoverflow.com/a/66438578). ~ * ~ _How can I run the eslint command in the project root?_ – It's [`npx eslint . --ext .js`](https://stackoverflow.com/a/71423006). ~ * ~ _VS Code doesn't pick up that there is ESLint present_ – Yes it does! Maybe [add `"eslint.nodePath": "C:\\Program Files\\nodejs"`, to `settings.json` in VS Code](https://stackoverflow.com/a/46999435). ~ * ~ [Answers to your questions](https://stackoverflow.com/a/71423006). – Henke Mar 25 '22 at 11:01

4 Answers4

82

Yes, create-react-app comes with eslint config.

How do I enable and extend it correctly?

You can check how to extend it here.

{
  "eslintConfig": {
    "extends": ["react-app", "shared-config"],
    "rules": {
      "additional-rule": "warn"
    },
    "overrides": [
      {
        "files": ["**/*.ts?(x)"],
        "rules": {
          "additional-typescript-only-rule": "warn"
        }
      }
    ]
  }
}

How do I enable it?

You need to integrate it with your IDE.

How do I run it?

After integrating it, an eslint server will be running in the background and will enable linting for your IDE (sometimes restarting IDE required).


I checked all your claims after running npx create-react-app example:

...one cannot run the eslint command in the project root.

You can:

enter image description here

eslint is installed as part of the project dependency, just by running eslint globally (eslint [cmd]) you need to ensure it installed globally (not recommended).

...ESLint does not seem to be a dependency within package.json.

Why should it be? That's why you using a starter like CRA. It's an inner dependency, you don't need to worry about it, that's CRA's job.

...VS Code doesn't pick up that there is ESLint present.

It does, check the OUTPUT tab and look for ESLint to see the server's output.

enter image description here

...there is no .eslintrc.* file in the project root.

You get the default configuration from CRA (which is hidden from you for focusing on coding). Add such file if you want to override it (you can also extend it, check the docs).


Its very useful to understand what eslint actually is and how we use it React development, check out related question "Do React hooks really have to start with “use”?".

Dennis Vash
  • 50,196
  • 9
  • 100
  • 118
  • 1
    Need to integrate it with extensions and settings via `settings.json` – Dennis Vash Jan 07 '20 at 17:24
  • If you open a console in DEBUG mode in vscode, you can check the `eslint` tab see it logs (after fixing errors you will get linting enabled) – Dennis Vash Jan 07 '20 at 17:25
  • I think you struggling to integrate it with vscode, why to downvote? – Dennis Vash Jan 07 '20 at 17:57
  • Sadly, none of the things you write help my situation. I don't have `yarn`, so I still cannot run `eslint`, and after creating a couple new projects just the way you stated, opening up those projects in VS Code still results in an empty "Output" console. Thank you for your efforts, though. – typeduke Jan 07 '20 at 18:07
  • 1
    As I said, you need to integrate it with vscode... Cheers. And "I don't have yarn, so I still cannot run eslint", you can run it however you want, it will work – Dennis Vash Jan 07 '20 at 18:09
  • Regarding the downvote: Trying to earn easy points by doing one second of googling, and then posting the first link that comes up as an answer -- that's just lazy, insulting, and should not be rewarded. Now that you revised your answer and actually spent some time trying to help me, I will vote your answer back up. Once it actually solves my problem, I will of course accept it as *the* answer. :) – typeduke Jan 07 '20 at 18:11
  • How did you integrate it? The docs that you shared the link to say that I just have to install and enable the ESLint plugin for VSCode -- I did. Also, I tried `npm eslint .`, and it complained that it didn't know about `eslint`. – typeduke Jan 07 '20 at 18:15
  • Well.. you need to install eslint globally for `npm eslint` to work, and obviously I can't guess how you integrated it... Which steps you took... What are your vscode settings... Its an entirely new question. – Dennis Vash Jan 07 '20 at 18:39
  • So how do I "integrate it with VS Code"? Since it normally picks up any present ESLint configuration, having to manually wire it up is not straightforward. – typeduke Jan 07 '20 at 22:15
  • 3
    No matter what I added to `eslintConfig`, I cannot alter the built-in rules. Have you actually been able to do so? – David Harkness Jan 12 '21 at 19:28
  • Be sure you dont have other eslint file which overrides it, and try openning a question. And yes, it works for me. – Dennis Vash Jan 14 '21 at 05:14
47

To expand on the top comment's answer:

...ESLint does not seem to be a dependency within package.json.

Why should it be? That's why you using a starter like CRA. It's an inner dependency, you don't need to worry about it, that's CRA's job.

A project created with create-react-app will have react-scripts as a dependency.

react-scripts has eslint installed as a dependency, as seen in react-scripts package.json.

You can see if a package is installed (and where) by running npm ls <package> in your project root.

npm ls eslint shows:

└─┬ react-scripts@4.0.3
  └── eslint@7.21.0 

This shows the dependency tree that we manually investigated by looking in GitHub at react-scripts.

So - a project made with create-react-app does come with eslint. As it is a dependency, not something globally installed, then it must be ran with a npm script.

This is why running eslint . in your terminal does not work, but using

    "lint": "eslint .",

then npm run lint does. (though you may with to make the command eslint --ignore-path .gitignore . due to a current bug).

Similarly, the eslint configs are installed in react-scripts, then referenced in the default project output's own package.json.

glenrothes
  • 1,543
  • 1
  • 14
  • 17
17

Every Create React App depends on ESLint via react-scripts

I believe I have answered most of your questions in the Sections below.
Here is a summary.

Do projects generated by create-react-app come with some kind of ESLint configuration?

– Yes, ESLint gets installed and configured.
(Section 1 below.)

How do I enable and extend it correctly?

– It is already enabled. You expand it exactly as you already suggested in the question, except that you don't need to change anything under the extends attribute.
(Sections 1 & 2 below.)

ESLint is obviously integrated into Create React App in a different way than it would be if it had been manually added to the project using
[npm install eslint --save-dev and npm init @eslint/config ?]

No, it's not.
Installing ESLint once again (npm install eslint --save-dev) does add
  "devDependencies": {
    "eslint": "^7.32.0"
  }
to package.json. But that's all it does.
The practical implications are none, because "eslint": "^7.32.0" is already installed as a dependency via react-scripts.

I advise against running npm init @eslint/config, which is a command that creates a .eslintrc.* configuration file. If you do run this command, consider moving all the contents of .eslintrc.* to package.json under eslintConfig.
Then delete the problematic .eslintrc.* file. It might save you a lot of pain. 1
(Sections 1 & 5 below.)

one cannot run the eslint command in the project root [?]

Yes, you can!
It's npx eslint . --ext .js
(Section 4 below.)

ESLint does not seem to be a dependency within package.json [?]

Yes, it is!
The dependency is indirect as react-scripts depends on ESLint and on a lot of other packages.
(Section 1 below.)

VS Code doesn't pick up that there is ESLint present [?]

Yes, it does! Run npx eslint . --ext .js.
If you get at least one warning or error, then you know you should see it in VS Code as well.
(Section 3 below – check out the gotchas.)

there is no .eslintrc.* file in the project root.

Be glad there isn't! And don't put one there either!
(Section 5 below.)

0. Prerequisites

In order to be able to answer your questions, I created an App : 2

npx create-react-app how-is-eslint-integrated-into-create-react-app

I then deleted all files in the src subdirectory, and inserted my own versions of App.js, App.css, index.js, index.css, along with a components subdirectory that contains a Button component.

In package.json I deleted a few irrelevant lines, such as "version": "0.1.0",
and "private": true, and the production attribute under browserslist.

The resulting package.json :

{
  "name": "how-is-eslint-integrated-into-create-react-app",
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.2",
    "@testing-library/react": "^12.1.3",
    "@testing-library/user-event": "^13.5.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-scripts": "5.0.0",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "development": [
      "last 1 chrome version"
    ]
  }
}

When you wrote your question a little more than two years ago, the eslintConfig attribute was

,
  "eslintConfig": {
    "extends": "react-app"
  }

whereas nowadays, it's

,
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  }

I will assume that this change makes no difference for the issues and questions you bring up
(unless someone proves me wrong).

Another difference over the past two years – apart from the obvious changes in version numbering – is the added web-vitals attribute :

,
    "web-vitals": "^2.1.4"

which is a package for measuring performance metrics in JavaScript. 3
Thus, web-vitals is irrelevant for your questions.

You can download the resulting zip file containing all necessary project files.

Once downloaded – from the root of the project (directory Q59633005) – run npm install.
Expect it to take anytime between 4 and 11 minutes to complete.

Next run npm start.
Expect your default web browser to open and – after hitting F12 – display : 4

'npm start' opens the App in the default web browser

Now close the server from the terminal by hitting Ctrl+C.

Take a look inside App.js. The contents are :

// App.js
import React, { useCallback, useState } from 'react';
import "./App.css";
import Button from "./components/UI/Button/Button"

function App(unUsedArgument) {
  const [unUsedVariable, setShowParagraph] = useState(true);
  const showParagraphFcn = useCallback(() => {
    setShowParagraph((prevToggle) => !prevToggle);
  },[]);
  console.log("App RUNNING");
  return (
    <div className="app">
      <h1>Hi there!</h1>
      <Button onClick={showParagraphFcn}>A Button</Button>
    </div>
  );
}
export default App;

I now have project to help answer your questions.

1. ESLint in Visual Studio Code

VS Code does not seem to recognize that there is any kind of linter present/configured. This is not super surprising, as ESLint is not a dependency of the React project I just generated -- at least not according to package.json.

The npx create-react-app ... does indeed install ESLint.

ESLint is deeply buried in the dependency tree of the react-scripts package.
The top node for ESLint in react-scripts is eslint-config-react-app. 5

Some basic configuration is also part of the deal. So ESLint does work out of the box.

VS Code shows a warning for unUsedVariable on line 7 of App.js
(but for some reason not for unUsedArgument on line 6).

In VS Code, expect to see :

ESLint works out of the box for Create React App. VS Code shows 1 warning.

2. How to expand ESLint

How do I expand [ESLint in a Create React App]?

To expand ESLint, you need to add rules under eslintConfig in package.json, exactly as you have already suggested in your question.

To try your example, replace

,
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  }

with

,
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ],
    "rules": {
      "semi": [
        "error",
        "always"
      ],
      "quotes": [
        "error",
        "double"
      ]
    }
  }

After restarting VS Code, it still shows the warning for unUsedVariable on line 7, but now also an error on line 2 for having single quotes instead of double quotes, and an error on line 4 for the missing semicolon at the end of the line.

With ESLint 'rules' set, VS Code shows a warnings and errors

This shows that you have already correctly answered how to expand Create React App.

For another example, consider looking at the package.json | eslintConfig of this answer.


3. Some gotchas with VS Code

Still don't see the errors and warnings as in the screenshot above? It might not work, I know.

Three gotchas to check :

4. A much faster way to check if ESLint works

For starters: How do I run it?

Answer: 6

npx eslint . --ext .js

11 errors and 1 warning when running ESLint from the command line

The first four lines of the response:

C:\stackexchange\stackoverflow\linting\eslint\Q59633005\src\App.js
 2:46 error    Strings must use doublequote                         quotes
 4:51 error    Missing semicolon                                    semi
 7:10 warning  'unUsedVariable' is assigned a value but never used  no-unused-vars

– In less than 10 seconds, you get the same information about errors and warnings as in VS Code.

5. A word of warning

If you don't like hard-to-debug errors such as
Parsing error: The keyword 'import' is reserved
then don't use any .eslintrc.* files at all. 1

In my experience, you can put all ESLint configurations under eslintConfig in package.json as described in Section 2 above. – You won't need any .eslintrc.* files.

References


1 If you want to know why, compare this long answer with this short answer.

2 I'm on Windows 10, but I expect all the commands provided here to work just as fine on both Linux and macOS – except where otherwise stated.

3 You can find that out by running npm ll.

4 I use Google Chrome Version 98.0.4758.102, 64-bit. Running on Windows 10.

5 I got this information from NPMGraph - Visualize NPM Module Dependencies.

6 Alternatively, use the first line below if you are on Microsoft Windows (backslashes).
Use the second line if you are on Linux or macOS (forward slashes).

node*modules\.bin\eslint . --ext .js
node*modules/.bin/eslint . --ext .js
Henke
  • 4,445
  • 3
  • 31
  • 44
0

your question makes perfect sense. I found that this works:

  • run ESLint in VS Code with 'npx eslint' (shows all the options) or also 'npx eslint .'
  • add a script to package.json "lint": "eslint ." and then use 'npm run lint'

I did not have a problem with integrating ESLint to VS Code. After installing VS Code extension for ESLint, I automatically see the warnings/errors in VS Code under Problems.

AuS
  • 9
  • 1