How to set up ESLint with StandardJS for a new React Native/TypeScript project
Tags: eslint, reactnative
Published: 2021-01-31 12:36:53

---
title: How to set up ESLint with StandardJS for a new React Native/TypeScript project
published: true
description: 
tags: eslint, reactnative
//cover_image: https://direct_url_to_image.jpg
---

If you have a situation like below, this walkthrough is for you!

✔ You have a React Native project
✔ It uses TypeScript
✔ You want to set up ESLint
✔ You want to use Standard JS 

_NOTE: If you don't know about Standard JS, check out their rules [here](https://standardjs.com/rules.html). Notable rules include using two spaces for indentation and not using semicolons at the end of lines._

This tutorial walks you through installing and configuring ESLint, and setting up Github Actions so ESLint runs every time you push your code.

Step-by-step commit list: 
{% github https://github.com/risafj/StorybookExampleReactNativeTS/pull/1 %}

# Steps
## 1. Install ESLint, and its plugins for React and React Native

Simply run below!

```
yarn add -D eslint eslint-plugin-react eslint-plugin-react
```

Docs: https://github.com/intellicode/eslint-plugin-react-native#installation

## 2. Install ESLint plugins for Standard and TypeScript

Now run this:

```
yarn add -D eslint@7 eslint-plugin-promise@4 eslint-plugin-import@2 eslint-plugin-node@11 @typescript-eslint/eslint-plugin@4 eslint-config-standard-with-typescript
```

Why do we need so many dependencies? Good question, the docs mention why.

Docs: https://github.com/standard/eslint-config-standard-with-typescript#usage
> This long list of dependencies includes:
1. ESLint
2. Peer dependencies of eslint-config-standard
3. @typescript-eslint/eslint-plugin; ESLint rules for TypeScript.

## 3. Disable Prettier's rules that conflict with ESLint

If you tried configuring and running ESLint at this point, you will probably find that some of its rules conflict with Prettier (which comes pre-installed in React Native projects). We can use a package called [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier#readme) to turn off conflicting Prettier rules (I found this solution in this helpful [Github comment](https://github.com/facebook/react-native/issues/26903#issuecomment-581074476)).

Install as below:
```
yarn add -D eslint-config-prettier
```

We will configure ESLint to use this package in step 5. Ok, we're finally done installing the necessary packages!

## 4. Configure .eslintignore

Create a file called `.eslintignore` in your project root. This file is like `.gitignore` for ESLint - you should list anything that you don't want checked by ESLint. As an example, here is my `.eslintignore`:

```
node_modules/
babel.config.js
metro.config.js
```

## 5. Configure .eslintrc.js

There are a few file extensions that you can use for ESLint config, like `.js` and `.json`. We will go with `.js` here.
Find or create a file called `.eslintrc.js` in your project root. Then, configure as below (minus the comments):

```js
module.exports = {
  root: true,
  extends: [
    '@react-native-community/eslint-config', // Default RN config
    'standard-with-typescript', // Installed in step 2
    'eslint-config-prettier' // Installed in step 3
  ],
  parser: '@typescript-eslint/parser', // Installed in step 2
  plugins: [
    '@typescript-eslint', // Installed in step 2
    'react', // Installed in step 1
    'react-native' // Installed in step 1
  ],
  'parserOptions': {
    'ecmaFeatures': {
      'jsx': true
    },
    'project': './tsconfig.json' // Required for Standard plugin
  },
  'env': {
    'react-native/react-native': true
  },
  'rules': {
    'prettier/prettier': 'off', // Turn off prettier
    // These are the rules that I use
    'react-native/no-unused-styles': 'warn',
    'react-native/no-inline-styles': 'error',
    'react-native/no-raw-text': ['warn', {
      skip: ['CustomText']
    }],
    'react-native/no-single-element-style-arrays': 'warn',
    'object-curly-spacing': 'error',
    '@typescript-eslint/explicit-function-return-type': 'off',
    '@typescript-eslint/strict-boolean-expressions': 'off',
    '@typescript-eslint/no-floating-promises': 'off',
    '@typescript-eslint/no-unused-vars': 'off',
    '@typescript-eslint/require-array-sort-compare': ['error', {
      ignoreStringArrays: true
    }],
    'react/jsx-curly-spacing': ['error', {
      when: 'always',
      allowMultiline: true,
      children: true
    }],
    'eol-last': ['error', 'always'],
    'no-multiple-empty-lines': 'error',
    semi: ['error', 'never'],
    // Indent with 2 spaces
    indent: ['error', 2],
    // Indent JSX with 2 spaces
    'react/jsx-indent': ['error', 2],
    // Indent props with 2 spaces
    'react/jsx-indent-props': ['error', 2]
  }
  }
}
```

As for specific ESLint rules, it depends on personal preference so I'll leave it up to you. If you want to see my config as a reference, you can find it here:
https://github.com/risafj/StorybookExampleReactNativeTS/blob/main/.eslintrc.js

## 6. Edit tsconfig.json

If you tried running ESLint at this point, you will probably get an error like this:

```
/Users/risa/projects/project-name/.eslintrc.js
  0:0  error  Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: .eslintrc.js.
The file must be included in at least one of the projects provided
```

You can find a discussion about this error in this [Github issue](https://github.com/typescript-eslint/typescript-eslint/issues/967). Basically, you have to include the files you want to lint in `tsconfig.json`. Create a file like [this](https://github.com/risafj/StorybookExampleReactNativeTS/blob/main/tsconfig.json) if it doesn't exist yet, or add the lines below if it does.

```jsonc
// tsconfig.json

{
  "compilerOptions": {
    // Various options...
  },
  // Add the "include" array below
  // Inside the array, specify files you want ESLint to check
  "include": [
    "./**/*",
    "./*",
    ".eslintrc.js"
  ]
}
```

## 7. Add npm scripts

At this point, you're ready to run ESLint! But before that, let's add some npm scripts to your `package.json` to save you a few keystrokes.

```jsonc
// package.json

{
  "scripts": {
    // Add the two scripts below
    "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
    "lint:fix": "eslint . --fix --ext .js,.jsx,.ts,.tsx",
  }
}
```

Now, you can run ESLint with `yarn lint` or `yarn lint:fix` (for auto-correcting errors).

## 8. [Optional] Run ESLint in Github Actions

You can configure Github Actions to run ESLint every time you push your code. This is convenient because it's easy to forget to run lint locally. Setup is simple - just copy the configuration below.

```yml
# .github/workflows/lint.yml

name: Lint
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Install modules
        run: yarn
      - name: Run ESLint
        run: yarn lint
```

---

That's all! Thanks for reading, and I'd like to hear if it worked :)