ESLint
ESLint is a static analysis tool for quickly finding and fixing problems in your JavaScript code.
Good to know:
This guide assumes you're using create-turbo or a repository with a similar structure.In this guide, we'll cover:
- ESLint v9 with Flat Configuration
- ESLint v8 with legacy configuration
- How to set up a
lint
task (applies to both versions)
We will share configurations across the monorepo's Workspace, ensuring configuration is consistent across packages and composable to maintain high cache hit ratios.
ESLint v9 (Flat Configs)
Using ESLint v9's Flat Configs, we will end up with a file structure like this:
This structure includes:
- A package called
@repo/eslint-config
in./packages/eslint-config
that holds all ESLint configuration - Two applications, each with their own
eslint.config.js
- A
ui
package that also has its owneslint.config.js
About the configuration package
The @repo/eslint-config
package has three configuration files, base.js
, next.js
, and react-internal.js
. They are exported from package.json
so that they can be used by other packages, according to needs. Examples of the configurations can be found in the Turborepo GitHub repository and are available in npx create-turbo@latest
.
Notably, the next.js
and react-internal.js
configurations use the base.js
configuration for consistency, extending it with more configuration for their respective requirements. Additionally, notice that the package.json
for eslint-config
has all of the ESLint dependencies for the repository. This is useful, since it means we don't need to re-specify the dependencies in the packages that import @repo/eslint-config
.
Using the configuration package
In our web
app, we first need to add @repo/eslint-config
as a dependency.
We can then import the configuration like this:
Additionally, you can add configuration specific to the package like this:
ESLint v8 (Legacy)
ESLint v8 is end-of-life as of October 5, 2024. We encourage you to upgrade to ESLint v9 or later. This documentation is here to help with existing projects that have not yet upgraded.
Using legacy configuration from ESLint v8 and lower, we will end up with a file structure like this:
There's a package called @repo/eslint-config
, and two applications, each with their own .eslintrc.js
.
The @repo/eslint-config
package
The @repo/eslint-config
file contains two files, next.js
, and library.js
. These are two different ESLint configurations, which we can use in different packages, depending on our needs.
A configuration for Next.js may look like this:
The package.json
looks like this:
Note that the ESLint dependencies are all listed here. This is useful, since it means we don't need to re-specify the dependencies inside the apps which import @repo/eslint-config
.
How to use the @repo/eslint-config
package
In our web
app, we first need to add @repo/eslint-config
as a dependency.
We can then import the config like this:
By adding @repo/eslint-config/next.js
to our extends
array, we're telling ESLint to look for a package called @repo/eslint-config
, and reference the file next.js
.
Setting up a lint
task
The package.json
for each package where you'd like to run ESLint should look like this:
With your scripts prepared, you can then create your Turborepo task:
You can now run turbo lint
with global turbo
or create a script in your root package.json
:
Was this helpful?