Customizable rules for Prettier + Eslint in React
Tags: react, eslint, prettier, webdev
Published: 2024-06-24 21:07:26

## Introduction

In last month's [article](https://dev.to/griseduardo/setup-eslint-prettier-for-code-standardization-in-react-112p), I presented the setup of Eslint with Prettier for a React application, focusing on using these libraries as tools for code standardization and error prevention. In this article, I will show how to customize the rules and introduce some interesting ones to consider. However, I will not suggest whether to use them or not, as this depends on the project and the decisions of the development team involved.

## Rules

Recalling the definition used in the previous article, inside the eslint configuration file `.eslintrc.json`, we set it to use the recommended rules from eslint, react, react-hooks, and to use prettier together:

```js
{
  //...
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:react-hooks/recommended",
    "prettier"
  ],
  "rules": {
    "prettier/prettier": ["error"]
  }
}
```

If the code does not comply with the rules from this configuration, an error is returned when running eslint.

## Prettier customization

To customize the rules, the `.eslintrc.json` file follows this structure:

```js
{
  //...
  "rules": {
    "prettier/prettier": [
      "error_type",
      {
        //...
        rule: rule_expectative,
        rule: rule_expectative
      }
    ]
  }
}
```

In `error_type` two types can be defined:

- warn: returns a warning if the rules are not satisfied
- error: returns an error if the rules are not satisfied

In `rule`, the rule to be customized is defined, and in `rule_expectative`, what is expected to be satisfied in the code.

## Prettier rules

| Rule | Default | Type |
| :--: | :-----: | :--: |
| singleQuote | false | boolean |
| tabWidth | 2 | number |
| printWidth | 80 | number |
| jsxSingleQuote | false | boolean |
| arrowParens | "always" | "always" or "avoid"

`singleQuote`: defines if the project will use single quotes, excluding jsx (by default, it is set to false, meaning double quotes will be used)
`tabWidth`: defines the space indentation
`printWidth`: defines the desired line length
`jsxSingleQuote`: defines if the project will use single quotes for jsx (by default, it is set to false, meaning double quotes will be used)
`arrowParens`: defines if to include parentheses for arrow functions with a single parameter (by default always included)

- "always": `(x) => x`
- "avoid": `x => x`

To demonstrate how customization is done, here's an example of a definition in `.eslintrc.json`:

```js
{
  //...
  "rules": {
    "prettier/prettier": [
      "error",
      {
        //...
        "singleQuote": true,
        "jsxSingleQuote": true,
        "arrowParens": "avoid"
      }
    ]
  }
}
```

## Eslint customization

To customize the rules, the `.eslintrc.json` file follows this structure:

```js
{
  //...
  "rules": {
    //...
    rule: error_type,
    rule: [error_type, rule_expectative]
  }
}
```

In `error_type` three types can be defined:

- warn: returns a warning if the rule is not satisfied
- error: returns an error if the rule is not satisfied
- off: disables rule

For eslint, there are two ways to define rules. For rules where you only activate or disable them, follow this structure: `rule: error_type`. For rules that involve setting a value or something more than just activation, follow this structure: `rule: [error_type, rule_expectative]`, where `rule_expectative` defines what is expected to be satisfied in the code.

## Eslint rules

| Source | Rule | Default |
| :----: | :--: | :-----: |
| eslint | no-duplicated-imports | disabled |
| eslint | no-console | disabled |
| eslint | no-nested-ternary | disabled |
| eslint | eqeqeq | disabled |
| plugin react | react/jsx-uses-react | enabled |
| plugin react | react/react-in-jsx-scope | enabled |
| plugin react | react/jsx-no-useless-fragment | disabled |
| plugin react | react/no-array-index-key | disabled |
| plugin react | react/destructuring-assignment | disabled |
| plugin react-hooks | react-hooks/rules-of-hooks | enabled |
| plugin react-hooks | react-hooks/exhaustive-deps | enabled |

`no-duplicated-imports`: does not allow duplicate import calls from the same relative path
`no-console`: does not allow console.log()
`no-nested-ternary`: does not allow nested ternary
`eqeqeq`: defines comparison only with `===` or `!==`
`react/jsx-uses-react` e `react/react-in-jsx-scope`: defines the requirement to include `import React`, but for React 17+ applications that do not require this import, it is interesting to disable these rules
`react/jsx-no-useless-fragment`: does not allow useless fragment
`react/no-array-index-key`: does not allow array index key
`react/destructuring-assignment`: defines the use of destructuring for props, state, and context
`react-hooks/rules-of-hooks`: defines the use of rules of hooks, which includes, for example, not placing hooks inside conditionals (among others that I will add the link at the end of the article).
`react-hooks/exhaustive-deps`: defines the requirement to place all dependencies inside hooks

To demonstrate how customization is done, here's an example of a definition in `.eslintrc.json`:

```js
{
  //...
  "rules": {
    //...
    "no-console": "warn",
    "eqeqeq": "error",
    "react/destructuring-assignement": "error",
    "react/no-array-index-key": "error",
    "react-hooks/exhaustive-deps": "warn"
  }
}
```

## Conclusion

The idea of this article was to show how to customize rules aimed at defining project standards and anticipating errors in React, presenting some interesting rules from prettier, eslint, react plugin and react-hooks plugin. However, the number of customizable rules is quite extensive, so I will include the links to the available ones below. If you find any other interesting rules, please feel free to share them in the comments for others to see more options there.

## Links

[Prettier](https://prettier.io/docs/en/options.html)
[Eslint](https://eslint.org/docs/v8.x/rules/)
[Plugin react (rules in the end of README)](https://github.com/jsx-eslint/eslint-plugin-react?tab=readme-ov-file)
[Plugin react-hooks](https://www.npmjs.com/package/eslint-plugin-react-hooks)
[Rules of hooks](https://react.dev/reference/rules/rules-of-hooks)