Skip to content

CLI

The main package ships a CLI that can scaffold or refresh the project config.

bash
pnpm dlx @santi020k/eslint-config-basic init
pnpm dlx @santi020k/eslint-config-basic update
pnpm dlx @santi020k/eslint-config-basic explain
pnpm dlx @santi020k/eslint-config-basic explain-preset app
pnpm dlx @santi020k/eslint-config-basic inspect
pnpm dlx @santi020k/eslint-config-basic install
pnpm dlx @santi020k/eslint-config-basic doctor
pnpm dlx @santi020k/eslint-config-basic compatibility
pnpm dlx @santi020k/eslint-config-basic config-types
pnpm dlx @santi020k/eslint-config-basic migrate --to v3
pnpm dlx @santi020k/eslint-config-basic baseline
pnpm dlx @santi020k/eslint-config-basic profile
pnpm dlx @santi020k/eslint-config-basic snapshot
pnpm dlx @santi020k/eslint-config-basic diff
pnpm dlx @santi020k/eslint-config-basic docs
pnpm dlx @santi020k/eslint-config-basic generate-skill
  • Detects TypeScript, runtime, and supported optional integrations from package.json.
  • Chooses eslint.config.js for ESM projects.
  • Chooses eslint.config.mjs otherwise.
  • Writes the zero-argument defineConfig() setup.
  • Leaves framework selection to runtime detection, so the file stays stable as dependencies change.
  • Prints detected config inputs with explain.
  • Compares preset adoption by rule category with explain-preset.
  • Prints detected inputs, package-manager details, workspace projects, and active config features with inspect.
  • Installs missing framework and feature-category packages with install.
  • Checks common v3 adoption issues with doctor.
  • Checks Node, ESLint, TypeScript, and config-package peer compatibility.
  • Generates human-readable ESLINT_STANDARDS.md docs with docs.
  • Plans and safely applies v1-to-v2 or v2-to-v3 migrations with migrate.
  • Creates an incremental-adoption suppression baseline with baseline.
  • Compares single-threaded and multithreaded rule performance with profile.
  • Saves and diffs effective-rule snapshots for representative files.
bash
pnpm dlx @santi020k/eslint-config-basic init

The default output remains the smallest zero-config setup. Use --explicit when the detected TypeScript, framework, and feature selections should be committed directly for reproducible configuration:

Terminal window
npx @santi020k/eslint-config-basic init --explicit

If the package is already installed locally, the basic-eslint bin is also available through your package manager’s local binary resolution.

Terminal window
basic-eslint --help
basic-eslint --version
bash
pnpm dlx @santi020k/eslint-config-basic update

Use update to replace an older generated config with the stable zero-argument v3 setup. Adding or removing dependencies no longer requires regenerating it.

Use explain before committing a zero-config setup or after dependency changes.

Terminal window
npx @santi020k/eslint-config-basic explain

It prints the detected TypeScript state, preset, runtime, framework list, optional integrations, tools, and formats.

Pass a rule name and representative file to inspect the final value and every loaded flat-config entry that defines it:

Terminal window
npx @santi020k/eslint-config-basic explain @typescript-eslint/no-floating-promises --file src/index.ts

The report includes the effective severity and options, defining config names, and the likely config package responsible for the rule.

Before changing an existing project to a broader preset, compare its current effective rules for a representative file:

Terminal window
npx @santi020k/eslint-config-basic explain-preset app --file src/index.ts

The report groups newly enabled rules into formatting, correctness, security, framework, and domain sections. Add --analyze-source to count current findings and preview autofix without writing files:

Terminal window
npx @santi020k/eslint-config-basic explain-preset app --analyze-source

Use --semantic-only to preview fixes from correctness, security, framework, and domain rules while leaving formatting fixes out of the preview. Add --write only after reviewing that report:

Terminal window
npx @santi020k/eslint-config-basic explain-preset app \
--analyze-source \
--semantic-only \
--write

The command refuses --write without --semantic-only. Source analysis also lists file-reading scripts that apply regular expressions as possible formatting-sensitive parsers. Review those scripts and run their validators after any later formatting pass.

For TypeScript projects, source analysis first runs the consumer’s own compiler with --noEmit. Module-resolution and other root compiler diagnostics are shown before cascading type-aware unsafe-rule findings, so dependency or import problems can be fixed before lint debt is classified. The structured result is also available through --json.

To keep a migration incremental, generate a temporary override that disables only the newly enabled rules:

Terminal window
npx @santi020k/eslint-config-basic explain-preset app --file src/index.ts --compatibility

Import the generated .eslint-preset-app-compat.mjs after the preset config, then remove its entries as findings are adopted. Use --output <path> to choose another filename.

Use inspect when you want a fuller view than explain, including package-manager detection, workspace package discovery, and features read from the active ESLint config when it can be loaded.

Terminal window
npx @santi020k/eslint-config-basic inspect

For automation, use JSON output:

Terminal window
npx @santi020k/eslint-config-basic inspect --json

explain, doctor, compatibility, config-types, migrate, profile, snapshot, and diff support --json for CI and migration tooling:

Terminal window
npx @santi020k/eslint-config-basic explain --json
npx @santi020k/eslint-config-basic doctor --json
npx @santi020k/eslint-config-basic migrate --json

Use install after adding the lean Basic package. It detects frameworks, TypeScript, and optional feature categories, then adds any missing config packages with the project’s package manager.

Terminal window
npx @santi020k/eslint-config-basic install

Preview the package-manager command without changing package.json:

Terminal window
npx @santi020k/eslint-config-basic install --dry-run

Companion config packages use the installed Basic major/minor range. If pnpm’s minimumReleaseAge blocks that exact compatible release, the CLI reports the policy explicitly instead of suggesting an older incompatible major.

Use doctor while adopting v3 or after moving a project into a workspace. It reports missing config files, configs that cannot be loaded, missing optional framework or integration packages, missing lint scripts, and detected workspace packages that are not represented with projects scoping.

It also detects when two different ESLint copies are installed — for example a project pinning an older ESLint while the config packages resolve their own ESLint dependency. The current release line supports ESLint 10, and parallel copies can make your editor and CLI apply slightly different rule behavior, so doctor warns and suggests aligning or deduping.

For Astro projects, doctor also reports mismatched Astro Doctor configuration, suggests the optional integration when Astro is detected, and checks the installed Astro Doctor package against the current Node.js and ESLint versions.

Terminal window
npx @santi020k/eslint-config-basic doctor

Add --verbose in a workspace to print a compact row for the root and every detected project. Each row includes the selected runtime, TypeScript mode and tsconfig, framework processors, formats, libraries, extensions, testing packs, tools, and ignore patterns. Feature markers distinguish installed (I), detected (D), and enabled (E) state:

Terminal window
npx @santi020k/eslint-config-basic doctor --verbose

When a supporting optional package is installed but not activated, the verbose report explains whether the project lacked a matching detection signal or the active config did not load the detected pack. doctor --json always includes the same structured data in its projects array, including inactive-package reasons, without requiring --verbose.

Use --fix to create a missing generated config, add a lint script, declare detected v3 packages, and rewrite straightforward v1 framework imports. package.json and rewritten configs receive numbered .doctor.bak backups. The command changes metadata only; run the package-manager install afterward.

Terminal window
npx @santi020k/eslint-config-basic doctor --fix

doctor --lite-install is deprecated and remains available only for existing v2 lite migrations. It is scheduled for removal in v4. New v3 projects should install basic plus their detected framework and category packages.

Terminal window
npx @santi020k/eslint-config-basic doctor --lite-install

Use init --check when CI should verify that a project already has an ESLint flat config without writing a file:

Terminal window
npx @santi020k/eslint-config-basic init --check

compatibility resolves every declared @santi020k/eslint-config-* package through Node package resolution, including dependencies declared with default or named pnpm catalog: specifiers. It reports each declaration, resolved manifest path, and version; checks the current Node runtime plus the consumer’s declared engines.node range; and verifies ESLint and TypeScript peer ranges:

Terminal window
npx @santi020k/eslint-config-basic compatibility
npx @santi020k/eslint-config-basic compatibility --json

When Full is declared, the report shows both the installed Full version and the resolved Basic package that supplies composer behavior. Release CI also requires a Full changeset whenever one of its aggregated config packages is released, so batteries-included consumers receive meaningful aggregate updates without forcing every package to share the same minor version.

It exits with code 1 for missing or incompatible declared packages, or when the consumer Node range permits versions unsupported by an installed config package. This makes it suitable for dependency-update pull requests.

doctor reports the same consumer Node-range mismatch. Use doctor --fix to update engines.node; the fixer computes the intersection of the existing consumer range and all resolved config-package requirements, so supported union branches are retained and the manifest is never broadened accidentally. As with other doctor writes, the original manifest is saved as package.json.doctor.bak.

Use docs to create a project-local ESLINT_STANDARDS.md summary for humans.

Terminal window
npx @santi020k/eslint-config-basic docs

This is separate from generate-skill: docs writes a general standards document, while generate-skill targets AI coding assistant rule folders.

Without a target, migrate retains its v1-to-v2 compatibility behavior:

Terminal window
npx @santi020k/eslint-config-basic migrate

For v2 projects, preview the complete v3 dependency and config migration:

Terminal window
npx @santi020k/eslint-config-basic migrate --to v3

The command selects lean mode by default, detects required framework and feature-pack packages, moves direct factory imports to their granular packages, replaces removed aliases, migrates literal category arrays and the deprecated integrations map to features, consolidates a single root-directory alias into root, and migrates Remix to React Router. Dynamic expressions and conflicting root aliases are left unchanged with a manual-action note. Config and package.json changes are dry-run only until --write is passed:

Terminal window
npx @santi020k/eslint-config-basic migrate --to v3 --write

Both modified files receive .v2.bak backups. Use --full to select the batteries-included bundle, --check in CI to fail when a migration remains, and --json for machine-readable plans.

For straightforward v1 configs, the historical migration remains available:

Terminal window
npx @santi020k/eslint-config-basic migrate --write

baseline uses ESLint bulk suppressions to record existing errors while still rejecting new violations:

Terminal window
npx @santi020k/eslint-config-basic baseline

Enable a strict profile at the same time when the config is still the generated zero-argument form:

Terminal window
npx @santi020k/eslint-config-basic baseline --preset pedantic

The config is backed up before it is changed. As violations are fixed, remove obsolete entries with:

Terminal window
npx @santi020k/eslint-config-basic baseline --prune

Commit eslint-suppressions.json so local and CI behavior stays aligned.

profile runs ESLint with rule timing enabled and compares concurrency off with auto:

Terminal window
npx @santi020k/eslint-config-basic profile

The report includes total duration, file and diagnostic counts, parsing and rule time, the slowest rules, and the faster concurrency mode. Pin a mode or limit the lint targets when investigating:

Terminal window
npx @santi020k/eslint-config-basic profile --concurrency 4 --file src
npx @santi020k/eslint-config-basic profile --json

Enforce warning and performance budgets in CI:

Terminal window
npx @santi020k/eslint-config-basic profile \
--max-warnings 0 \
--max-duration 15000 \
--max-rule-time 2000

The fastest successful concurrency run is evaluated and the command exits with code 1 when any configured budget is exceeded.

Save the effective rule configuration for representative source, test, framework, and config files:

Terminal window
npx @santi020k/eslint-config-basic snapshot

Commit .eslint-config-snapshot.json, then review dependency-update behavior:

Terminal window
npx @santi020k/eslint-config-basic diff

diff exits with code 1 when rules are added, removed, or changed. Use repeatable --file options to select explicit representatives, --snapshot-path to choose another file, or snapshot --check for the same comparison in CI.

For a smaller review artifact that tracks only effective rule changes, omit globals, parser language options, and plugin registration metadata:

Terminal window
npx @santi020k/eslint-config-basic snapshot --rules-only \
--file src/index.ts \
--file src/index.test.ts

The snapshot records its scope, so later snapshot --check and diff commands automatically use the same rules-only comparison.

TypeScript-powered editors infer a declaration for eslint.config.* even when the normal application typecheck excludes that file. Verify that the inferred type is emit-safe and does not expose pnpm internals or the transitive typescript-eslint implementation package:

Terminal window
npx @santi020k/eslint-config-basic config-types

The command uses the consumer’s installed TypeScript and the closest tsconfig for module settings, adding the local Node ambient boundary only when a config uses Node globals, and emits only the selected ESLint config in memory. Application-only ambient types do not leak into this isolated config check. JavaScript configs are checked for declaration portability without turning unrelated checkJs findings into migration blockers; TypeScript configs retain their normal static checks. No declaration files are written. Use repeatable --file options for project-scoped configs and --json for CI reporting.

The repository root publishes a composite action that installs the consumer, checks compatibility, uploads a structured Doctor report, verifies a committed effective-config snapshot, runs the normal lint command, and optionally checks config declarations and profiler budgets:

- uses: santi020k/eslint-config-basic@v3
with:
install-command: pnpm install --frozen-lockfile
lint-command: pnpm lint
config-types: "true"
profile: "true"
max-warnings: "0"
max-duration: "15000"
max-rule-time: "2000"

Set snapshot-check: "false" when the project intentionally does not commit .eslint-config-snapshot.json. Set doctor-report: "false" when the workflow must not upload the default eslint-config-doctor artifact, or use doctor-artifact-name to avoid collisions in a matrix.

Set config-types: "true" after adopting a release with the portable config boundary. Monorepos can provide whitespace-separated config paths through config-types-files; otherwise the root eslint.config.* file is checked.

The generate-skill command creates or updates ESLint standards files for AI coding assistants based on your project’s active configuration.

This is a beta feature and is non-breaking (it only adds/updates files in existing agent folders and instruction files).

Supported targets:

ToolLocationFormat
Generic agents.agent/skills/, .agents/skills/Markdown + front-matter
Claude Code.claude/commands/Markdown
Cursor.cursor/rules/MDC front-matter
Windsurf.windsurf/rules/Markdown + front-matter
GitHub Copilot.copilot/instructions/, .github/copilot-instructions.mdMarkdown / guarded section
Aider.aider/Markdown
Gemini.gemini/styleguide.mdMarkdown
Cline.clinerules/Markdown
Roo Code.roo/rules/Markdown
Kiro.kiro/steering/Markdown + inclusion: always front-matter
AGENTS.md standard (Codex CLI, OpenCode, Jules, Amp, etc.)root AGENTS.mdGuarded section appended/updated

Folder targets are only written when the folder already exists, and AGENTS.md / .github/copilot-instructions.md are only updated when those files already exist — the command never creates tool folders for tools you do not use.

bash
pnpm dlx @santi020k/eslint-config-basic generate-skill

Use --force if you want to overwrite existing standards files.

  • --force — overwrite existing skill files and guarded sections.
  • --check — CI mode: compares existing skill files against freshly generated content without writing anything, and exits with code 1 when any file is stale or missing. Useful as a CI step or pre-push hook so agent rules never drift from the actual config.
  • --create — scaffold a root AGENTS.md (with the guarded ESLint-standards section) when the project has none. Without this flag, AGENTS.md is only updated when it already exists.
  • --with-eslint-mcp — add the official eslint --mcp server to the root .mcp.json while preserving other registered servers.
CI example
npx @santi020k/eslint-config-basic generate-skill --check
Agent standards and ESLint MCP
npx @santi020k/eslint-config-basic generate-skill --with-eslint-mcp
  • Use init when the project does not have an ESLint flat config yet.
  • Use update when the dependency graph changed and you want a fresh generated baseline.
  • Use explain when you want to review what auto-detection found.
  • Use explain <rule> --file <path> to trace an effective rule value.
  • Use inspect when you need machine-readable details or active config feature extraction.
  • Use doctor when a v3 setup is not behaving as expected.
  • Use compatibility during dependency and runtime upgrades.
  • Use config-types to protect editor-facing config type inference in CI.
  • Use docs when you want a committed standards summary.
  • Use migrate --to v3 when upgrading a v2 consumer.
  • Use baseline when enabling strict rules in an established codebase.
  • Use profile when lint execution becomes expensive.
  • Use snapshot and diff to review rule changes during dependency upgrades.
  • Use manual editing when the config already has custom organization that you do not want regenerated.

The CLI writes:

import { defineConfig } from '@santi020k/eslint-config-basic'
export default defineConfig()

Detection happens when ESLint loads the config, so dependency changes do not make the generated file stale. Add arguments only when the project needs explicit options or local overrides.

  • The CLI detects frameworks and doctor explains missing optional packages.
  • Generated files use the documented zero-argument defineConfig() setup.
  • Existing eslint.config.js or eslint.config.mjs files are respected for updates.
  • The generated file is a starting point that you can still edit by hand.

Did this page help?

Your answer stays in this browser. Share details on GitHub to help improve the docs.