# Keep your code clean with ESLint

> Learn how ESLint finds problems in JavaScript code, how to create a modern flat configuration, run the linter, fix issues, and disable a rule when needed.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2018-03-12 | Updated: 2026-07-18 | Topics: [DevTools](https://flaviocopes.com/tags/devtool/) | Canonical: https://flaviocopes.com/eslint/

ESLint analyzes JavaScript code and reports patterns that can cause bugs or make the code inconsistent.

It can catch unused variables, unreachable code, duplicate `case` clauses, accidental globals, and many other problems before you run the program.

ESLint is configurable. You choose the rules, plugins, and file types that make sense for your project.

## Install and configure ESLint

ESLint's official setup command installs the required packages and creates a configuration:

```bash
npm init @eslint/config@latest
```

Run it from a project that already has a `package.json` file. The command asks where the code runs and which module system or framework you use.

It creates an `eslint.config.js` or `eslint.config.mjs` file. This **flat config** format has been the default since ESLint 9.

The [official getting started guide](https://eslint.org/docs/latest/use/getting-started) lists the current Node.js requirements and walks through the setup questions.

## A small ESLint configuration

Here is a minimal flat configuration using ESLint's recommended JavaScript rules:

```js
import js from '@eslint/js'
import { defineConfig } from 'eslint/config'

export default defineConfig([
  {
    files: ['**/*.js'],
    plugins: { js },
    extends: ['js/recommended'],
    rules: {
      'no-console': 'warn',
    },
  },
])
```

Configuration files export an array. You can add separate objects for source files, tests, or any other group that needs different rules.

The [flat configuration reference](https://eslint.org/docs/latest/use/configure/configuration-files) explains `files`, `ignores`, plugins, shared configurations, and language options.

Old `.eslintrc` files use the previous configuration system. If you maintain one, ESLint provides an [official migration guide](https://eslint.org/docs/latest/use/configure/migration-guide) and this command:

```bash
npx @eslint/migrate-config .eslintrc.json
```

Review the generated config before using it. Some JavaScript-based legacy configurations need manual work.

## Run ESLint

Lint the current project with:

```bash
npx eslint .
```

You can lint one file:

```bash
npx eslint src/app.js
```

Add a script to `package.json` when you run ESLint often:

```json
{
  "scripts": {
    "lint": "eslint ."
  }
}
```

Then run:

```bash
npm run lint
```

Some rules can fix code automatically:

```bash
npx eslint . --fix
```

Always review the changes. Not every lint problem has an automatic fix.

## Configure rules

Each rule has one of three severity levels:

- `off` disables the rule
- `warn` reports a warning without making ESLint exit with an error
- `error` reports an error and makes ESLint exit with a non-zero status

For example:

```js
export default [
  {
    rules: {
      'no-console': 'warn',
      'no-unused-vars': 'error',
    },
  },
]
```

ESLint does not enable every rule automatically. Start with a recommended configuration, then add project-specific rules where they provide value.

See the [official rules reference](https://eslint.org/docs/latest/rules/) for the current list.

## ESLint and Prettier

[Prettier](https://flaviocopes.com/prettier/) formats code. ESLint checks code quality.

Use Prettier for formatting and ESLint for suspicious code. If stylistic ESLint rules conflict with Prettier, add `eslint-config-prettier` to turn those rules off.

## Disable a rule for one line

Sometimes a rule does not fit one specific line. Disable only that rule:

```js
alert('Saved') // eslint-disable-line no-alert
```

For the next line:

```js
// eslint-disable-next-line no-console
console.log('Server started')
```

Keep disable comments narrow and explain unusual exceptions when the reason is not clear.
