DEV Community

Dor Shinar
Dor Shinar

Posted on • Edited on • Originally published at dorshinar.me

Linting Your React+Typescript Project with ESLint and Prettier!

Lately we started a new project at work, written in React + Typescript. Of course, like any other project we wanted it to be automatically linted and style checked, so we don’t have to worry about that ourselves.

The two largest, most familiar tools for Typescript linting are TSLint and ESLint. While ESLint exists for a longer period, it never had proper, production ready support for Typescript, so most Typescript projects were written with TSLint.

I was tasked with finding the right tool for our project. It is a completely new project, so no code migration or rule migration is necessary. First I looked at TSLint. It has great support for TypeScript, plus an excellent VSCode extension. It definitely seemed like the right choice, until I stumbled upon this article. I found it quite interesting, but If you don’t feel like reading, I’ll give you the gist here.

On Microsoft’s TypeScript roadmap for the first 6 months of 2019 they provide an entire section about the growing demand among Typescript developers to have proper ESLint support. Furthermore, they talk about how ESLint’s architecture is more suitable to their needs, and finally they say they intend to fully embrace ESLint as the linting tool for the Typescript project, and guarantee to improve ESLint’s Typescript support in an effort to match TSLint’s support.

The rest of the article talks about a new repository that aims to contain the core projects needed for ESLint to be able to parse and lint Typescript code.

After some further testing and comparisons, I believe that ESLint is in fact the right tool for the job (not only because I trust the Typescript’s team 😉).

Update - May 10th:
Create React App v3 started linting TypeScript projects with @typescript/eslint as well, so I firmly believe I've made the right choice.

Wow, this was a long introduction. Let’s get coding!

First things first, we need to create a new project. For this article I’ll be using create-react-app, but whichever boilerplate you choose (or create on your own) will do just fine.

npx create-react-app eslint-react-intro --typescript

For those who are not familiar, npx is a tool first introduced with node@5.2.0. In a sentence, it allows us to run binaries of npm packages with ease without global installation. It actually does a little more than that, you’re encouraged to read more in this great article.

Now we have a basic react app, but we’re here for the linting, so let’s install a few dependencies:

npm i -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin

eslint is an obvious dependency, but what are @typescript-eslint/parser and @typescript-eslint/eslint-plugin?

ESLint by default depends on a parser to read Javascript code and “translate” it to a language ESLint can understand (also called ESTree). By default ESLint uses Espree, which is great for reading JS code, but fails to read Typescript. @typescript-eslint/parser is an alternative parser that can read Typescript code and produce said ESTree, so we can tell ESLint to use it instead. @typescript-eslint/eslint-plugin is simply a list of rules you can turn on or off.

So we have our basic dependencies, lets configure ESLint.

ESLint has a nice interactive tool that you can run:

eslint --init

It will ask you a series of questions to help you configure it. I prefer defining the configuration on my own, so I’ll create the configuration file — .eslintrc.js (ESLint supports JSON and YAML as well). with the following content:

Now we’ll make sure ESLint will work with the packages we’ve installed. We need to configure the parser, make sure the plugin is configured and the rule set applied is extended by the ones we’ve downloaded. Modify the file to look like so:

We’ve told ESLint to parse out Typescript code properly, and to use a recommended set of rules (under the ‘extends’ field, this part is optional) from an installed plugin.

Next we’ll add basic rules for React, courtesy of the Create React App development team. Add them to the file like so:

So we have linting for both Typescript and React, let’s add a code formatter. Prettier is my weapon of choice, as it does a great job at detecting and fixing style errors, and has superb ESLint integration.

To add Prettier support, we need to install a few dependencies:

npm i -D prettier eslint-config-prettier eslint-plugin-prettier

eslint-config-prettier will disable any linting rule that might interfere with an existing Prettier rule, and eslint-plugin-prettier will run Prettier analysis as part of ESLint.

Let’s add them to our ESLint config:

Go ahead, write poorly formatted code and you’ll see how Prettier is yelling at you. You are welcome to add your own custom Prettier configuration!

Basically we’re done. It should all work nice and easy, allowing us to keep our code linted and formatted like pros!

ESLint and Prettier are very powerful tools, and my article scratches the surface of their abilities, but it should get you started easily. I encourage you to explore more abilities and plugins that are available.

If you’d like a basic working project with my configuration, you’re welcome to take a look here.

A little bonus for those who stuck around and work with the all-mighty Visual Studio Code (my go-to IDE for web development) — ESLint and Prettier both have excellent integration with VSCode.

First, install the ESLint and Prettier VSCode extensions:

ext install esbenp.prettier-vscode dbaeumer.vscode-eslint

Both come with various configuration options to play with, but their defaults are pretty good. The only thing we need to change is ESLint’s default behavior to only inspect *.JS and *.JSX files. Add this configuration option to your settings:

the autoFix key speaks for itself I believe, ESLint will try to fix all the errors it can (some are impossible to fix automatically). You can of course disable it if you prefer fixing the errors yourself. Now you’ll see all of the errors right in your IDE, so no one can miss them. I recommend combining ESLint with Husky to make linting a must for every commit, but that’s up to you and your team.

Thank you for reading!

This article is a result of a quite frustrating personal experience trying to configure ESLint with no proper guide to help me through (except for the packages’ documentations). After struggling for several hours for something that felt like it should have taken five minutes, I decided to write this article so other developers won’t face the same struggle.

This is my first dev.to article, be gentle with me 😄 I welcome constructive criticism and general comments.
This article was published here as well.

Top comments (15)

Collapse
 
nareshjbhatia profile image
Naresh Bhatia

Great article Dor! Quick question - how do you run eslint? From the command line? Have you found any way to tightly integrate with create-react-app? In other words, npm start should run your linter instead of create-react-app's.

Collapse
 
dorshinar profile image
Dor Shinar

Thank you!
I've looked into that a while ago. There's an issue on the create-react-app GitHub about that (I'll link it when I find it), basically they say that the ESLint configuration react-scripts uses cannot be altered, and it contains only rules that might prevent bugs (such as unused variable).
I run it with the command line, and I've set up git hooks to run it on every commit (using husky and lint-staged).

Collapse
 
nareshjbhatia profile image
Naresh Bhatia

Thanks for the response, Dor. Running husky/lint-staged is exactly what I am thinking of.

BTW, I am aware of the issue on the CRA repo: github.com/facebook/create-react-a.... See my comment on it related to this.

Thread Thread
 
dorshinar profile image
Dor Shinar

I was actually referring to this issue. Dan Abramov seemed pretty adamant there.

Thread Thread
 
nareshjbhatia profile image
Naresh Bhatia

Ah, thanks for digging it up!

Collapse
 
bartekpacia profile image
Bartek Pacia

Great article, however in my case it didn't work. Running ./node_modules/.bin/eslint . just didn't output anything. After a few hours of cursing the universe, I found a solution. ESLint works out-of-the-box only for .js, so I had to tell it to lint .ts as well. It can be done by adding --ext ts.

./node_modules/.bin/eslint --ext ts .

Hope it helps somebody!

Collapse
 
michalpuskel profile image
Michal Puškel • Edited

Thank you, great tutorial!,
finally my ESlint works for TS almost properly.

Though, for me there is some rule conflict between eslint and prettier
and it either always inserts once 2 spaces on next file save 4 spaces. Or some weird tab is inserted.

Anyone same problem? How to fix, please?

I tried literally every possible combination of settings for
vscode workspace:
codepile.net/pile/83MNXYDz
prettier:
codepile.net/pile/ZwNz6vwE
eslint:
codepile.net/pile/4Q7Y0BxM

I have macOS Sierra 10.12.6
VSCode v. 1.35.1.

screenshot:
ibb.co/9Y7xSVp

Collapse
 
michalpuskel profile image
Michal Puškel

SOLVED:
youtube.com/watch?v=mg_pDqszL3g

add rule "@typescript-eslint/indent": "off" to .eslintrc

{
  "parser": "@typescript-eslint/parser",
  "extends": [
    "plugin:@typescript-eslint/recommended",
    "react-app",
    "plugin:prettier/recommended"
  ],
  "plugins": ["@typescript-eslint", "react"],
  "rules": {
    "no-console": "warn",
    "no-debugger": "warn",
    "@typescript-eslint/indent": "off"
  }
}

Collapse
 
dorshinar profile image
Dor Shinar

I'm sorry I didn't get a chance to look into your problem, but I'm glad you figured it out. I've faced the same issue and solved it this way too.

Thread Thread
 
michalpuskel profile image
Michal Puškel

No problem, I'm glad it works! Thanks!

Collapse
 
nickytonline profile image
Nick Taylor • Edited

Great post. I'm using eslint, prettier and TypeScript for my blog. I'm also a big fan of husky.

Here's my repository if you're interested.

GitHub logo nickytonline / iamdeveloper.com

Source code for my web site iamdeveloper.com

iamdeveloper.com

Netlify Status

Hey there, I'm Nick and this is my site's source code. This site started off as a clone of the Netlify CMS Gatsby Starter (check it out!). Since then, I've tweaked it a lot and converted the codebase to TypeScript.

Feel free to peruse the code and/or fork it. 😉

Thanks to all the wonderful projects that made it possible to build this blog.

To get up and running:

  • clone the repository by running git clone git@github.com:nickytonline/www.iamdeveloper.com.git or git clone https://github.com/nickytonline/www.iamdeveloper.com.git
  • run npm install
  • run npm run develop to get up and running with the Gatsby development server.
  • Since the project uses Babel and not TypeScript as the compiler, a separate process is required to run type checking. Open another terminal and run npm run type-check:watch
  • If you're curious about why the Netlify CMS admin…

I wasn't aware of 'plugin:@typescript-eslint/recommended'. I'm going to add that to my eslint config. Thanks and looking forward to your next post!

Collapse
 
dorshinar profile image
Dor Shinar

Thank you very much! I'll be sure to check it.

Collapse
 
fentech profile image
Joe Fensler • Edited

I was going through the same thing creating multiple TypeScript + React apps with the same configuration as you've spelled out so I created and npx package to do just that: npmjs.com/package/create-react-typ....

Collapse
 
dorshinar profile image
Dor Shinar

It looks really cool! I'll be sure to check it out when I get the chance.

Collapse
 
robertcoopercode profile image
Robert Cooper

Hey, great article on the setup of eslint & prettier for a TypeScript project. I was planning on writing a article on this exact topic, but you've pretty much covered everything on the topic 👍🏼.