A well-tuned linting configuration is essential for a quality JavaScript project, as it will catch errors, enforce coding conventions, and ensure consistent style. ESLint is the tool of choice for most JavaScript projects. It can detect and enforce a large number of JavaScript rules out of the box and can also be extended with plugins to support additional functionality or libraries, like React or Jest.
While ESLint is an indispensible tool, due to the number of linting rules and plugins available, it can be a bit cumbersome to set up on new projects. To simplify setup, most new projects use a base ESLint configuration as a starting point. This base configuration might be recommended by or provided with the framework that’s being used, like eslint-config-next for Next.js, eslint-config-universe for React Native Expo, or @remix-run/eslint-config for Remix. Or, there are other popular ESLint configurations that are usually framework-agnostic, like Airbnb’s eslint-config-airbnb.
I’m excited to announce that thoughtbot has just updated our ESLint configuration package, eslint-config-thoughtbot, to now include opinionated rules with support for common JavaScript environments and concerns, like React, React Native, Prettier, Jest, Testing Library, and additional accessibility plugins. Keep reading to learn more!
Airbnb’s ESLint configuration
Airbnb’s ESLint configuration has been quite popular for some time. Their JavaScript style guide repo where the ESLint config package lives has amassed over 130,000 stars on GitHub – five times as many as ESLint itself. I anecdotally find that when I work with an organization that has an existing JavaScript team, they are often using Airbnb’s configuration.
Airbnb’s configuration is thorough, including hundreds of rule definitions and support for React and accessibility plugins.
While Airbnb’s base ruleset is thorough and widely adopted, the project lacks rules for TypeScript, React Native, Prettier, Jest, Testing Library, and other tooling. I find that if I’m using this Airbnb configuration, I usually have to install and configure plugins for all of these other tools.
Announcing the thoughtbot ESLint Config
We created the thoughtbot ESLint config to be an out-of-the-box configuration that supports all of the tools that we at thoughtbot work with on most projects, with little to no extra configuration necessary. This configuration is built from the foundation that AirBnb’s ESLint config provides but additionally includes rules for React Native, TypeScript, Prettier, Jest, Testing Library, and Node.js.
Installation
If using npm, run:
npm install @thoughtbot/eslint-config --save-dev
If using Yarn, run:
yarn add @thoughtbot/eslint-config --dev
All other ESLint plugins that this package uses will be automatically installed with the package. There is no need to have any of them listed explicitly in your package.json
.
Usage
This package includes configurations for most common tech stacks. Update your ESLint configuration to extend the appropriate setup:
@thoughtbot/eslint-config
- React web, Jest, Testing Library, Prettier@thoughtbot/eslint-config/react
- React web (same as above)@thoughtbot/eslint-config/base
- base web config, no React or Prettier@thoughtbot/eslint-config/native
- React Native, Jest, RN Testing Library, Prettier@thoughtbot/eslint-config/prettier
- Prettier, automatically used when using React or Native config@thoughtbot/eslint-config/typescript
- TypeScript config, add this if using Typescript
The configurations that include Prettier turn off all formatting rules that are also handled by Prettier to reduce conflicts between the two tools. It is recommended to add Prettier to your project and ensure that your CI environment also runs Prettier to verify code formatting.
Example usage:
Following are some example usages of this config (eg. in .eslintrc.js
).
React with TypeScript:
{
"extends": [
"@thoughtbot/eslint-config",
"@thoughtbot/eslint-config/typescript"
]
}
React Native with TypeScript:
{
"extends": [
"@thoughtbot/eslint-config/native",
"@thoughtbot/eslint-config/typescript"
]
}
Base web without React or TypeScript
{
"extends": ["@thoughtbot/eslint-config/base"]
}
You can override rules from the shared configuration, by setting your
own values within the rules
property:
{
"extends": "@thoughtbot/eslint-config",
"rules": {
"react/jsx-newline": "warn"
}
}
You might also need to add the following to your ESLint config if you get an error about Jest not being able to detect the version:
{
"settings": {
"jest": { "version": "detect" }
}
}
Consult the ESLint documentation for more information about configuring ESLint, and take a look at the config files in this repo for more information about the rules and plugins they include.
Running ESLint
We usually set up several scripts in our project package.json
file to facilitate linting and testing:
{
"scripts": {
"lint": "run-p lint:eslint lint:types lint:prettier",
"lint:eslint": "eslint --max-warnings=0 --ext js,jsx,ts,tsx .",
"lint:prettier": "prettier --check '**/*' --ignore-unknown",
"lint:types": "tsc",
"test": "jest",
"test:cov": "yarn test --coverage --coverageDirectory ./.cache/coverage",
"test:ci": "yarn test:cov --maxWorkers=2 --silent --ci",
"test:debug": "node --inspect-brk node_modules/.bin/jest --runInBand",
"test:all": "yarn lint && yarn test:cov"
}
}
With the above scripts added, you can run yarn lint
or npm run lint
to run ESLint, the TypeScript compiler, and Prettier. The run-p
command, which comes from the npm-run-all
package, runs the supplied npm scripts in parallel to speed up linting.
Or you can run yarn test:all
to run all linters and the test suite. I run this command prior to pushing code.
Philosophy
This configuration is batteries-included to support most common environments out of the box. The goal is to be able to drop it into most projects without much customization. Since it’s based off of Airbnb’s thorough config and includes plugins for common tools, it could be described as a fairly strict, opinionated linter. Rules can be relaxed as needed in project overrides if needed. We will likely simplify the linting rules and begin to diverge more from Airbnb’s configuration over time.
This linter treats some rule violations, like unused variables or imports, as warnings instead of errors, only to make them less jarring during development. It can be nice to see an orange squiggly instead of a red squiggly for errors that happen frequently during normal development. It is recommended to run ESLint with the --max-warnings=0
flag to ensure the test suite and linter catch these warnings.
Let us know what you think
We’ve been using the new configuration internally on several projects and are benefiting from the easy configuration and standardization across our team. We hope you give it a try and let us know what you think!