ESLint 04 🛡️ CLI Basics — Running npx eslint on files and directories
The ESLint CLI is how you run the linter against your codebase. The command shape is simple: npx eslint followed by one or more file paths, directory paths, or glob patterns. What happens next depends on the configuration resolved for each file, the rules enabled in that configuration, and the flags you pass on the command line. The CLI does not lint “the project” by default. It lints exactly what you point it at, filtered through the ignore rules in your configuration.
This chapter covers the core CLI invocations: running ESLint on a single file, a directory, and multiple targets. It explains how ESLint discovers files when given a directory versus a glob, how the --fix flag changes files in place, how to filter output with --quiet and fail CI with --max-warnings, and how to ignore files from the command line with --ignore-pattern and --no-ignore. By the end, you will be able to run ESLint deliberately—on the files you intend, with the output you need, and with exit codes that mean what you expect.
Key point: npx eslint with no arguments does not lint the whole project. It prints help. You must pass at least one file, directory, or glob pattern.
Why the CLI invocation matters
The target selection problem. ESLint does not automatically find “all JavaScript files in the project” unless you give it a directory or a glob that resolves to them. The default file patterns in flat config are **/*.js, **/*.cjs, and **/*.mjs, but these are only applied when you pass a directory argument . If you pass a specific file, ESLint lints that file regardless of whether it matches the default patterns. If you pass a glob, ESLint expands the glob and lints the matches. The selection logic is deterministic, but it is not implicit.
The fix boundary problem. --fix applies auto-fixable rule violations directly to the files on disk. It does not apply every possible change—only fixes that the enabled rules provide. Rules without fixers remain as reported violations. This means --fix is not a “make it pass” command; it is a “apply what can be applied automatically” command . Understanding the boundary prevents the surprise of running --fix and still seeing errors.
The warning-versus-error problem. ESLint distinguishes between errors (severity 2) and warnings (severity 1). A run with only warnings exits with code 0, which means CI passes despite the warnings. The --max-warnings flag changes this behavior: if the warning count exceeds the threshold, ESLint exits with code 1 . This is how you turn warnings into a CI gate without changing every rule from warn to error.
a. Running on a single file
The simplest invocation targets one file. ESLint resolves the configuration for that file, applies the matching rules, and reports violations.
# Lint a single file
npx eslint src/app.js
If the file has no violations, the command produces no output and exits with code 0. If there are violations, each is printed with the file path, line number, column, rule ID, and message. The exit code is 1 if any error-level violations exist, and 0 if only warnings exist (unless --max-warnings is set).
Single-file linting is useful during development, especially in editor integrations that run ESLint on the current file. It is not how you lint a project in CI, because it only covers one file.
b. Running on a directory
Passing a directory tells ESLint to recurse into that directory and lint the files that match its default patterns. In flat config, the default patterns are **/*.js, **/*.cjs, and **/*.mjs . The recursion respects the ignore patterns defined in eslint.config.js and any command-line ignore flags.
# Lint everything in src/ recursively
npx eslint src/
# Lint the current directory
npx eslint .
The . argument is the most common CI invocation. It lints the current working directory and all subdirectories, subject to the configuration’s ignore rules. This is why the configuration’s ignores array matters: without it, ESLint will attempt to lint dist/, coverage/, and any other generated output that matches the default patterns. The flat config’s ignores property is the mechanism for excluding those directories .
c. Running on multiple targets and globs
ESLint accepts multiple file and directory arguments in a single invocation. Each argument is processed independently, and the results are combined.
# Lint a directory and a file
npx eslint src/ file.js
# Lint multiple directories
npx eslint src/ test/
Glob patterns are also accepted. The pattern must be quoted to prevent the shell from expanding it, for the same reason Prettier globs must be quoted: the shell’s expansion may not match ESLint’s file resolution logic.
# Quoted glob: ESLint expands it
npx eslint "src/**/*.ts"
When a directory is passed, ESLint uses the default file patterns to decide which files inside it to lint. When a glob is passed, ESLint matches the glob against the filesystem directly. The two modes are not identical: a directory argument applies the default patterns; a glob argument applies the glob as written .
d. Fixing violations with –fix
The --fix flag instructs ESLint to apply auto-fixable corrections to the files in place. After the fixes are applied, any remaining violations are reported as usual.
# Lint and fix what can be fixed
npx eslint src/ --fix
Not every rule provides a fixer. The no-unused-vars rule does not fix unused variables automatically, because removing a variable is a semantic change that the rule cannot safely make. The semi rule (if enabled) does provide a fixer, because adding a semicolon is deterministic. The --fix-type flag can narrow which categories of fixes are applied: problem, suggestion, layout, or directive .
# Apply only problem fixes
npx eslint src/ --fix --fix-type problem
This is useful when a project uses Prettier for formatting and wants ESLint’s --fix to only touch logical issues, not layout.
e. Filtering and failing on warnings
The --quiet flag suppresses warnings entirely, reporting only errors. This is useful when you want a clean signal from the CLI without changing the rule configuration.
# Report only errors
npx eslint src/ --quiet
The --max-warnings flag sets a threshold: if the number of warnings exceeds the threshold, ESLint exits with a non-zero code. This is how warnings become a CI gate without being promoted to errors .
# Fail if more than 10 warnings
npx eslint src/ --max-warnings 10
A threshold of -1 (the default) disables the check. Setting it to 0 makes any warning fail the run.
f. Ignoring files from the command line
Command-line ignore patterns supplement the configuration’s ignores array. The --ignore-pattern flag accepts a glob pattern and can be repeated.
# Ignore lib/ and vendor files
npx eslint . --ignore-pattern "lib/" --ignore-pattern "src/vendor/*"
The --no-ignore flag disables all ignore rules, including the configuration’s ignores and any --ignore-pattern flags. This forces ESLint to lint every file it finds, which is occasionally useful for debugging why a file is not being linted.
# Lint everything, including ignored files
npx eslint . --no-ignore
Use --no-ignore with caution: it will attempt to lint node_modules and build output if those are present in the directory tree.
Complete Example Session
# ============================================
# PART 1: LINT A SINGLE FILE
# ============================================
npx eslint src/app.js
# No output: no violations, exit 0.
# Violations: printed with line, column, rule ID, message.
# Exit 1 if errors exist.
# ============================================
# PART 2: LINT A DIRECTORY
# ============================================
npx eslint src/
# Recurses into src/ and lints files matching
# default patterns (**/*.js, **/*.cjs, **/*.mjs).
# Respects ignores in eslint.config.js.
# ============================================
# PART 3: LINT THE CURRENT DIRECTORY
# ============================================
npx eslint .
# The most common CI invocation.
# Requires ignores in config to exclude dist/ and build/.
# ============================================
# PART 4: LINT MULTIPLE TARGETS
# ============================================
npx eslint src/ test/ scripts/build.js
# Each target is processed independently.
# Results are combined in a single report.
# ============================================
# PART 5: LINT A QUOTED GLOB
# ============================================
npx eslint "src/**/*.ts"
# Quotes prevent shell expansion.
# ESLint matches the glob against the filesystem.
# Does not apply the default .js patterns.
# ============================================
# PART 6: FIX AUTO-FIXABLE VIOLATIONS
# ============================================
npx eslint src/ --fix
# Applies fixes to files in place.
# Remaining violations are printed after fixes.
# Not all rules have fixers.
# ============================================
# PART 7: FIX ONLY PROBLEM-TYPE ISSUES
# ============================================
npx eslint src/ --fix --fix-type problem
# Applies fixes for potential errors only.
# Layout and suggestion fixes are skipped.
# Useful when Prettier handles formatting.
# ============================================
# PART 8: SUPPRESS WARNINGS
# ============================================
npx eslint src/ --quiet
# Only errors are reported.
# Warnings are invisible.
# Exit 0 if only warnings existed.
# ============================================
# PART 9: FAIL ON WARNING THRESHOLD
# ============================================
npx eslint src/ --max-warnings 0
# Any warning causes exit code 1.
# Use in CI to enforce zero warnings.
# ============================================
# PART 10: IGNORE PATTERNS FROM CLI
# ============================================
npx eslint . --ignore-pattern "lib/" --ignore-pattern "**/generated/**"
# Supplements ignores from eslint.config.js.
# Both patterns are applied during file discovery.
The ten parts covered single-file linting, directory recursion, current-directory linting, multiple targets, quoted globs, --fix, --fix-type, --quiet, --max-warnings, and CLI ignore patterns.
Quick Reference
Core invocations
| Command | Effect |
|---|---|
npx eslint file.js | Lint a single file |
npx eslint src/ | Recurse into src/, use default patterns |
npx eslint . | Lint current directory recursively |
npx eslint "src/**/*.ts" | Lint quoted glob (ESLint expands) |
npx eslint src/ file.js | Lint multiple targets |
Fixing flags
| Flag | Effect |
|---|---|
--fix | Apply auto-fixable corrections in place |
--fix --fix-type problem | Apply only problem-type fixes |
--fix --fix-type layout | Apply only layout-type fixes |
Output and exit flags
| Flag | Effect |
|---|---|
--quiet | Report only errors, suppress warnings |
--max-warnings N | Exit 1 if warnings exceed N |
--max-warnings 0 | Exit 1 on any warning |
-f json | Output as JSON |
-o results.txt | Write output to file |
Ignore flags
| Flag | Effect |
|---|---|
--ignore-pattern "glob" | Add ignore pattern (repeatable) |
--no-ignore | Disable all ignore rules |
Default file patterns (flat config)
| Pattern | Matches |
|---|---|
**/*.js | JavaScript files |
**/*.cjs | CommonJS files |
**/*.mjs | ES module files |
Best Practices
✅ Do This:
# Pass a directory or glob; no arguments prints help
npx eslint src/ # ✅
# Quote globs so ESLint expands them
npx eslint "src/**/*.ts" # ✅
# Use --fix in development, not in CI
npx eslint src/ --fix # ✅
# Fail CI on warnings with --max-warnings
npx eslint . --max-warnings 0 # ✅
# Use --ignore-pattern for ad-hoc exclusions
npx eslint . --ignore-pattern "**/generated/**" # ✅
❌ Don’t Do This:
# Run npx eslint with no arguments
npx eslint # ❌ (prints help)
# Unquoted glob: shell expands it
npx eslint src/**/*.ts # ❌
# Use --fix in CI without checking git diff
npx eslint . --fix # ❌ (changes discarded)
# Assume --quiet changes exit code
npx eslint . --quiet # ❌ (exit still 1 on errors)
# Use --no-ignore on a directory with node_modules
npx eslint . --no-ignore # ❌ (lints dependencies)
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
npx eslint prints help | No file or directory argument | Pass a path: npx eslint . |
| Directory argument lints too much | No ignores in flat config | Add ignores: ["**/dist/**"] to config |
| Glob matches nothing | Shell expanded it before ESLint saw it | Quote the glob |
--fix does not fix an error | The rule has no fixer | Fix manually; not all rules are auto-fixable |
| CI passes despite warnings | Warnings exit 0 by default | Add --max-warnings 0 |
--ignore-pattern does not exclude nested files | Missing **/ prefix | Use "**/pattern" for recursive matching |
Real-World Examples
1. Lint a single file
npx eslint src/index.js
2. Lint a directory
npx eslint src/
3. Lint the whole project
npx eslint .
4. Lint a glob
npx eslint "src/**/*.ts"
5. Fix violations
npx eslint src/ --fix
6. Fix only problem-type issues
npx eslint src/ --fix --fix-type problem
7. Suppress warnings
npx eslint src/ --quiet
8. Fail on any warning
npx eslint src/ --max-warnings 0
9. Ignore a directory from CLI
npx eslint . --ignore-pattern "lib/"
10. Output to JSON
npx eslint src/ -f json -o results.json
Visual
Target resolution
┌─────────────────────────────────────────────────────────────┐
│ WHAT DOES ESLINT LINT? │
│ │
│ Argument: "src/app.js" │
│ │ │
│ ▼ │
│ Lint exactly this file. │
│ Default patterns do not apply. │
│ │
│ Argument: "src/" │
│ │ │
│ ▼ │
│ Recurse into src/. │
│ Lint files matching **/*.js, **/*.cjs, **/*.mjs. │
│ Respect ignores from config. │
│ │
│ Argument: "src/**/*.ts" │
│ │ │
│ ▼ │
│ Expand glob. │
│ Lint matching .ts files. │
│ Default .js patterns do not apply. │
└─────────────────────────────────────────────────────────────┘
–fix boundary
┌─────────────────────────────────────────────────────────────┐
│ --fix APPLIES ONLY WHAT RULES PROVIDE │
│ │
│ Rule with fixer (e.g., semi): │
│ const x = 1 → const x = 1; │
│ Fixed automatically by --fix. │
│ │
│ Rule without fixer (e.g., no-unused-vars): │
│ const unused = 1; │
│ Reported, not fixed. │
│ Removing a variable is a semantic change. │
│ │
│ --fix is not "make it pass." │
│ It is "apply deterministic corrections." │
└─────────────────────────────────────────────────────────────┘
Warning handling
┌─────────────────────────────────────────────────────────────┐
│ EXIT CODES AND WARNINGS │
│ │
│ Rule severity: warn (1) │
│ Violations reported as warnings. │
│ Default exit code: 0 (pass). │
│ │
│ --max-warnings 0: │
│ Any warning → exit code 1 (fail). │
│ │
│ --quiet: │
│ Warnings suppressed entirely. │
│ Exit code still 1 if errors exist. │
│ │
│ Rule severity: error (2) │
│ Violations reported as errors. │
│ Default exit code: 1 (fail). │
└─────────────────────────────────────────────────────────────┘
Ignore precedence
┌─────────────────────────────────────────────────────────────┐
│ IGNORE LAYERS │
│ │
│ 1. Default ignores (config) │
│ **/node_modules/, .git/ │
│ │
│ 2. Config ignores │
│ ignores: ["**/dist/**"] │
│ │
│ 3. CLI --ignore-pattern │
│ --ignore-pattern "lib/" │
│ │
│ 4. --no-ignore disables all of the above. │
│ │
│ Files are filtered through every active layer. │
└─────────────────────────────────────────────────────────────┘
Summary
| Item | Value |
|---|---|
| No arguments | Prints help, does not lint |
| Single file | npx eslint file.js |
| Directory | npx eslint src/ (recurses, default patterns) |
| Current directory | npx eslint . |
| Glob | Quote it: npx eslint "src/**/*.ts" |
| Fix flag | --fix applies auto-fixable corrections |
| Warning suppression | --quiet (errors only) |
| Warning gate | --max-warnings N (exit 1 if exceeded) |
| Ignore supplement | --ignore-pattern "glob" |
| Ignore disable | --no-ignore |
| Default patterns | **/*.js, **/*.cjs, **/*.mjs |
Key takeaways:
- You must pass a target.
npx eslintwith no arguments prints help. The command lints what you point it at, not the project implicitly. - Directory and glob arguments behave differently. A directory applies the default file patterns and recurses. A glob matches the filesystem directly and does not apply default patterns.
--fixis bounded by rule fixers. It applies deterministic corrections that rules provide. Rules without fixers remain as reported violations.- Warnings exit 0 by default. CI passes unless you add
--max-warnings. The threshold turns warnings into a gate without changing rule severity. --quietsuppresses warnings, not errors. It does not change the exit code for errors.- Ignore layers stack. Default ignores, config
ignores, and--ignore-patternall apply.--no-ignoredisables all of them and should be used with care.
Remember: The CLI is a target selector plus a set of flags that modify reporting and fixing. The target determines what gets linted. The flags determine what happens to the results. The two mistakes that cause the most confusion are passing no target (which prints help) and assuming --fix makes everything pass (it only applies what rules can safely change). Use directory arguments for project-wide linting, quoted globs for specific file sets, --fix during development, and --max-warnings 0 in CI when warnings should block merging.
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!