diff --git a/.eslintignore b/.eslintignore
index 37e0a229afb6..fa46bc2d129c 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -2,6 +2,7 @@ node_modules
 **/.next/**
 **/_next/**
 **/dist/**
+e2e-tests/**
 examples/with-typescript-eslint-jest/**
 examples/with-kea/**
 packages/next/bundles/webpack/packages/*.runtime.js
@@ -16,4 +17,5 @@ packages/next-codemod/**/*.js
 packages/next-codemod/**/*.d.ts
 packages/next-env/**/*.d.ts
 test/integration/async-modules/**
+test/integration/eslint/**
 test-timings.json
\ No newline at end of file
diff --git a/docs/api-reference/next.config.js/eslint-warnings-errors.md b/docs/api-reference/next.config.js/eslint-warnings-errors.md
new file mode 100644
index 000000000000..d13372413216
--- /dev/null
+++ b/docs/api-reference/next.config.js/eslint-warnings-errors.md
@@ -0,0 +1,70 @@
+---
+description: Learn how to opt-in and out of ESLint during development mode and production builds.
+---
+
+# ESLint Warnings and Errors
+
+## During builds
+
+Next.js fails your **production build** (`next build`) when ESLint errors are present in your
+project.
+
+If you'd like Next.js to dangerously produce production code even when your application has errors,
+you can disable ESLint running during the build process.
+
+> It's recommended to run ESLint as part of the production build process to ensure your application
+> is resilient against runtime issues.
+
+Open `next.config.js` and disable the `build` option in the `eslint` config:
+
+```js
+module.exports = {
+  eslint: {
+    // !! WARN !!
+    // Dangerously allow production builds to successfully complete even if
+    // your project has ESLint errors.
+    // !! WARN !!
+    build: false,
+  },
+}
+```
+
+## During development
+
+By default, Next.js does not run ESLint during **development** (`next dev`).
+
+If you would like Next.js to lint files separately in development mode, you can enable it in your
+configuration.
+
+> Enabling ESLint during development mode will slow down how fast pages are compiled. Until this is
+> optimized, we recommend that you [integrate ESLint in your code
+> editor](https://eslint.org/docs/user-guide/integrations#editors).
+
+Open `next.config.js` and enable the `dev` option in the `eslint` config:
+
+```js
+module.exports = {
+  eslint: {
+    // !! WARN !!
+    // This can slow down how long pages take to compile during development
+    // !! WARN !!
+    dev: true,
+  },
+}
+```
+
+## Related
+
+<div class="card">
+  <a href="/docs/api-reference/next.config.js/introduction.md">
+    <b>Introduction to next.config.js:</b>
+    <small>Learn more about the configuration file used by Next.js.</small>
+  </a>
+</div>
+
+<div class="card">
+  <a href="/docs/basic-features/eslint.md">
+    <b>ESLint:</b>
+    <small>Learn more about how to use ESLint in Next.js.</small>
+  </a>
+</div>
diff --git a/docs/basic-features/eslint.md b/docs/basic-features/eslint.md
new file mode 100644
index 000000000000..019cc1d7c3e2
--- /dev/null
+++ b/docs/basic-features/eslint.md
@@ -0,0 +1,50 @@
+---
+description: Next.js uses ESLint to find and resolve issues affecting the user or developer
+experience.
+---
+
+# ESLint
+
+Next.js uses [ESLint](https://eslint.org/) to find and resolve issues affecting the user or
+developer experience. A minimal set of Next.js rules are provided by default, but can be extended by
+adding an `.eslintrc` file to your project.
+
+## Default configuration
+
+By default, Next.js provides a set of [recommended ESLint
+rules](https://github.com/vercel/next.js/blob/canary/packages/eslint-plugin-next/lib/index.js#L10-L18)
+that are automatically linted against as part of `next build`. If you would like to control which
+ESLint rules are checked during builds, you will need to add an `.eslintrc` file to the root of your
+project.
+
+Here's an example of an `.eslintrc.json` file:
+
+```json
+{
+  "extends": ["plugin:@next/next/recommended"],
+  "parser": "@babel/eslint-parser",
+  "parserOptions": {
+    "requireConfigFile": false,
+    "sourceType": "module",
+    "babelOptions": {
+      "presets": ["next/babel"]
+    }
+  }
+}
+```
+
+- Extending the original base of rules (`plugin:@next/next/recommended`) is highly recommended to
+  catch and fix significant Next.js issues in your application
+- Including `@babel/eslint-parser` with the `next/babel` preset ensures that all language features
+  supported by Next.js will also be supported by ESLint. Although `@babel/eslint-parser` can parse
+  TypeScript, consider using
+  [`@typescript-eslint/parser`](https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/parser)
+  if you have TypeScript enabled in your application to check for type-specific linting rules.
+
+> If you add an `.eslintrc` file to your application and don't include
+> `plugin:@next/next/recommended`in the config, its rules will not be checked during development or
+> production builds. This is **not recommended**.
+
+If you want to enable ESLint to run during development, or disable it for production builds; refer
+to the documentation for [ESLint Warnings and
+Errors](/docs/api-reference/next.config.js/eslint-warnings-errors.md).
diff --git a/docs/manifest.json b/docs/manifest.json
index a9dcd38126b8..cd9010eb8bfc 100644
--- a/docs/manifest.json
+++ b/docs/manifest.json
@@ -33,6 +33,10 @@
               "title": "Fast Refresh",
               "path": "/docs/basic-features/fast-refresh.md"
             },
+            {
+              "title": "ESLint",
+              "path": "/docs/basic-features/eslint.md"
+            },
             {
               "title": "TypeScript",
               "path": "/docs/basic-features/typescript.md"
@@ -336,6 +340,10 @@
               "title": "Configuring onDemandEntries",
               "path": "/docs/api-reference/next.config.js/configuring-onDemandEntries.md"
             },
+            {
+              "title": "ESLint Warnings and Errors",
+              "path": "/docs/api-reference/next.config.js/eslint-warnings-errors.md"
+            },
             {
               "title": "Ignoring TypeScript Errors",
               "path": "/docs/api-reference/next.config.js/ignoring-typescript-errors.md"
diff --git a/packages/eslint-plugin-next/lib/rules/no-html-link-for-pages.js b/packages/eslint-plugin-next/lib/rules/no-html-link-for-pages.js
index 947850a6f5af..b816a418b860 100644
--- a/packages/eslint-plugin-next/lib/rules/no-html-link-for-pages.js
+++ b/packages/eslint-plugin-next/lib/rules/no-html-link-for-pages.js
@@ -1,10 +1,18 @@
 const path = require('path')
 const fs = require('fs')
-const { getUrlFromPagesDirectory, normalizeURL } = require('../utils/url')
+const {
+  getUrlFromPagesDirectory,
+  normalizeURL,
+  execOnce,
+} = require('../utils/url')
+
+const pagesDirWarning = execOnce((pagesDirs) => {
+  console.warn(
+    `Pages directory cannot be found at ${pagesDirs.join(' or ')}. ` +
+      `If using a custom path, please configure with the no-html-link-for-pages rule in your eslint config file`
+  )
+})
 
-//------------------------------------------------------------------------------
-// Rule Definition
-//------------------------------------------------------------------------------
 module.exports = {
   meta: {
     docs: {
@@ -26,10 +34,8 @@ module.exports = {
         ]
     const pagesDir = pagesDirs.find((dir) => fs.existsSync(dir))
     if (!pagesDir) {
-      throw new Error(
-        `Pages directory cannot be found at ${pagesDirs.join(' or ')}. ` +
-          `If using a custom path, please configure with the no-html-link-for-pages rule`
-      )
+      pagesDirWarning(pagesDirs)
+      return {}
     }
 
     const urls = getUrlFromPagesDirectory('/', pagesDir)
diff --git a/packages/eslint-plugin-next/lib/utils/url.js b/packages/eslint-plugin-next/lib/utils/url.js
index 4b3999b10f45..ae1163b47ff1 100644
--- a/packages/eslint-plugin-next/lib/utils/url.js
+++ b/packages/eslint-plugin-next/lib/utils/url.js
@@ -76,7 +76,21 @@ function normalizeURL(url) {
   return url
 }
 
+function execOnce(fn) {
+  let used = false
+  let result
+
+  return (...args) => {
+    if (!used) {
+      used = true
+      result = fn(...args)
+    }
+    return result
+  }
+}
+
 module.exports = {
   getUrlFromPagesDirectory,
   normalizeURL,
+  execOnce,
 }
diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts
index 4faaaad434e9..e79555487d23 100644
--- a/packages/next/build/index.ts
+++ b/packages/next/build/index.ts
@@ -175,6 +175,41 @@ export default async function build(
       telemetry.record(events)
     )
 
+    if (config.eslint?.build) {
+      await nextBuildSpan
+        .traceChild('verify-and-lint')
+        .traceAsyncFn(async () => {
+          const lintWorkers = new Worker(
+            require.resolve('../lib/verifyAndLint'),
+            {
+              numWorkers: config.experimental.cpus,
+              enableWorkerThreads: config.experimental.workerThreads,
+            }
+          ) as Worker & {
+            verifyAndLint: typeof import('../lib/verifyAndLint').verifyAndLint
+          }
+
+          lintWorkers.getStdout().pipe(process.stdout)
+          lintWorkers.getStderr().pipe(process.stderr)
+
+          const lintResults = await lintWorkers.verifyAndLint(
+            dir,
+            pagesDir,
+            null
+          )
+
+          if (lintResults.hasErrors) {
+            console.error(chalk.red('Failed to compile.'))
+            console.error(lintResults.results)
+            process.exit(1)
+          } else if (lintResults.hasMessages) {
+            console.log(lintResults.results)
+          }
+
+          lintWorkers.end()
+        })
+    }
+
     const ignoreTypeScriptErrors = Boolean(config.typescript?.ignoreBuildErrors)
     await nextBuildSpan
       .traceChild('verify-typescript-setup')
diff --git a/packages/next/lib/eslint/customFormatter.ts b/packages/next/lib/eslint/customFormatter.ts
new file mode 100644
index 000000000000..6fc55ef09b04
--- /dev/null
+++ b/packages/next/lib/eslint/customFormatter.ts
@@ -0,0 +1,68 @@
+import { ESLint, Linter } from 'eslint'
+
+import chalk from 'chalk'
+import path from 'path'
+
+export enum MessageSeverity {
+  Warning = 1,
+  Error = 2,
+}
+
+function formatMessage(
+  dir: string,
+  messages: Linter.LintMessage[],
+  filePath: string
+): string | void {
+  let fileName = path.posix.normalize(
+    path.relative(dir, filePath).replace(/\\/g, '/')
+  )
+
+  if (!fileName.startsWith('.')) {
+    fileName = './' + fileName
+  }
+
+  let output = '\n' + chalk.cyan(fileName)
+
+  for (let i = 0; i < messages.length; i++) {
+    const { message, severity, line, column, ruleId } = messages[i]
+
+    output = output + '\n'
+
+    if (line && column) {
+      output =
+        output +
+        chalk.yellow(line.toString()) +
+        ':' +
+        chalk.yellow(column.toString()) +
+        '  '
+    }
+
+    if (severity === MessageSeverity.Warning) {
+      output += chalk.yellow.bold('Warning') + ': '
+    } else {
+      output += chalk.red.bold('Error') + ': '
+    }
+
+    output += message
+
+    if (ruleId) {
+      output += '  ' + chalk.gray.bold(ruleId)
+    }
+  }
+
+  return output
+}
+
+export function formatResults(
+  baseDir: string,
+  results: ESLint.LintResult[]
+): string {
+  return (
+    results
+      .filter(({ messages }) => messages?.length)
+      .map(({ messages, filePath }) =>
+        formatMessage(baseDir, messages, filePath)
+      )
+      .join('\n') + '\n'
+  )
+}
diff --git a/packages/next/lib/verifyAndLint.ts b/packages/next/lib/verifyAndLint.ts
new file mode 100644
index 000000000000..997b77b94b10
--- /dev/null
+++ b/packages/next/lib/verifyAndLint.ts
@@ -0,0 +1,141 @@
+import { ESLint } from 'eslint'
+import { join } from 'path'
+
+import { formatResults } from './eslint/customFormatter'
+import { fileExists } from './file-exists'
+import * as log from '../build/output/log'
+
+import findUp from 'next/dist/compiled/find-up'
+
+type Config = {
+  plugins: string[]
+  rules: { [key: string]: Array<number | string> }
+}
+
+export async function verifyAndLint(
+  baseDir: string,
+  pagesDir: string,
+  pagePath: string | null
+): Promise<{
+  results: string
+  hasErrors: boolean
+  hasMessages: boolean
+}> {
+  let options: ESLint.Options
+
+  let pathNotExists = Boolean(
+    pagePath && !(await fileExists(join(pagesDir, pagePath)))
+  )
+
+  if (pathNotExists)
+    return { results: '', hasErrors: false, hasMessages: false }
+
+  const eslintrcFile = await findUp(
+    [
+      '.eslintrc.js',
+      '.eslintrc.yaml',
+      '.eslintrc.yml',
+      '.eslintrc.json',
+      '.eslintrc',
+    ],
+    {
+      cwd: baseDir,
+    }
+  )
+
+  const pagesDirRules = ['@next/next/no-html-link-for-pages']
+  const pkgJsonPath = await findUp('package.json', { cwd: baseDir })
+  const { eslintConfig = null } = !!pkgJsonPath
+    ? await import(pkgJsonPath!)
+    : {}
+  let pluginIsEnabled = false
+
+  if (eslintrcFile) {
+    options = {
+      useEslintrc: true,
+      baseConfig: {},
+    }
+  } else {
+    if (!eslintConfig) {
+      console.log()
+      log.info(
+        'No ESLint configuration was detected, but checks from the Next.js ESLint plugin were included automatically (see https://nextjs.org/docs/basic-features/eslint).'
+      )
+      pluginIsEnabled = true
+    }
+
+    options = {
+      baseConfig: eslintConfig ?? {
+        extends: ['plugin:@next/next/recommended'],
+        parser: require.resolve('@babel/eslint-parser'),
+        parserOptions: {
+          requireConfigFile: false,
+          sourceType: 'module',
+          babelOptions: {
+            presets: ['next/babel'],
+          },
+        },
+      },
+      useEslintrc: false,
+    }
+  }
+
+  let eslint = new ESLint(options)
+
+  // check both eslintrc and package.json config since
+  // eslint will load config from both
+  for (const configFile of [eslintrcFile, pkgJsonPath]) {
+    if (!configFile) continue
+
+    const completeConfig: Config = await eslint.calculateConfigForFile(
+      configFile
+    )
+
+    if (completeConfig.plugins?.includes('@next/next')) {
+      pluginIsEnabled = true
+      break
+    }
+  }
+
+  if (pluginIsEnabled) {
+    let updatedPagesDir = false
+
+    for (const rule of pagesDirRules) {
+      if (
+        !options.baseConfig!.rules?.[rule] &&
+        !options.baseConfig!.rules?.[
+          rule.replace('@next/next', '@next/babel-plugin-next')
+        ]
+      ) {
+        if (!options.baseConfig!.rules) {
+          options.baseConfig!.rules = {}
+        }
+        options.baseConfig!.rules[rule] = [1, pagesDir]
+        updatedPagesDir = true
+      }
+    }
+
+    if (updatedPagesDir) {
+      eslint = new ESLint(options)
+    }
+  } else {
+    console.log()
+    log.warn(
+      `The Next.js ESLint plugin was not detected in ${
+        eslintrcFile || pkgJsonPath
+      }. We recommend including it to prevent significant issues in your application (see https://nextjs.org/docs/basic-features/eslint).`
+    )
+  }
+
+  const results = await eslint.lintFiles([
+    pagePath ? join(pagesDir, pagePath) : `${pagesDir}/**/*.{js,tsx}`,
+  ])
+
+  const errors = ESLint.getErrorResults(results)
+
+  return {
+    results: formatResults(baseDir, results),
+    hasErrors: errors?.length > 0 && !pagePath,
+    hasMessages: results?.length > 0,
+  }
+}
diff --git a/packages/next/next-server/server/config-shared.ts b/packages/next/next-server/server/config-shared.ts
index a677d5db3a25..196973e5709b 100644
--- a/packages/next/next-server/server/config-shared.ts
+++ b/packages/next/next-server/server/config-shared.ts
@@ -89,6 +89,10 @@ export const defaultConfig: NextConfig = {
   serverRuntimeConfig: {},
   publicRuntimeConfig: {},
   reactStrictMode: false,
+  eslint: {
+    dev: false,
+    build: true,
+  },
 }
 
 export function normalizeConfig(phase: string, config: any) {
diff --git a/packages/next/package.json b/packages/next/package.json
index c248c52fb4d8..e2fe18a11b8c 100644
--- a/packages/next/package.json
+++ b/packages/next/package.json
@@ -60,9 +60,12 @@
     ]
   },
   "dependencies": {
+    "@babel/core": "7.12.10",
     "@babel/runtime": "7.12.5",
+    "@babel/eslint-parser": "7.13.4",
     "@hapi/accept": "5.0.1",
     "@next/env": "10.0.10-canary.7",
+    "@next/eslint-plugin-next": "10.0.10-canary.7",
     "@next/polyfill-module": "10.0.10-canary.7",
     "@next/react-dev-overlay": "10.0.10-canary.7",
     "@next/react-refresh-utils": "10.0.10-canary.7",
@@ -79,6 +82,7 @@
     "crypto-browserify": "3.12.0",
     "cssnano-simple": "1.2.2",
     "domain-browser": "4.19.0",
+    "eslint": "7.9.0",
     "etag": "1.8.1",
     "find-cache-dir": "3.3.1",
     "get-orientation": "1.1.2",
@@ -130,7 +134,6 @@
   "devDependencies": {
     "@ampproject/toolbox-optimizer": "2.7.1-alpha.0",
     "@babel/code-frame": "7.12.11",
-    "@babel/core": "7.12.10",
     "@babel/plugin-proposal-class-properties": "7.12.1",
     "@babel/plugin-proposal-export-namespace-from": "7.12.1",
     "@babel/plugin-proposal-numeric-separator": "7.12.7",
@@ -161,6 +164,7 @@
     "@types/cookie": "0.3.3",
     "@types/cross-spawn": "6.0.0",
     "@types/debug": "4.1.5",
+    "@types/eslint": "7.2.5",
     "@types/etag": "1.8.0",
     "@types/fresh": "0.5.0",
     "@types/json5": "0.0.30",
diff --git a/packages/next/server/hot-reloader.ts b/packages/next/server/hot-reloader.ts
index 15e33caa2a6c..1470bde405eb 100644
--- a/packages/next/server/hot-reloader.ts
+++ b/packages/next/server/hot-reloader.ts
@@ -512,6 +512,7 @@ export default class HotReloader {
     this.onDemandEntries = onDemandEntryHandler(this.watcher, multiCompiler, {
       pagesDir: this.pagesDir,
       pageExtensions: this.config.pageExtensions,
+      eslint: this.config.eslint?.dev,
       ...(this.config.onDemandEntries as {
         maxInactiveAge: number
         pagesBufferLength: number
diff --git a/packages/next/server/on-demand-entry-handler.ts b/packages/next/server/on-demand-entry-handler.ts
index d6bef0477fe5..bd918494f257 100644
--- a/packages/next/server/on-demand-entry-handler.ts
+++ b/packages/next/server/on-demand-entry-handler.ts
@@ -4,6 +4,7 @@ import { join, posix } from 'path'
 import { parse } from 'url'
 import { webpack } from 'next/dist/compiled/webpack/webpack'
 import * as Log from '../build/output/log'
+import { verifyAndLint } from '../lib/verifyAndLint'
 import {
   normalizePagePath,
   normalizePathSep,
@@ -32,11 +33,13 @@ export default function onDemandEntryHandler(
   {
     pagesDir,
     pageExtensions,
+    eslint,
     maxInactiveAge,
     pagesBufferLength,
   }: {
     pagesDir: string
     pageExtensions: string[]
+    eslint: boolean
     maxInactiveAge: number
     pagesBufferLength: number
   }
@@ -192,6 +195,15 @@ export default function onDemandEntryHandler(
           }
         }
 
+        // TODO: Move out of hot-reloader into a separate process
+        if (eslint) {
+          verifyAndLint(process.cwd(), pagesDir, pagePath).then(
+            ({ results, hasMessages }) => {
+              if (hasMessages) console.log(results)
+            }
+          )
+        }
+
         Log.event(`build page: ${normalizedPage}`)
 
         entries[normalizedPage] = {
diff --git a/test-pnp.sh b/test-pnp.sh
index 8b5fd93beb57..1bcc4a4016c7 100755
--- a/test-pnp.sh
+++ b/test-pnp.sh
@@ -29,6 +29,9 @@ do
   cp -r "./examples/$testCase/." "./e2e-tests/$testCase"
   cd "./e2e-tests/$testCase"
 
+  # Ensure builds do not fail due to lint errors
+  echo "module.exports = { eslint: { build: false } }" > next.config.js
+
   touch yarn.lock
   yarn set version berry
 
diff --git a/test/integration/dist-dir/test/index.test.js b/test/integration/dist-dir/test/index.test.js
index 8930f21ed046..d9202d8d8d52 100644
--- a/test/integration/dist-dir/test/index.test.js
+++ b/test/integration/dist-dir/test/index.test.js
@@ -47,7 +47,10 @@ describe('distDir', () => {
 
   it('should throw error with invalid distDir', async () => {
     const origNextConfig = await fs.readFile(nextConfig, 'utf8')
-    await fs.writeFile(nextConfig, `module.exports = { distDir: '' }`)
+    await fs.writeFile(
+      nextConfig,
+      `module.exports = { distDir: '', eslint: { build: false } }`
+    )
     const { stderr } = await nextBuild(appDir, [], { stderr: true })
     await fs.writeFile(nextConfig, origNextConfig)
 
@@ -58,10 +61,12 @@ describe('distDir', () => {
 
   it('should handle null/undefined distDir', async () => {
     const origNextConfig = await fs.readFile(nextConfig, 'utf8')
-    await fs.writeFile(nextConfig, `module.exports = { distDir: null }`)
+    await fs.writeFile(
+      nextConfig,
+      `module.exports = { distDir: null, eslint: { build: false } }`
+    )
     const { stderr } = await nextBuild(appDir, [], { stderr: true })
     await fs.writeFile(nextConfig, origNextConfig)
-
     expect(stderr.length).toBe(0)
   })
 })
diff --git a/test/integration/eslint/custom-eslint-config/.eslintrc.json b/test/integration/eslint/custom-eslint-config/.eslintrc.json
new file mode 100644
index 000000000000..f0dc21af7d53
--- /dev/null
+++ b/test/integration/eslint/custom-eslint-config/.eslintrc.json
@@ -0,0 +1,16 @@
+{
+  "extends": ["plugin:@next/next/recommended"],
+  "rules": {
+    "@next/next/no-sync-scripts": "off",
+    "@next/next/no-css-tags": "warn",
+    "@next/next/no-html-link-for-pages": ["error", "./"]
+  },
+  "parserOptions": {
+    "ecmaVersion": 2018,
+    "sourceType": "module",
+    "ecmaFeatures": {
+      "jsx": true,
+      "modules": true
+    }
+  }
+}
diff --git a/test/integration/eslint/custom-eslint-config/pages/index.js b/test/integration/eslint/custom-eslint-config/pages/index.js
new file mode 100644
index 000000000000..64a516a0323a
--- /dev/null
+++ b/test/integration/eslint/custom-eslint-config/pages/index.js
@@ -0,0 +1,13 @@
+import { Head } from 'next/document'
+
+export default class Test extends Head {
+  render() {
+    return (
+      <div>
+        <h1>Hello title</h1>
+        <script src="https://synchronous-script.com"></script>
+        <link href="/_next/static/css/styles.css" rel="stylesheet" />
+      </div>
+    )
+  }
+}
diff --git a/test/integration/eslint/custom-next-config/.eslintrc.json b/test/integration/eslint/custom-next-config/.eslintrc.json
new file mode 100644
index 000000000000..444bf63d9ee1
--- /dev/null
+++ b/test/integration/eslint/custom-next-config/.eslintrc.json
@@ -0,0 +1,14 @@
+{
+  "extends": ["plugin:@next/next/recommended"],
+  "rules": {
+    "@next/next/no-html-link-for-pages": ["error", "./"]
+  },
+  "parserOptions": {
+    "ecmaVersion": 2018,
+    "sourceType": "module",
+    "ecmaFeatures": {
+      "jsx": true,
+      "modules": true
+    }
+  }
+}
diff --git a/test/integration/eslint/custom-next-config/next.config.js b/test/integration/eslint/custom-next-config/next.config.js
new file mode 100644
index 000000000000..d1567e6d0576
--- /dev/null
+++ b/test/integration/eslint/custom-next-config/next.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+  eslint: {
+    dev: true,
+    build: false,
+  },
+}
diff --git a/test/integration/eslint/custom-next-config/pages/index.js b/test/integration/eslint/custom-next-config/pages/index.js
new file mode 100644
index 000000000000..64a516a0323a
--- /dev/null
+++ b/test/integration/eslint/custom-next-config/pages/index.js
@@ -0,0 +1,13 @@
+import { Head } from 'next/document'
+
+export default class Test extends Head {
+  render() {
+    return (
+      <div>
+        <h1>Hello title</h1>
+        <script src="https://synchronous-script.com"></script>
+        <link href="/_next/static/css/styles.css" rel="stylesheet" />
+      </div>
+    )
+  }
+}
diff --git a/test/integration/eslint/pkg-json-eslint-config/package.json b/test/integration/eslint/pkg-json-eslint-config/package.json
new file mode 100644
index 000000000000..4d09b24ceb47
--- /dev/null
+++ b/test/integration/eslint/pkg-json-eslint-config/package.json
@@ -0,0 +1,36 @@
+{
+  "name": "hello-world",
+  "version": "1.0.0",
+  "scripts": {
+    "dev": "next",
+    "build": "next build",
+    "start": "next start"
+  },
+  "dependencies": {
+    "next": "latest",
+    "react": "^16.13.1",
+    "react-dom": "^16.13.1"
+  },
+  "license": "MIT",
+  "eslintConfig": {
+    "extends": [
+      "plugin:@next/next/recommended"
+    ],
+    "rules": {
+      "@next/next/no-sync-scripts": "off",
+      "@next/next/no-css-tags": "warn",
+      "@next/next/no-html-link-for-pages": [
+        "error",
+        "./"
+      ]
+    },
+    "parserOptions": {
+      "ecmaVersion": 2018,
+      "sourceType": "module",
+      "ecmaFeatures": {
+        "jsx": true,
+        "modules": true
+      }
+    }
+  }
+}
diff --git a/test/integration/eslint/pkg-json-eslint-config/pages/index.js b/test/integration/eslint/pkg-json-eslint-config/pages/index.js
new file mode 100644
index 000000000000..64a516a0323a
--- /dev/null
+++ b/test/integration/eslint/pkg-json-eslint-config/pages/index.js
@@ -0,0 +1,13 @@
+import { Head } from 'next/document'
+
+export default class Test extends Head {
+  render() {
+    return (
+      <div>
+        <h1>Hello title</h1>
+        <script src="https://synchronous-script.com"></script>
+        <link href="/_next/static/css/styles.css" rel="stylesheet" />
+      </div>
+    )
+  }
+}
diff --git a/test/integration/eslint/test/custom-eslint-config.test.js b/test/integration/eslint/test/custom-eslint-config.test.js
new file mode 100644
index 000000000000..bcfce446a5f5
--- /dev/null
+++ b/test/integration/eslint/test/custom-eslint-config.test.js
@@ -0,0 +1,37 @@
+import { join } from 'path'
+import { nextBuild } from 'next-test-utils'
+import { remove } from 'fs-extra'
+
+jest.setTimeout(1000 * 60 * 2)
+
+const appDir = join(__dirname, '../custom-eslint-config')
+
+describe('ESLint', () => {
+  let stdout
+  let code
+
+  beforeAll(async () => {
+    await remove(join(appDir, '.next'))
+    ;({ code, stdout } = await nextBuild(appDir, [], {
+      stdout: true,
+    }))
+  })
+
+  it('should show warnings and errors based on custom eslint config', async () => {
+    expect(code).toBe(0)
+    expect(stdout).not.toContain(
+      'No ESLint configuration was detected, but checks from the Next.js ESLint plugin were included automatically'
+    )
+    expect(stdout).toContain('./pages/index.js')
+    expect(stdout).not.toContain(
+      "8:9  Warning: A synchronous script tag can impact your webpage's performance  @next/next/no-sync-scripts"
+    )
+    expect(stdout).toContain(
+      '9:9  Warning: In order to use external stylesheets use @import in the root stylesheet compiled with NextJS. This ensures proper priority to CSS when loading a webpage.  @next/next/no-css-tags'
+    )
+    expect(stdout).toContain(
+      '9:9  Warning: Stylesheet does not have an associated preload tag. This could potentially impact First paint.  @next/next/missing-preload'
+    )
+    expect(stdout).toContain('Compiled successfully')
+  })
+})
diff --git a/test/integration/eslint/test/custom-next-config.test.js b/test/integration/eslint/test/custom-next-config.test.js
new file mode 100644
index 000000000000..7daf4689de0a
--- /dev/null
+++ b/test/integration/eslint/test/custom-next-config.test.js
@@ -0,0 +1,55 @@
+import { join } from 'path'
+import {
+  launchApp,
+  renderViaHTTP,
+  killApp,
+  findPort,
+  nextBuild,
+} from 'next-test-utils'
+
+jest.setTimeout(1000 * 60 * 2)
+
+const appDir = join(__dirname, '../custom-next-config')
+
+describe('ESLint', () => {
+  it('should show messages in dev mode as specified in next config', async () => {
+    let stdout
+
+    const appPort = await findPort()
+    const app = await launchApp(appDir, appPort, {
+      onStdout(msg) {
+        stdout += msg || ''
+      },
+    })
+    await renderViaHTTP(appPort, '/')
+    await killApp(app)
+    expect(stdout).toContain('pages/index.js')
+    expect(stdout).toContain(
+      "8:9  Warning: A synchronous script tag can impact your webpage's performance  @next/next/no-sync-scripts"
+    )
+    expect(stdout).toContain(
+      '9:9  Warning: In order to use external stylesheets use @import in the root stylesheet compiled with NextJS. This ensures proper priority to CSS when loading a webpage.  @next/next/no-css-tags'
+    )
+    expect(stdout).toContain(
+      '9:9  Warning: Stylesheet does not have an associated preload tag. This could potentially impact First paint.  @next/next/missing-preload'
+    )
+  })
+
+  it('should not show messages in build mode as specified in next config', async () => {
+    const { code, stdout } = await nextBuild(appDir, [], {
+      stdout: true,
+    })
+    expect(code).toBe(0)
+    expect(stdout).not.toContain('pages/index.js')
+    expect(stdout).not.toContain(
+      "8:9  Warning: A synchronous script tag can impact your webpage's performance  @next/next/no-sync-scripts"
+    )
+    expect(stdout).not.toContain(
+      '9:9  Warning: In order to use external stylesheets use @import in the root stylesheet compiled with NextJS. This ensures proper priority to CSS when loading a webpage.  @next/next/no-css-tags'
+    )
+    expect(stdout).not.toContain(
+      '9:9  Warning: Stylesheet does not have an associated preload tag. This could potentially impact First paint.  @next/next/missing-preload'
+    )
+    expect(stdout).toContain('Compiled successfully')
+  })
+})
diff --git a/test/integration/eslint/test/pkg-json-eslint-config.test.js b/test/integration/eslint/test/pkg-json-eslint-config.test.js
new file mode 100644
index 000000000000..ac0069ee7b74
--- /dev/null
+++ b/test/integration/eslint/test/pkg-json-eslint-config.test.js
@@ -0,0 +1,44 @@
+import { join } from 'path'
+import { nextBuild } from 'next-test-utils'
+import { remove } from 'fs-extra'
+
+jest.setTimeout(1000 * 60 * 2)
+
+const appDir = join(__dirname, '../pkg-json-eslint-config')
+
+describe('ESLint', () => {
+  let code
+  let output
+
+  beforeAll(async () => {
+    await remove(join(appDir, '.next'))
+    let stderr
+    let stdout
+    ;({ code, stdout, stderr } = await nextBuild(appDir, [], {
+      stdout: true,
+      stderr: true,
+    }))
+    output = stderr + stdout
+  })
+
+  it('should show warnings and errors based on eslint config in package.json', async () => {
+    expect(code).toBe(0)
+    expect(output).not.toContain(
+      'The Next.js ESLint plugin was not detected in'
+    )
+    expect(output).not.toContain(
+      'No ESLint configuration was detected, but checks from the Next.js ESLint plugin were included automatically'
+    )
+    expect(output).toContain('./pages/index.js')
+    expect(output).not.toContain(
+      "8:9  Warning: A synchronous script tag can impact your webpage's performance  @next/next/no-sync-scripts"
+    )
+    expect(output).toContain(
+      '9:9  Warning: In order to use external stylesheets use @import in the root stylesheet compiled with NextJS. This ensures proper priority to CSS when loading a webpage.  @next/next/no-css-tags'
+    )
+    expect(output).toContain(
+      '9:9  Warning: Stylesheet does not have an associated preload tag. This could potentially impact First paint.  @next/next/missing-preload'
+    )
+    expect(output).toContain('Compiled successfully')
+  })
+})
diff --git a/test/integration/index-index/pages/index/index.js b/test/integration/index-index/pages/index/index.js
index 626b31302558..6a83652f5ecf 100644
--- a/test/integration/index-index/pages/index/index.js
+++ b/test/integration/index-index/pages/index/index.js
@@ -1,3 +1,3 @@
 export default function Index() {
-  return <div id="page">index > index</div>
+  return <div id="page">index &gt; index</div>
 }
diff --git a/test/integration/index-index/pages/index/index/index.js b/test/integration/index-index/pages/index/index/index.js
index 639914d7c4bb..5dfa7851c114 100644
--- a/test/integration/index-index/pages/index/index/index.js
+++ b/test/integration/index-index/pages/index/index/index.js
@@ -1,3 +1,3 @@
 export default function Index() {
-  return <div id="page">index > index > index</div>
+  return <div id="page">index &gt; index &gt; index</div>
 }
diff --git a/test/integration/index-index/pages/index/project/index.js b/test/integration/index-index/pages/index/project/index.js
index b6b50016bf4e..87892a403390 100644
--- a/test/integration/index-index/pages/index/project/index.js
+++ b/test/integration/index-index/pages/index/project/index.js
@@ -1,3 +1,3 @@
 export default function Index() {
-  return <div id="page">index > project</div>
+  return <div id="page">index &gt; project</div>
 }
diff --git a/test/integration/index-index/pages/index/user.js b/test/integration/index-index/pages/index/user.js
index b317488aaebf..398520816d1d 100644
--- a/test/integration/index-index/pages/index/user.js
+++ b/test/integration/index-index/pages/index/user.js
@@ -1,3 +1,3 @@
 export default function Index() {
-  return <div id="page">index > user</div>
+  return <div id="page">index &gt; user</div>
 }
diff --git a/test/integration/production-build-dir/next.config.js b/test/integration/production-build-dir/next.config.js
new file mode 100644
index 000000000000..397e034c301b
--- /dev/null
+++ b/test/integration/production-build-dir/next.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+  eslint: {
+    build: false,
+  },
+}
diff --git a/test/integration/production/pages/error-in-ssr-render.js b/test/integration/production/pages/error-in-ssr-render.js
index 863abf80fb1d..c2477a38db1c 100644
--- a/test/integration/production/pages/error-in-ssr-render.js
+++ b/test/integration/production/pages/error-in-ssr-render.js
@@ -1,10 +1,11 @@
+/* eslint-disable */
+
 import React from 'react'
 export default class ErrorInRenderPage extends React.Component {
   static async getInitialProps() {
     return {}
   }
 
-  // eslint-disable-next-line react/require-render-return
   render() {
     throw new Error('An Expected error occured')
   }
diff --git a/test/integration/tsconfig-verifier/pages/index.tsx b/test/integration/tsconfig-verifier/pages/index.tsx
index f8dc264a3716..47bd85b976b0 100644
--- a/test/integration/tsconfig-verifier/pages/index.tsx
+++ b/test/integration/tsconfig-verifier/pages/index.tsx
@@ -1,6 +1,6 @@
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
+/* eslint-disable */
+
 const blah: boolean = false
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
 const blah2 = import('../value').then((r) => r.default)
 
 export default () => <h3>Hello TypeScript</h3>
diff --git a/test/integration/webpack-require-hook/next.config.js b/test/integration/webpack-require-hook/next.config.js
index 01cbcf62c6cf..588fbfd05bb5 100644
--- a/test/integration/webpack-require-hook/next.config.js
+++ b/test/integration/webpack-require-hook/next.config.js
@@ -11,4 +11,7 @@ module.exports = {
       throw new Error('Webpack require hook not applying')
     return config
   },
+  eslint: {
+    build: false,
+  },
 }
diff --git a/yarn.lock b/yarn.lock
index 464133effdf5..5062f49526fa 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -93,6 +93,15 @@
     semver "^5.4.1"
     source-map "^0.5.0"
 
+"@babel/eslint-parser@7.13.4":
+  version "7.13.4"
+  resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.13.4.tgz#dd9df3c70f44d2fb5a6519e8e10ca06c67dca43a"
+  integrity sha512-WfFEd89SzqmtYox8crTLJuEXyJolZY6Uu6iJpJmw4aMu50zHbYnxzxwuVkCt2cWygw+gLkUPTtAuox7eSnrL8g==
+  dependencies:
+    eslint-scope "5.1.0"
+    eslint-visitor-keys "^1.3.0"
+    semver "7.0.0"
+
 "@babel/generator@^7.12.10", "@babel/generator@^7.12.11":
   version "7.12.11"
   resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.11.tgz#98a7df7b8c358c9a37ab07a24056853016aba3af"
@@ -1162,6 +1171,22 @@
   version "0.7.5"
   resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed"
 
+"@eslint/eslintrc@^0.1.3":
+  version "0.1.3"
+  resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.1.3.tgz#7d1a2b2358552cc04834c0979bd4275362e37085"
+  integrity sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA==
+  dependencies:
+    ajv "^6.12.4"
+    debug "^4.1.1"
+    espree "^7.3.0"
+    globals "^12.1.0"
+    ignore "^4.0.6"
+    import-fresh "^3.2.1"
+    js-yaml "^3.13.1"
+    lodash "^4.17.19"
+    minimatch "^3.0.4"
+    strip-json-comments "^3.1.1"
+
 "@firebase/analytics-types@0.3.1":
   version "0.3.1"
   resolved "https://registry.yarnpkg.com/@firebase/analytics-types/-/analytics-types-0.3.1.tgz#3c5f5d71129c88295e17e914e34b391ffda1723c"
@@ -2925,6 +2950,14 @@
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
 
+"@types/eslint@7.2.5":
+  version "7.2.5"
+  resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.5.tgz#92172ecf490c2fce4b076739693d75f30376d610"
+  integrity sha512-Dc6ar9x16BdaR3NSxSF7T4IjL9gxxViJq8RmFd+2UAyA+K6ck2W+gUwfgpG/y9TPyUuBL35109bbULpEynvltA==
+  dependencies:
+    "@types/estree" "*"
+    "@types/json-schema" "*"
+
 "@types/estree@*":
   version "0.0.45"
   resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.45.tgz#e9387572998e5ecdac221950dab3e8c3b16af884"
@@ -3034,6 +3067,11 @@
   dependencies:
     "@types/jest-diff" "*"
 
+"@types/json-schema@*":
+  version "7.0.7"
+  resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
+  integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
+
 "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6":
   version "7.0.6"
   resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0"
@@ -3568,6 +3606,11 @@ acorn-jsx@^5.1.0:
   version "5.1.0"
   resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384"
 
+acorn-jsx@^5.3.1:
+  version "5.3.1"
+  resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b"
+  integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==
+
 acorn-walk@^7.1.1:
   version "7.1.1"
   resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.1.1.tgz#345f0dffad5c735e7373d2fec9a1023e6a44b83e"
@@ -3585,6 +3628,11 @@ acorn@^7.1.0, acorn@^7.1.1:
   version "7.1.1"
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf"
 
+acorn@^7.4.0:
+  version "7.4.1"
+  resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
+  integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
+
 acorn@^8.0.4:
   version "8.0.4"
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.0.4.tgz#7a3ae4191466a6984eee0fe3407a4f3aa9db8354"
@@ -3681,6 +3729,11 @@ anser@1.4.9:
   version "1.4.9"
   resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.9.tgz#1f85423a5dcf8da4631a341665ff675b96845760"
 
+ansi-colors@^4.1.1:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
+  integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
+
 ansi-escapes@^3.0.0:
   version "3.2.0"
   resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b"
@@ -5624,7 +5677,7 @@ cross-spawn@^5.0.1:
     shebang-command "^1.2.0"
     which "^1.2.9"
 
-cross-spawn@^7.0.0, cross-spawn@^7.0.3:
+cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
   version "7.0.3"
   resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
   integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
@@ -6064,7 +6117,7 @@ deep-extend@^0.6.0:
   version "0.6.0"
   resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
 
-deep-is@~0.1.3:
+deep-is@^0.1.3, deep-is@~0.1.3:
   version "0.1.3"
   resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
 
@@ -6468,6 +6521,13 @@ enhanced-resolve@^4.3.0:
     memory-fs "^0.5.0"
     tapable "^1.0.0"
 
+enquirer@^2.3.5:
+  version "2.3.6"
+  resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d"
+  integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==
+  dependencies:
+    ansi-colors "^4.1.1"
+
 entities@^1.1.1, entities@~1.1.1:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
@@ -6707,6 +6767,14 @@ eslint-plugin-react@7.19.0:
     string.prototype.matchall "^4.0.2"
     xregexp "^4.3.0"
 
+eslint-scope@5.1.0:
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5"
+  integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==
+  dependencies:
+    esrecurse "^4.1.0"
+    estraverse "^4.1.1"
+
 eslint-scope@^4.0.3:
   version "4.0.3"
   resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848"
@@ -6722,6 +6790,14 @@ eslint-scope@^5.0.0:
     esrecurse "^4.1.0"
     estraverse "^4.1.1"
 
+eslint-scope@^5.1.0:
+  version "5.1.1"
+  resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
+  integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
+  dependencies:
+    esrecurse "^4.3.0"
+    estraverse "^4.1.1"
+
 eslint-utils@^1.4.3:
   version "1.4.3"
   resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f"
@@ -6734,10 +6810,22 @@ eslint-utils@^2.0.0:
   dependencies:
     eslint-visitor-keys "^1.1.0"
 
+eslint-utils@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27"
+  integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==
+  dependencies:
+    eslint-visitor-keys "^1.1.0"
+
 eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
 
+eslint-visitor-keys@^1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e"
+  integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==
+
 eslint@6.8.0:
   version "6.8.0"
   resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb"
@@ -6780,6 +6868,49 @@ eslint@6.8.0:
     text-table "^0.2.0"
     v8-compile-cache "^2.0.3"
 
+eslint@7.9.0:
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.9.0.tgz#522aeccc5c3a19017cf0cb46ebfd660a79acf337"
+  integrity sha512-V6QyhX21+uXp4T+3nrNfI3hQNBDa/P8ga7LoQOenwrlEFXrEnUEE+ok1dMtaS3b6rmLXhT1TkTIsG75HMLbknA==
+  dependencies:
+    "@babel/code-frame" "^7.0.0"
+    "@eslint/eslintrc" "^0.1.3"
+    ajv "^6.10.0"
+    chalk "^4.0.0"
+    cross-spawn "^7.0.2"
+    debug "^4.0.1"
+    doctrine "^3.0.0"
+    enquirer "^2.3.5"
+    eslint-scope "^5.1.0"
+    eslint-utils "^2.1.0"
+    eslint-visitor-keys "^1.3.0"
+    espree "^7.3.0"
+    esquery "^1.2.0"
+    esutils "^2.0.2"
+    file-entry-cache "^5.0.1"
+    functional-red-black-tree "^1.0.1"
+    glob-parent "^5.0.0"
+    globals "^12.1.0"
+    ignore "^4.0.6"
+    import-fresh "^3.0.0"
+    imurmurhash "^0.1.4"
+    is-glob "^4.0.0"
+    js-yaml "^3.13.1"
+    json-stable-stringify-without-jsonify "^1.0.1"
+    levn "^0.4.1"
+    lodash "^4.17.19"
+    minimatch "^3.0.4"
+    natural-compare "^1.4.0"
+    optionator "^0.9.1"
+    progress "^2.0.0"
+    regexpp "^3.1.0"
+    semver "^7.2.1"
+    strip-ansi "^6.0.0"
+    strip-json-comments "^3.1.0"
+    table "^5.2.3"
+    text-table "^0.2.0"
+    v8-compile-cache "^2.0.3"
+
 espree@^6.1.2:
   version "6.1.2"
   resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.2.tgz#6c272650932b4f91c3714e5e7b5f5e2ecf47262d"
@@ -6788,6 +6919,15 @@ espree@^6.1.2:
     acorn-jsx "^5.1.0"
     eslint-visitor-keys "^1.1.0"
 
+espree@^7.3.0:
+  version "7.3.1"
+  resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6"
+  integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==
+  dependencies:
+    acorn "^7.4.0"
+    acorn-jsx "^5.3.1"
+    eslint-visitor-keys "^1.3.0"
+
 esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
@@ -6798,17 +6938,31 @@ esquery@^1.0.1:
   dependencies:
     estraverse "^4.0.0"
 
+esquery@^1.2.0:
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57"
+  integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==
+  dependencies:
+    estraverse "^5.1.0"
+
 esrecurse@^4.1.0:
   version "4.2.1"
   resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf"
   dependencies:
     estraverse "^4.1.0"
 
+esrecurse@^4.3.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
+  integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
+  dependencies:
+    estraverse "^5.2.0"
+
 estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1:
   version "4.3.0"
   resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
 
-estraverse@^5.2.0:
+estraverse@^5.1.0, estraverse@^5.2.0:
   version "5.2.0"
   resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880"
   integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==
@@ -7116,7 +7270,7 @@ fast-json-stable-stringify@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
 
-fast-levenshtein@~2.0.6:
+fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
   version "2.0.6"
   resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
 
@@ -9858,6 +10012,14 @@ levn@^0.3.0, levn@~0.3.0:
     prelude-ls "~1.1.2"
     type-check "~0.3.2"
 
+levn@^0.4.1:
+  version "0.4.1"
+  resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
+  integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
+  dependencies:
+    prelude-ls "^1.2.1"
+    type-check "~0.4.0"
+
 libnpmaccess@^4.0.1:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-4.0.1.tgz#17e842e03bef759854adf6eb6c2ede32e782639f"
@@ -11484,6 +11646,18 @@ optionator@^0.8.1, optionator@^0.8.3:
     type-check "~0.3.2"
     word-wrap "~1.2.3"
 
+optionator@^0.9.1:
+  version "0.9.1"
+  resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499"
+  integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==
+  dependencies:
+    deep-is "^0.1.3"
+    fast-levenshtein "^2.0.6"
+    levn "^0.4.1"
+    prelude-ls "^1.2.1"
+    type-check "^0.4.0"
+    word-wrap "^1.2.3"
+
 ora@2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/ora/-/ora-2.0.0.tgz#8ec3a37fa7bffb54a3a0c188a1f6798e7e1827cd"
@@ -12826,6 +13000,11 @@ pre-commit@1.2.2:
     spawn-sync "^1.0.15"
     which "1.2.x"
 
+prelude-ls@^1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
+  integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
+
 prelude-ls@~1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
@@ -13499,6 +13678,11 @@ regexpp@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.0.0.tgz#dd63982ee3300e67b41c1956f850aa680d9d330e"
 
+regexpp@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2"
+  integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==
+
 regexpu-core@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b"
@@ -14146,7 +14330,7 @@ semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0:
   resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
   integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
 
-semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.3.2, semver@^7.3.4:
+semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4:
   version "7.3.4"
   resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
   integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==
@@ -14900,6 +15084,11 @@ strip-json-comments@^3.0.1:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7"
 
+strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
+  integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
+
 strip-json-comments@~2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
@@ -15535,6 +15724,13 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
   version "0.14.5"
   resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
 
+type-check@^0.4.0, type-check@~0.4.0:
+  version "0.4.0"
+  resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
+  integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
+  dependencies:
+    prelude-ls "^1.2.1"
+
 type-check@~0.3.2:
   version "0.3.2"
   resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
@@ -16240,7 +16436,7 @@ wide-align@^1.1.0:
   dependencies:
     string-width "^1.0.2 || 2"
 
-word-wrap@~1.2.3:
+word-wrap@^1.2.3, word-wrap@~1.2.3:
   version "1.2.3"
   resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
 
