Use the npx @eslint/migrate-config .eslintrc.json command.

It produces ugly output, but seems to work - I assume we will eventually be able to do it as recommended in the eslint docs.

Heres the output I got (placed inside eslint.config.mjs file).

import path from "node:path";
import { fileURLToPath } from "node:url";
import js from "@eslint/js";
import { FlatCompat } from "@eslint/eslintrc";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
    baseDirectory: __dirname,
    recommendedConfig: js.configs.recommended,
    allConfig: js.configs.all
});
export default [...compat.extends("next")];
🌐
Next.js
nextjs.org › docs › app › api-reference › config › eslint
Configuration: ESLint | Next.js
2 weeks ago - If you already have ESLint configured in your application, there are two approaches to integrate Next.js linting rules, depending on your setup. Use @next/eslint-plugin-next directly if you have any of the following already configured:
🌐
npm
npmjs.com › package › eslint-config-next
eslint-config-next - npm
Latest version: 16.1.6, last published: a month ago. Start using eslint-config-next in your project by running `npm i eslint-config-next`. There are 1677 other projects in the npm registry using eslint-config-next.
      » npm install eslint-config-next
    
Published   Jan 27, 2026
Version   16.1.6
🌐
ESLint
eslint.org › docs › latest › use › configure › configuration-files
Configuration Files - ESLint - Pluggable JavaScript Linter
With this configuration, the semi rule is enabled for all files that match the default files in ESLint. So if you pass example.js to ESLint, the semi rule is applied. If you pass a non-JavaScript file, like example.txt, the semi rule is not applied because there are no other configuration objects that match that filename.
🌐
GitHub
github.com › vercel › next.js › discussions › 49337
How to use new "flat config" approach in Eslint? · vercel/next.js · Discussion #49337
I have created a package eslint-config-next-flat (Source code) that is (roughly) a port of the eslint-config-next for FlatConfig.
Author   vercel
🌐
DEV Community
dev.to › jordanahaines › just-use-this-nextjs-eslint-configuration-540
Just use this Next.js Eslint Configuration - DEV Community
January 12, 2025 - npm i --save eslint typescript-eslint eslint-config-next eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-tailwindcss eslint-plugin-unicorn
🌐
CodeSandbox
codesandbox.io › examples › package › eslint-config-next
eslint-config-next examples - CodeSandbox
nextjs-dynamic-routes_lotr-app-dynamic-routesNext.js Dynamic Routes: Lord of the Rings Dynamic Routes
Find elsewhere
🌐
GitHub
github.com › vercel › next.js › discussions › 50453
How can I use the new ESLint flat config in a Next.js project and also use 'canonical' rules? · vercel/next.js · Discussion #50453
// mimic CommonJS variables -- not needed if using CommonJS const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); const compat = new FlatCompat({ baseDirectory: dirname, }); const customRules = { ...
Author   vercel
Top answer
1 of 3
37

Update

NextJS now has official guide to add eslint to project: https://nextjs.org/docs/basic-features/eslint Additionally you need to install ESLint extension.

Also, If you're looking for ESLint with typescript support: https://gourav.io/blog/nextjs-cheatsheet

Old answer:

Install ESLint

npm i eslint --save-dev

Install ESLint plugins:

npx install-peerdeps --dev eslint-config-airbnb

Above single command will install 6 plugins: eslint-config-airbnb, eslint-plugin-import, eslint-plugin-react, eslint-plugin-react-hooks, and eslint-plugin-jsx-a11y. You can also install these plugins individually.

Install babel eslint

npm i -D babel-eslint

Install prettier plugin (optional, so that prettier doesn't mess up with linting)

 npm i -D eslint-config-prettier eslint-plugin-prettier

Your "devDependencies" should look something like this:

"devDependencies": {
    "babel-eslint": "^10.1.0",
    "eslint": "^6.8.0",
    "eslint-config-airbnb": "^18.1.0",
    "eslint-config-prettier": "^6.11.0",
    "eslint-plugin-import": "^2.20.2",
    "eslint-plugin-jsx-a11y": "^6.2.3",
    "eslint-plugin-prettier": "^3.1.3",
    "eslint-plugin-react": "^7.20.0",
    "eslint-plugin-react-hooks": "^2.5.1"
  }

Now, create a file .eslintrc.json at root of project. Paste below config:

{
  "env": {
    "browser": true,
    "commonjs": true,
    "es6": true,
    "node": true
  },
  "parser": "babel-eslint",
  "extends": [
    "eslint:recommended",
    "airbnb",
    "airbnb/hooks",
    "plugin:react/recommended",
    "plugin:import/errors",
    "plugin:import/warnings",
    "plugin:jsx-a11y/recommended",
    // "plugin:react-hooks/recommended",
    // always put prettier at last
    "prettier"
  ],
  "globals": {
    "Atomics": "readonly",
    "SharedArrayBuffer": "readonly"
  },
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true // enable linting for jsx files
    },
    "ecmaVersion": 11,
    "sourceType": "module"
  },
  "settings": {
    "react": {
      "version": "detect"
    }
  },
  "plugins": ["react", "react-hooks"],
  "rules": {
    // NextJs specific fix: suppress errors for missing 'import React' in files for nextjs
    "react/react-in-jsx-scope": "off",
   // NextJs specific fix: allow jsx syntax in js files
    "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], //should add ".ts" if typescript project
    "react/display-name": 1
  }
}

Also, install ESLint extension for VSCode.

Reload VSCode window once to get proper linting

ESLint will automatically start detecting errors/warnings in *.js and *.jsx files. If that's not the case then either your project has no linting errors or ESLint is not properly setup. To test if linting works run eslint command in terminal with folder path i.e. eslint pages/** and notice output.

To disable linting of some files/folders you can create a .eslintignore at the root of project.

.eslintignore:

# don't ever lint node_modules
node_modules
# don't lint build output (make sure it's set to your correct build folder name)
dist
# don't lint nyc coverage output
coverage

Finally, you can also add linting to scripts in package.json as a part of your build/deploy process:

"scripts": {
    "lint": "eslint ./components/** ./pages/** -c .eslintrc.json --ext js,jsx",
    "lint-fix": "eslint ./components/** ./pages/** -c .eslintrc.json --fix --ext js,jsx",
}

See my current ESLint configuration for NextJS Typescript project: https://github.com/GorvGoyl/Personal-Site-Gourav.io/blob/main/.eslintrc.js

2 of 3
15

you need to install required npm modules.

with Npm:

npm i -D babel-eslint eslint-config-airbnb eslint eslint-plugin-jsx-a11y eslint-plugin-import eslint-plugin-react eslint-plugin-react-hooks

with Yarn:

yarn add -D babel-eslint eslint-config-airbnb eslint eslint-plugin-jsx-a11y eslint-plugin-import eslint-plugin-react eslint-plugin-react-hooks

Here is related article about that

https://medium.com/@melih193/next-js-eslint-setup-tutorial-for-airbnb-config-c2b04183a92a

🌐
GitHub
github.com › vercel › next.js › issues › 85947
Docs: ESLint config ambiguities · Issue #85947 · vercel/next.js
November 9, 2025 - The easiest way would be to instead start with a short text only about the config, then show how to install it (as already done) and then explain it contains the @next/eslint-plugin-next, as well as the other plugins (react etc.).
Author   thernstig
🌐
ESLint
eslint.org › docs › latest › use › getting-started
Getting Started with ESLint - ESLint - Pluggable JavaScript Linter
If you want to use a specific shareable config that is hosted on npm, you can use the --config option and specify the package name: ... # use `eslint-config-xo` shared config - npm 7+ npm init @eslint/config@latest -- --config eslint-config-xo
🌐
Next.js
nextjs.org › docs › 14 › app › building-your-application › configuring › eslint
Configuring: ESLint | Next.js
August 22, 2024 - If you already use a separate ESLint configuration and want to include eslint-config-next, ensure that it is extended last after other configurations. For example:
🌐
GitHub
github.com › vercel › next.js › blob › canary › packages › eslint-config-next › package.json
next.js/packages/eslint-config-next/package.json at canary · vercel/next.js
"name": "eslint-config-next", "version": "16.2.0-canary.60", "description": "ESLint configuration used by Next.js.", "license": "MIT", "repository": { "url": "vercel/next.js", "directory": "packages/eslint-config-next" }, "homepage": "https://nextjs.org/docs/app/api-reference/config/eslint", "files": [ "dist" ], "dependencies": { "@next/eslint-plugin-next": "16.2.0-canary.60", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jsx-a11y": "^6.10.0", "eslint-plugin-react": "^7.37.0", "eslint-plugin-react-hooks": "^7.0.0", "globals": "16.4.0", "typescript-eslint": "^8.46.0" }, "peerDependencies": { "eslint": ">=9.0.0", "typescript": ">=3.3.1" }, "peerDependenciesMeta": { "typescript": { "optional": true ·
Author   vercel
🌐
freeCodeCamp
freecodecamp.org › news › how-to-set-up-eslint-prettier-stylelint-and-lint-staged-in-nextjs
How to Set Up ESLint, Prettier, StyleLint, and lint-staged in Next.js
May 30, 2025 - For example, we can use rules from the eslint-plugin-next mentioned above by running npm install --save-dev eslint-plugin-next, then placing the following content in the ESLint config file .eslintrc.json in the app root:
🌐
npm
npmjs.com › package › @next › eslint-plugin-next
@next/eslint-plugin-next - npm
Documentation for @next/eslint-plugin-next can be found at: https://nextjs.org/docs/app/api-reference/config/eslint
      » npm install @next/eslint-plugin-next
    
Published   Jan 27, 2026
Version   16.1.6
🌐
GitHub
github.com › Goldziher › eslint-config-next
GitHub - Goldziher/eslint-config-next: This is a strict NextJS/Typescript eslint configuration
import eslintConfigTrumpet from "@trumpet/eslint-config-next"; export default [ ...eslintConfigTrumpet, // other configurations below, for example: { rules: { "@typescript-eslint/no-unsafe-member-access": "off", }, }, ];
Author   Goldziher
🌐
Paulintrognon
paulintrognon.fr › blog › typescript-prettier-eslint-next-js
Start a clean Next.js project with TypeScript, ESLint and Prettier
We have to separate prettier format of TS files and other files, because we don't want ESLint to fix errors in TS files and at the same time having Prettier format the files: that would results in conflicts. For the TypeScript (tsc) command, we don't pass filenames as TypeScript cannot be run on isolated files. Now we need to change our pre-commit hook (in the .husky/pre-commit file): #!/bin/sh . "$(dirname "$0")/_/husky.sh" yarn lint-staged # Replace the last line with "yarn lint-staged" Let's try the new configuration.
🌐
Chris
chris.lu › web_development › tutorials › next-js-static-first-mdx-starterkit › linting-setup-using-eslint
Linting setup using ESLint 9 flat config - Next.js 15 Tutorial
For a complete list of rules that the Next.js ESLint plugin adds check out the Nextjs "ESLint rules" documentation or have a look at the eslint-plugin-next rules directory on GitHub ... We are transitioning to a new config system in ESLint v9.0.0. The config system shared on this page is currently the default but will be deprecated in v9.0.0. You can opt-in to the new config system by following the instructions in the documentation. You can still use eslintrc (classic) configuration files but it is recommended that you switch to the new flat config files ... For example the eslint-plugin-react-hooks announced on Oct.