Skip to content

Troubleshooting

Common problems and how to resolve them.

Before diving into specific issues, run the built-in diagnostics:

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

doctor checks for missing config files, configs that cannot be loaded, lingering v1 imports, missing lint scripts, workspace packages not covered by projects, and parallel ESLint version copies. It also checks whether Astro Doctor is paired with Astro and whether its installed package supports the current Node.js and ESLint versions.

For automation, use structured output:

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

explain prints every detected input so you can confirm what the composer will receive before anything is written.


Why does one package install so many plugins?

Section titled “Why does one package install so many plugins?”

v2 bundles every framework config and integration plugin as regular dependencies of @santi020k/eslint-config-basic. This is a deliberate DX-first tradeoff:

  • Vetted together: every plugin version is tested against the others in CI, so you never resolve peer-dependency conflicts yourself.
  • Installs never break: there are no optional peers to forget or mismatch — pnpm add -D @santi020k/eslint-config-basic is the whole setup.
  • Lazy at runtime: framework packages and integration plugins are imported only when enabled, so unused frameworks cost disk space but zero lint startup time.

If install size is critical (e.g. tight CI caches), the individual @santi020k/eslint-config-* packages remain published and can be composed manually.

For projects that still want the main composer API with a smaller default install, use @santi020k/eslint-config-lite. It installs the core composer and TypeScript support, but requires you to install framework config packages and @santi020k/eslint-config-integrations yourself when you enable those features.

Run basic-eslint doctor --lite-install to generate the install command for the current project before switching.


A framework I did not enable is being linted

Section titled “A framework I did not enable is being linted”

Auto-detection reads package.json and enables bundled framework configs for packages it finds. To disable this:

import { defineConfig } from '@santi020k/eslint-config-basic'
export default await defineConfig({
autoFrameworks: false,
frameworks: {
react: true
}
})

Or disable only framework detection while keeping other categories automatic:

export default await defineConfig({
detection: { frameworks: false },
frameworks: { react: true }
})

Detected frameworks override my explicit config

Section titled “Detected frameworks override my explicit config”

By default, detected and explicit values are merged (optionMergeStrategy: 'merge'). Use 'replace' to make your explicit object the sole source:

export default await defineConfig({
frameworks: { react: true },
optionMergeStrategy: 'replace'
})

The TypeScript projectService rejects files not covered by any tsconfig.json. Solutions:

  1. Make sure your tsconfig.json includes the file (check include/exclude patterns).
  2. Set tsconfigRootDir explicitly:
export default await defineConfig({
tsconfigRootDir: import.meta.dirname,
typescript: true
})
  1. In integration tests with virtual file paths, pass typescript: false to skip type-aware rules.

ESLint times out with Atomics.wait() failed: timed-out

Section titled “ESLint times out with Atomics.wait() failed: timed-out”

Tailwind CSS v4 uses a heavy initialization process in worker threads. Provide an explicit entryPoint:

import { defineConfig, Library } from '@santi020k/eslint-config-basic'
export default [
...await defineConfig({ libraries: [Library.Tailwind] }),
{
name: 'project/tailwind-settings',
settings: {
'better-tailwindcss': {
entryPoint: './src/index.css'
}
}
}
]

If timeouts persist, increase the worker timeout:

Terminal window
SYNCKIT_TIMEOUT=60000 eslint .

Set detectRootDir explicitly:

export default await defineConfig({
detectRootDir: process.cwd()
})

doctor warns when two different ESLint copies are installed. The current release line supports ESLint 10, so align your app and workspace packages on the same ESLint 10 version. With pnpm, use overrides:

{
"pnpm": {
"overrides": {
"eslint": "$eslint"
}
}
}

Then run pnpm install to deduplicate.


VS Code does not pick up flat config rules

Section titled “VS Code does not pick up flat config rules”

Make sure you are on ESLint extension v3.0+ and add to .vscode/settings.json:

{
"eslint.useFlatConfig": true
}

eslintConfig is not a function or import error

Section titled “eslintConfig is not a function or import error”

In v2, the primary export is defineConfig. Both names are exported for compatibility:

// v1 style (still works in v2)
// v2 preferred

Use the inspector to find which config block sets the rule last:

Terminal window
pnpm run inspector

Did this page help?

One click helps us spot documentation that needs another pass. No personal data is sent.