← Catalog

No. 003 · code-quality

ESLint Configuration

Linting rules that catch bugs without fighting your style

Version 1.0.0 License MIT Format SKILL.md

Most ESLint pain comes from fighting the default config instead of tuning it. This skill helps you set up a config that catches real bugs while staying out of the way on style choices that don’t matter.

Flat config (eslint.config.mjs)

New projects should use the flat config format. The old .eslintrc is legacy as of ESLint v9.

// eslint.config.mjs
import js from '@eslint/js';
import tseslint from 'typescript-eslint';

export default tseslint.config(
  js.configs.recommended,
  ...tseslint.configs.recommended,
  {
    rules: {
      'no-unused-vars': 'off',
      '@typescript-eslint/no-unused-vars': ['error', {
        argsIgnorePattern: '^_',
        varsIgnorePattern: '^_',
      }],
      '@typescript-eslint/no-explicit-any': 'warn',
      'no-console': ['warn', { allow: ['warn', 'error'] }],
    },
  },
  {
    ignores: ['dist/', 'node_modules/', '*.config.*'],
  },
);

Rule tuning principles

Promote to error only rules that catch real bugs:

  • no-floating-promises — unhandled promises cause silent failures
  • no-misused-promises — async functions in wrong contexts
  • eqeqeq== coerces in surprising ways

Use warn for code smell that might be intentional:

  • no-console — sometimes you genuinely want console output
  • @typescript-eslint/no-explicit-any — sometimes any is the right call

Turn off rules that conflict with your formatter:

  • All formatting rules (indentation, semicolons, trailing commas) — let Prettier handle these
  • no-multiple空格 — Prettier manages whitespace

Prettier integration

Install eslint-config-prettier to disable all ESLint rules that conflict with Prettier:

npm install -D eslint-config-prettier

Then add it as the last config in your flat config array:

import prettier from 'eslint-config-prettier';

export default tseslint.config(
  // ... other configs
  prettier, // must be last
);

Never use eslint-plugin-prettier (running Prettier through ESLint) — it’s slow and produces noisy diffs. Run Prettier separately.

Adding custom rules

For project-specific patterns, create a local rule only if no existing rule covers the case. Most needs are met by combining existing rules:

rules: {
  // Enforce error handling on specific functions
  '@typescript-eslint/no-misused-promises': ['error', {
    checksVoidReturn: { attributes: false },
  }],
}

See references/flat-config-migration.md for migrating from .eslintrc.

When it triggers

  • setting up a new project's linter
  • ESLint rule is too strict or too lenient
  • conflict between ESLint and Prettier
  • migrating from .eslintrc to flat config