| | |

ESLint 02 🛡️ Installation — Node requirements & @eslint/create-config

⏱️ Estimated read: 11 min | |

ESLint is a Node.js package, and its installation is bounded by two constraints that change with every major release: the minimum Node.js version the package supports, and the configuration generator that scaffolds the initial setup. The first constraint is non-negotiable—ESLint will refuse to run on an unsupported Node version. The second is a convenience that has become the recommended installation path: @eslint/create-config, invoked through npm init @eslint/config, walks through a short questionnaire and writes a working flat configuration file.

This chapter covers the Node.js version requirements for current ESLint releases, the exact commands for installing ESLint both locally and globally, and the @eslint/create-config workflow in detail. It explains what the generator asks, what files it produces, how it detects the project’s module system and framework, and why the generated configuration is a starting point rather than a finished setup.

Key point: ESLint v10 requires Node.js ^20.19.0 || ^22.13.0 || >=24. Installing ESLint on an older Node version produces a runtime error, not a warning. Verify the Node version before installing.


Why installation has these constraints

The Node.js support policy problem. ESLint follows a formal Node.js support policy tied to major releases. When a Node.js version reaches end-of-life, the next ESLint major drops support for it. ESLint v9 supported Node.js ^18.18.0, ^20.9.0, or >=21.1.0 . ESLint v10 raised the floor to ^20.19.0, ^22.13.0, or >=24, dropping Node 18 entirely and requiring patch-level minimums within the supported lines . The patch-level minimum for Node 20 (20.19.0) exists because that release enabled native require(esm) support by default, which ESLint v10 relies on .

The configuration format transition problem. ESLint v9 introduced flat config as the default and deprecated the legacy .eslintrc format. The @eslint/create-config utility generates flat config files (eslint.config.js or .mjs). Projects that still need the legacy format must pass --eslintrc explicitly to the generator . This transition is why the installation chapter must cover the config generator: a bare npm install eslint produces no configuration, and ESLint does nothing without one.

The local versus global problem. ESLint’s documentation explicitly recommends against global installation. A global ESLint cannot resolve project-local plugins or shareable configs, because those packages are installed in the project’s node_modules, not the global prefix . The local install ensures that the ESLint version, the plugins, and the configuration all resolve from the same project context.


a. Node.js version requirements

The current ESLint release requires Node.js versions ^20.19.0, ^22.13.0, or >=24, built with SSL and ICU support . Official Node.js distributions include both by default.

# Verify the Node.js version before installing
node --version
# Expected: v20.19.0 or higher, v22.13.0 or higher, or v24+

# If the version is too old, upgrade Node.js first
# Using nvm:
nvm install 22
nvm use 22

The requirement is enforced at runtime. Running ESLint on an unsupported Node version produces an error rather than degraded behavior, which is preferable to silent misbehavior but still blocks installation workflows until the environment is corrected.

b. Local installation

The local install adds ESLint to the project’s devDependencies. The --save-dev flag places it there, which is correct because ESLint is a development tool and should not be part of the production dependency tree.

# Install ESLint locally
npm install --save-dev eslint

# Verify the installed version
npx eslint --version

The local binary lives at node_modules/.bin/eslint. Running it through npx resolves that binary rather than downloading a temporary copy, as long as the local install exists. The documentation notes that global installation is possible but “not recommended,” and that plugins and shareable configs must be installed locally regardless .

c. The @eslint/create-config generator

The recommended installation path is not a bare npm install. It is the configuration generator, which installs ESLint along with any plugins the project needs and writes a flat config file.

# Using npm (requires package.json to exist)
npm init @eslint/config@latest

# Using npx directly
npx @eslint/create-config@latest

The generator checks for Node.js compatibility. Its own prerequisites are ^18.18.0, ^20.9.0, or >=21.1.0, which are lower than ESLint v10’s requirements because the generator may run before the ESLint version is resolved . After the ESLint version is installed, the stricter requirement applies.

The generator asks a sequence of questions to determine the configuration:

✔ How would you like to use ESLint? · problems (or syntax, or style)
✔ What type of modules does your project use? · esm (or commonjs)
✔ Which framework does your project use? · react (or vue, none)
✔ Does your project use TypeScript? · No / Yes
✔ Where does your code run? · browser (or node)
✔ Would you like to install them now? · No / Yes
✔ Which package manager do you want to use? · npm (or yarn, pnpm)

The answers determine which packages are installed (eslint, @eslint/js, globals, typescript-eslint, eslint-plugin-react, and so on) and what the generated eslint.config.js contains . The generator writes a flat config file using the modern export default syntax, with languageOptions for globals and parser settings, and a rules object for any rule customizations.

d. What the generator produces and what it misses

The generated eslint.config.js is a functional starting point, not a complete linting strategy. It enables the recommended rule set for the detected environment and configures the parser and globals. It does not enable type-aware rules (which require a tsconfig.json reference and additional configuration), does not add project-specific rules, and does not integrate with a formatter.

// A generated config typically looks like this:
import js from "@eslint/js";
import globals from "globals";

export default [
  js.configs.recommended,
  {
    languageOptions: {
      globals: {
        ...globals.node,
      },
    },
    rules: {
      // project-specific rules go here
    },
  },
];

The generated file is the foundation. The next chapter covers how to extend it with plugins, custom rules, and the eslint-config-prettier integration that prevents formatting conflicts.


Complete Example Session

# ============================================
# PART 1: VERIFY NODE.JS VERSION
# ============================================
node --version
# Expected output: v20.19.0 or higher, v22.13.0 or higher, or v24+

# If the version is unsupported, upgrade before proceeding.
# ============================================
# PART 2: ENSURE package.json EXISTS
# ============================================
# The generator requires a package.json in the current directory
ls package.json

# If it does not exist:
npm init -y
# ============================================
# PART 3: RUN THE CONFIG GENERATOR
# ============================================
npm init @eslint/config@latest

# The generator installs @eslint/create-config temporarily,
# asks configuration questions, and writes eslint.config.js.
# ============================================
# PART 4: ANSWER THE GENERATOR QUESTIONS
# ============================================
# Example answers for a Node.js ESM project:
# How would you like to use ESLint? → problems
# What type of modules? → esm
# Which framework? → none
# TypeScript? → No
# Where does your code run? → node
# Install dependencies now? → Yes
# Package manager? → npm
# ============================================
# PART 5: INSPECT THE GENERATED CONFIG
# ============================================
cat eslint.config.js

# Expected structure: imports, js.configs.recommended,
# languageOptions with globals, empty rules object.
# ============================================
# PART 6: RUN ESLINT FOR THE FIRST TIME
# ============================================
npx eslint .

# ESLint analyzes all supported files and reports violations.
# A clean run exits with code 0.
# ============================================
# PART 7: FIX AUTO-FIXABLE ISSUES
# ============================================
npx eslint . --fix

# Rules that provide fixes are applied in place.
# Remaining violations are reported.
# ============================================
# PART 8: ADD AN NPM SCRIPT
# ============================================
# package.json:
# "scripts": { "lint": "eslint ." }

npm run lint
# Equivalent to npx eslint .
# ============================================
# PART 9: USE A SHARED CONFIG WITH THE GENERATOR
# ============================================
npm init @eslint/config@latest -- --config eslint-config-standard

# The --config flag specifies an npm-hosted shareable config
# instead of generating rules from scratch.
# ============================================
# PART 10: TROUBLESHOOT A VERSION FAILURE
# ============================================
# If ESLint fails with a Node version error:
# 1. Check node --version
# 2. Upgrade Node.js to a supported version
# 3. Delete node_modules and package-lock.json
# 4. Reinstall: npm install
# 5. Re-run: npx eslint --version

The ten parts covered version verification, package initialization, generator invocation, question answering, config inspection, first run, auto-fix, npm scripting, shared config usage, and version failure troubleshooting.


Quick Reference

Node.js requirements

ESLint versionNode.js requirement
v10.x^20.19.0 || ^22.13.0 || >=24
v9.x^18.18.0 || ^20.9.0 || >=21.1.0

Installation commands

MethodCommand
Generator (npm)npm init @eslint/config@latest
Generator (npx)npx @eslint/create-config@latest
Local install onlynpm install --save-dev eslint
Global install (not recommended)npm install --global eslint

Generator options

FlagEffect
--config <name>Use a specific shareable config from npm
--eslintrcGenerate legacy .eslintrc format instead of flat config

Generated files

FilePurpose
eslint.config.jsFlat config (default output)
eslint.config.mjsESM flat config (if project type is module)

Best Practices

✅ Do This:

# Verify Node.js version before installing
node --version                                            # ✅
# Use the config generator for new projects
npm init @eslint/config@latest                            # ✅
# Install ESLint locally, not globally
npm install --save-dev eslint                             # ✅
# Run the generated config against the project immediately
npx eslint .                                              # ✅

❌ Don’t Do This:

# Install ESLint globally and expect plugins to resolve
npm install --global eslint                               # ❌
# Run the generator without a package.json
npm init @eslint/config@latest                            # ❌ (fails)
# Ignore the Node version requirement
node --version  # v18.x                                   # ❌
# Treat the generated config as complete without review
cat eslint.config.js  # no project-specific rules         # ❌

Common Pitfalls

PitfallWhy It HappensFix
npm init @eslint/config failsNo package.json in the directoryRun npm init -y first
ESLint throws Node version errorNode.js is below the required minimumUpgrade Node.js to a supported version
Plugins cannot be foundESLint installed globally, plugins installed locallyInstall ESLint locally; remove global install
Generated config uses wrong module typeAnswer to “module type” question was incorrectRe-run generator or edit eslint.config.js manually
eslint.config.js not recognizedESLint v8 installed instead of v9/v10Verify npx eslint --version; upgrade if needed

Real-World Examples

1. Check Node.js version

node --version

2. Run the config generator

npm init @eslint/config@latest

3. Run the generator with npx directly

npx @eslint/create-config@latest

4. Use a shareable config

npm init @eslint/config@latest -- --config eslint-config-standard

5. Generate legacy eslintrc format

npm init @eslint/config@latest -- --eslintrc

6. Install ESLint locally without the generator

npm install --save-dev eslint

7. Verify ESLint version

npx eslint --version

8. Inspect the generated config

cat eslint.config.js

9. Run ESLint with auto-fix

npx eslint . --fix

10. Add a lint script to package.json

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

Visual

The installation and configuration flow

┌─────────────────────────────────────────────────────────────┐
│  ESLINT INSTALLATION FLOW                                    │
│                                                              │
│  1. Verify Node.js version                                   │
│       │                                                      │
│       ▼                                                      │
│  2. Ensure package.json exists                               │
│       │                                                      │
│       ▼                                                      │
│  3. Run npm init @eslint/config@latest                       │
│       │                                                      │
│       ├── Answer module type question                        │
│       ├── Answer framework question                          │
│       ├── Answer TypeScript question                         │
│       └── Answer environment question                        │
│       │                                                      │
│       ▼                                                      │
│  4. Generator installs dependencies                          │
│       │                                                      │
│       ▼                                                      │
│  5. Generator writes eslint.config.js                        │
│       │                                                      │
│       ▼                                                      │
│  6. npx eslint . (verify it works)                           │
└─────────────────────────────────────────────────────────────┘

Node.js version support across ESLint majors

┌─────────────────────────────────────────────────────────────┐
│  NODE.JS SUPPORT BY ESLINT VERSION                           │
│                                                              │
│  ESLint v9.x                                                 │
│    ^18.18.0 || ^20.9.0 || >=21.1.0                          │
│    Supports Node 18, 20, 21+                                │
│                                                              │
│  ESLint v10.x                                                │
│    ^20.19.0 || ^22.13.0 || >=24                             │
│    Drops Node 18 (EOL April 2025)                           │
│    Requires Node 20.19.0+ (require(esm) support)            │
│    Requires Node 22.13.0+ (LTS patch level)                 │
│                                                              │
│  The pattern: each major release tracks Node.js EOL dates.  │
└─────────────────────────────────────────────────────────────┘

What the generator asks and produces

┌─────────────────────────────────────────────────────────────┐
│  GENERATOR QUESTION → CONFIG OUTPUT                          │
│                                                              │
│  "Module type?"                                              │
│    esm → import syntax in config, ESM parser                │
│    commonjs → require in config, script parser              │
│                                                              │
│  "Framework?"                                                │
│    react → eslint-plugin-react, react hooks rules           │
│    vue → eslint-plugin-vue                                  │
│    none → no framework plugin                               │
│                                                              │
│  "TypeScript?"                                               │
│    yes → typescript-eslint, parser, type-aware rules        │
│    no → default parser                                      │
│                                                              │
│  "Where does code run?"                                      │
│    browser → browser globals (window, document)             │
│    node → node globals (process, __dirname)                 │
└─────────────────────────────────────────────────────────────┘

Local vs global resolution

┌─────────────────────────────────────────────────────────────┐
│  WHY LOCAL INSTALLATION IS REQUIRED                          │
│                                                              │
│  Project structure:                                          │
│    project/                                                  │
│    ├── node_modules/                                         │
│    │   ├── eslint/          ← local ESLint                   │
│    │   └── eslint-plugin-react/ ← local plugin              │
│    ├── eslint.config.js                                      │
│    └── package.json                                          │
│                                                              │
│  Global ESLint tries to resolve eslint-plugin-react:         │
│    /usr/local/lib/node_modules/eslint-plugin-react           │
│    → Not found (plugin is in project/node_modules)          │
│    → Error                                                   │
│                                                              │
│  Local ESLint resolves the plugin from the same node_modules │
│  tree. That is why the docs say: install locally.            │
└─────────────────────────────────────────────────────────────┘

Summary

ItemValue
ESLint v10 Node requirement^20.19.0 || ^22.13.0 || >=24
ESLint v9 Node requirement^18.18.0 || ^20.9.0 || >=21.1.0
Recommended install commandnpm init @eslint/config@latest
Direct generator commandnpx @eslint/create-config@latest
Local install onlynpm install --save-dev eslint
Generated fileeslint.config.js (flat config)
Legacy format flag--eslintrc
Global installNot recommended

Key takeaways:

  • Node.js version is a hard gate. ESLint v10 requires ^20.19.0 || ^22.13.0 || >=24. Verify the version before installing, because the failure mode is a runtime error, not a warning.
  • The patch-level minimums exist for a reason. Node 20.19.0 enabled require(esm) by default, and ESLint v10 depends on it. Older patch releases in the same major line are unsupported.
  • The config generator is the recommended installation path. npm init @eslint/config@latest installs ESLint, asks about the project, and writes a working eslint.config.js in one step.
  • The generator produces a starting point, not a finished configuration. It enables recommended rules for the detected environment but does not add project-specific rules, type-aware analysis, or formatter integration.
  • Local installation is not optional for plugins. A global ESLint cannot resolve plugins installed in a project’s node_modules. The documentation explicitly recommends against global installation for this reason.
  • The legacy .eslintrc format still exists but is no longer the default. Projects that need it must pass --eslintrc to the generator.

Remember: ESLint installation is two decisions in one step: the Node.js version determines whether ESLint can run, and the generator determines what ESLint will check. Verify the version first, because a version mismatch blocks everything else. Then run the generator, answer its questions accurately, and inspect the generated config before treating it as final. The generator saves the boilerplate, but it does not know your project’s conventions, your framework’s specific pitfalls, or whether you use a formatter. Those decisions belong to the configuration chapter, not the installation chapter.

Was this helpful?


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!