diff --git a/docs/repo-docs/guides/tools/eslint.mdx b/docs/repo-docs/guides/tools/eslint.mdx
index f11dd047d5d41..14b30df52238f 100644
--- a/docs/repo-docs/guides/tools/eslint.mdx
+++ b/docs/repo-docs/guides/tools/eslint.mdx
@@ -12,132 +12,175 @@ ESLint is a static analysis tool for quickly finding and fixing problems in your
-
- This page is written for ESLint v8. If you'd like to contribute to add a
- version for v9, the core team is happy to review your pull request.
-
+In this guide, we'll cover:
-## Installing ESLint
+- [ESLint v9 with Flat Configuration](#eslint-v9-flat-configs)
+- [ESLint v8 with legacy configuration](#eslint-v8-legacy)
+- [How to set up a `lint` task (applies to both versions)](#setting-up-a-lint-task)
-Install ESLint into each package where you'd like to run it:
+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)
-```bash title="Terminal"
-npm install eslint --workspace=web --workspace=docs --workspace=@repo/ui --save-dev
-```
+Using ESLint v9's Flat Configs, we will end up with a file structure like this:
-
- You can keep ESLint versions in sync using a tool like
- [syncpack](https://jamiemason.github.io/syncpack).
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+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 own `eslint.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`](https://github.com/vercel/turborepo/blob/main/examples/basic/packages/eslint-config/package.json#L6) so that they can be used by other packages, according to needs. Examples of the configurations can be found [in the Turborepo GitHub repository](https://github.com/vercel/turborepo/tree/main/examples/basic/packages/eslint-config) 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`](https://github.com/vercel/turborepo/blob/main/examples/basic/packages/eslint-config/package.json) 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.
+
+
+
+```jsonc title="./apps/web/package.json"
+{
+ "devDependencies": {
+ "@repo/eslint-config": "*"
+ }
+}
+```
+
+
+```jsonc title="./apps/web/package.json"
+{
+ "devDependencies": {
+ "@repo/eslint-config": "*"
+ }
+}
+```
+
+
+```jsonc title="./apps/web/package.json"
+{
+ "devDependencies": {
+ "@repo/eslint-config": "workspace:*"
+ }
+}
+```
+
+
-
+We can then import the configuration like this:
-
+```js title="./apps/web/eslint.config.js"
+import { nextJsConfig } from '@repo/eslint-config/next-js';
-```bash title="Terminal"
-yarn workspace web add eslint --dev
-yarn workspace docs add eslint --dev
-yarn workspace @repo/ui add eslint --dev
+/** @type {import("eslint").Linter.Config} */
+export default nextJsConfig;
```
-
+Additionally, you can add configuration specific to the package like this:
-
+```js title="./apps/web/eslint.config.js"
+import { nextJsConfig } from "@repo/eslint-config/next-js";
-```bash title="Terminal"
-pnpm install eslint --save-dev --filter=@repo/ui --filter=docs --filter=web
+/** @type {import("eslint").Linter.Config} */
+export default [
+ ...nextJsConfig;
+ // Other configurations
+]
```
-
-
+## ESLint v8 (Legacy)
-## Sharing configuration
+
+ 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.
+
-Sharing an ESLint config across packages makes their source code more consistent. Let's imagine a Workspace like this:
+Using legacy configuration from ESLint v8 and lower, we will end up with a file structure like this:
-
+
-
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-We've got a package called `@repo/eslint-config`, and two applications, each with their own `.eslintrc.js`.
+There's a package called `@repo/eslint-config`, and two applications, each with their own `.eslintrc.js`.
-### Our `@repo/eslint-config` package
+### The `@repo/eslint-config` package
-Our `@repo/eslint-config` file contains two files, `next.js`, and `library.js`. These are two different ESLint configs, which we can use in different workspaces, depending on our needs.
+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.
-Let's investigate the `next.js` lint configuration:
+A configuration for Next.js may look like this:
```js title="./packages/eslint-config/next.js"
-const { resolve } = require('node:path');
-
-const project = resolve(process.cwd(), 'tsconfig.json');
-
-/*
- * This is a custom ESLint configuration for use with
- * Next.js apps.
- *
- * This config extends the Vercel Engineering Style Guide.
- * For more information, see https://github.com/vercel/style-guide
- *
- */
-
+/* Custom ESLint configuration for use with Next.js apps. */
module.exports = {
extends: [
- require.resolve('@vercel/style-guide/eslint/node'),
- require.resolve('@vercel/style-guide/eslint/typescript'),
- require.resolve('@vercel/style-guide/eslint/browser'),
- require.resolve('@vercel/style-guide/eslint/react'),
- require.resolve('@vercel/style-guide/eslint/next'),
- // Turborepo custom eslint configuration configures the following rules:
- // - https://github.com/vercel/turborepo/blob/main/packages/eslint-plugin-turbo/docs/rules/no-undeclared-env-vars.md
'eslint-config-turbo',
+ 'eslint-config-next',
+ // ...your other ESLint configurations
].map(require.resolve),
- parserOptions: {
- project,
- },
- globals: {
- React: true,
- JSX: true,
- },
- settings: {
- 'import/resolver': {
- typescript: {
- project,
- },
- },
- },
- ignorePatterns: ['node_modules/', 'dist/'],
- // add rules configurations here
- rules: {
- 'import/no-default-export': 'off',
- },
+ // ...your other configuration
};
```
-It's a typical ESLint config that extends the [Vercel style guide](https://github.com/vercel/style-guide), nothing fancy.
-
The `package.json` looks like this:
```json title="./packages/eslint-config/package.json"
@@ -146,8 +189,9 @@ The `package.json` looks like this:
"version": "0.0.0",
"private": true,
"devDependencies": {
- "@vercel/style-guide": "latest",
- "eslint-config-turbo": "latest"
+ "eslint": "^8",
+ "eslint-config-turbo": "latest",
+ "eslint-config-next": "latest"
}
}
```
@@ -199,10 +243,6 @@ module.exports = {
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`.
-### Summary
-
-This setup ships by default when you [create a new monorepo](/repo/docs/crafting-your-repository#from-zero-to-turbo) with `npx create-turbo@latest`. You can also look at [our basic example](https://github.com/vercel/turborepo/tree/main/examples/basic) to see a working version.
-
## Setting up a `lint` task
The `package.json` for each package where you'd like to run ESLint should look like this:
diff --git a/packages/eslint-config-turbo/README.md b/packages/eslint-config-turbo/README.md
index 834b887134852..fac8e1dd81f7e 100644
--- a/packages/eslint-config-turbo/README.md
+++ b/packages/eslint-config-turbo/README.md
@@ -16,7 +16,39 @@ npm install eslint --save-dev
npm install eslint-config-turbo --save-dev
```
-## Usage
+## Usage (Flat Config `eslint.config.js`)
+
+```js
+import turboConfig from "eslint-config-turbo/flat";
+
+export default [
+ ...turboConfig,
+ // Other configuration
+];
+```
+
+You can also configure rules available in the configuration:
+
+```js
+import turboConfig from "eslint-config-turbo/flat";
+
+export default [
+ ...turboConfig,
+ // Other configuration
+ {
+ rules: {
+ "turbo/no-undeclared-env-vars": [
+ "error",
+ {
+ allowList: ["^ENV_[A-Z]+$"],
+ },
+ ],
+ },
+ },
+];
+```
+
+## Usage (Legacy `eslintrc*`)
Add `turbo` to the extends section of your eslint configuration file. You can omit the `eslint-config-` prefix:
@@ -25,3 +57,19 @@ Add `turbo` to the extends section of your eslint configuration file. You can om
"extends": ["turbo"]
}
```
+
+You can also configure rules available in the configuration:
+
+```json
+{
+ "plugins": ["turbo"],
+ "rules": {
+ "turbo/no-undeclared-env-vars": [
+ "error",
+ {
+ "allowList": ["^ENV_[A-Z]+$"]
+ }
+ ]
+ }
+}
+```
diff --git a/packages/eslint-plugin-turbo/README.md b/packages/eslint-plugin-turbo/README.md
index 21299b643f0f8..cc8f6367ffdb4 100644
--- a/packages/eslint-plugin-turbo/README.md
+++ b/packages/eslint-plugin-turbo/README.md
@@ -16,45 +16,9 @@ npm install eslint --save-dev
npm install eslint-plugin-turbo --save-dev
```
-## Usage (Legacy `eslintrc*`)
-
-Add `turbo` to the plugins section of your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix:
-
-```json
-{
- "plugins": ["turbo"]
-}
-```
-
-Then configure the rules you want to use under the rules section.
-
-```json
-{
- "rules": {
- "turbo/no-undeclared-env-vars": "error"
- }
-}
-```
-
-## Example (Legacy `eslintrc*`)
-
-```json
-{
- "plugins": ["turbo"],
- "rules": {
- "turbo/no-undeclared-env-vars": [
- "error",
- {
- "allowList": ["^ENV_[A-Z]+$"]
- }
- ]
- }
-}
-```
-
## Usage (Flat Config `eslint.config.js`)
-In ESLint v8, both the legacy system and the new flat config system are supported. In ESLint v9, only the new system will be supported. See the [official ESLint docs](https://eslint.org/docs/latest/use/configure/configuration-files).
+ESLint v9 uses the Flat Config format seen below:
```js
import turbo from "eslint-plugin-turbo";
@@ -100,3 +64,39 @@ export default [
},
];
```
+
+## Usage (Legacy `eslintrc*`)
+
+Add `turbo` to the plugins section of your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix:
+
+```json
+{
+ "plugins": ["turbo"]
+}
+```
+
+Then configure the rules you want to use under the rules section.
+
+```json
+{
+ "rules": {
+ "turbo/no-undeclared-env-vars": "error"
+ }
+}
+```
+
+## Example (Legacy `eslintrc*`)
+
+```json
+{
+ "plugins": ["turbo"],
+ "rules": {
+ "turbo/no-undeclared-env-vars": [
+ "error",
+ {
+ "allowList": ["^ENV_[A-Z]+$"]
+ }
+ ]
+ }
+}
+```