eslint-biome

v2026.09.24

ESLint 9 flat config and Biome linter configuration. Covers typescript-eslint, rule categories, migration from legacy config, and performance optimization. USE WHEN: user mentions "ESLint 9", "Biome", "flat config", "eslint.config.mjs", asks about "typescript-eslint", "migration to ESLint 9", "linter performance", "Biome vs ESLint" DO NOT USE FOR: legacy ESLint - use `eslint` skill, Java/Spring - use SonarQube, basic linting concepts - use `quality-common`

GitHub
安装命令
npx skhub add claude-dev-suite/eslint-biome
Markdown
SKILL.md

ESLint 9 & Biome Linting

When NOT to Use This Skill

  • Legacy ESLint (.eslintrc) - Use eslint skill for old config format
  • TypeScript-only rules - Use typescript-eslint skill for deep TypeScript linting
  • Java/Kotlin linting - Use sonarqube skill
  • Code quality principles - Use quality-common for SOLID/Clean Code

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: eslint or biome for comprehensive documentation.

Official References

ToolDocumentation
ESLint 9https://eslint.org/docs/latest/
typescript-eslinthttps://typescript-eslint.io/
Biomehttps://biomejs.dev/
ESLint Ruleshttps://eslint.org/docs/latest/rules/
Biome Ruleshttps://biomejs.dev/linter/rules/

ESLint 9 Flat Config

Basic Setup

npm install --save-dev eslint @eslint/js typescript typescript-eslint
// eslint.config.mjs
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';

export default tseslint.config(
  eslint.configs.recommended,
  ...tseslint.configs.recommended,
);

TypeScript with Type Checking

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

export default tseslint.config(
  eslint.configs.recommended,
  ...tseslint.configs.recommendedTypeChecked,
  {
    languageOptions: {
      parserOptions: {
        projectService: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
  },
);

Full Configuration Example

// eslint.config.mjs
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import reactPlugin from 'eslint-plugin-react';
import reactHooksPlugin from 'eslint-plugin-react-hooks';

export default tseslint.config(
  // Ignores
  {
    ignores: ['dist/**', 'node_modules/**', '*.config.js'],
  },

  // Base configs
  eslint.configs.recommended,
  ...tseslint.configs.strictTypeChecked,
  ...tseslint.configs.stylisticTypeChecked,

  // TypeScript files
  {
    files: ['**/*.ts', '**/*.tsx'],
    languageOptions: {
      parserOptions: {
        projectService: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
    rules: {
      // Prevent bugs
      '@typescript-eslint/no-floating-promises': 'error',
      '@typescript-eslint/no-misused-promises': 'error',
      '@typescript-eslint/await-thenable': 'error',

      // Code quality
      '@typescript-eslint/no-explicit-any': 'error',
      '@typescript-eslint/explicit-function-return-type': 'warn',
      '@typescript-eslint/consistent-type-imports': 'error',

      // Complexity
      'complexity': ['warn', 10],
      'max-depth': ['warn', 4],
      'max-lines-per-function': ['warn', 50],
    },
  },

  // React files
  {
    files: ['**/*.tsx'],
    plugins: {
      react: reactPlugin,
      'react-hooks': reactHooksPlugin,
    },
    rules: {
      ...reactPlugin.configs.recommended.rules,
      ...reactHooksPlugin.configs.recommended.rules,
      'react/react-in-jsx-scope': 'off',
    },
    settings: {
      react: { version: 'detect' },
    },
  },

  // Test files
  {
    files: ['**/*.test.ts', '**/*.test.tsx', '**/*.spec.ts'],
    rules: {
      '@typescript-eslint/no-explicit-any': 'off',
      'max-lines-per-function': 'off',
    },
  },
);

typescript-eslint Presets

PresetDescription
recommendedCore rules without type checking
recommendedTypeCheckedRecommended + type-aware rules
strictAll recommended + stricter rules
strictTypeCheckedStrict + type-aware rules
stylisticStyle/convention rules
stylisticTypeCheckedStylistic + type-aware

Key Type-Checked Rules

rules: {
  // Async/Promise safety
  '@typescript-eslint/no-floating-promises': 'error',
  '@typescript-eslint/no-misused-promises': 'error',
  '@typescript-eslint/await-thenable': 'error',
  '@typescript-eslint/require-await': 'error',

  // Type safety
  '@typescript-eslint/no-unsafe-argument': 'error',
  '@typescript-eslint/no-unsafe-assignment': 'error',
  '@typescript-eslint/no-unsafe-call': 'error',
  '@typescript-eslint/no-unsafe-member-access': 'error',
  '@typescript-eslint/no-unsafe-return': 'error',

  // Best practices
  '@typescript-eslint/no-unnecessary-condition': 'error',
  '@typescript-eslint/prefer-nullish-coalescing': 'error',
  '@typescript-eslint/prefer-optional-chain': 'error',
}

Biome

Installation

npm install --save-dev @biomejs/biome
npx @biomejs/biome init

Configuration (biome.json)

{
  "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
  "organizeImports": {
    "enabled": true
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "complexity": {
        "noExcessiveCognitiveComplexity": {
          "level": "warn",
          "options": { "maxAllowedComplexity": 15 }
        }
      },
      "correctness": {
        "noUnusedImports": "error",
        "noUnusedVariables": "error",
        "useExhaustiveDependencies": "warn"
      },
      "suspicious": {
        "noExplicitAny": "error",
        "noConsoleLog": "warn"
      },
      "style": {
        "useConst": "error",
        "noNonNullAssertion": "warn"
      },
      "security": {
        "noDangerouslySetInnerHtml": "error"
      }
    }
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "single",
      "semicolons": "always"
    }
  }
}

Rule Categories

CategoryRulesDescription
a11y40+Accessibility problems
complexity15+Code simplification
correctness60+Guaranteed errors
performance10+Efficiency improvements
security5+Security flaws
style50+Consistent code style
suspicious50+Likely incorrect patterns
nursery100+Experimental rules

Commands

# Check all
npx biome check .

# Fix auto-fixable issues
npx biome check --write .

# Lint only
npx biome lint .

# Format only
npx biome format --write .

# CI mode (no writes)
npx biome ci .

Migration: ESLint to Biome

# Automatic migration
npx @biomejs/biome migrate eslint --write

# With inspired rules
npx @biomejs/biome migrate eslint --include-inspired --write

# Migrate prettier config too
npx @biomejs/biome migrate prettier --write

Supported ESLint Plugins

PluginBiome Support
@typescript-eslintFull
eslint-plugin-reactFull
eslint-plugin-react-hooksFull
eslint-plugin-jsx-a11yFull
eslint-plugin-unicornPartial
eslint-plugin-importPartial

Rule Name Mapping

ESLintBiome
no-unused-varsnoUnusedVariables
no-consolenoConsoleLog
prefer-constuseConst
@typescript-eslint/no-explicit-anynoExplicitAny

ESLint vs Biome

FeatureESLint 9Biome
Speed~3-5s/10k lines~200ms/10k lines
ConfigJavaScriptJSON/JSONC
Plugins1000+Built-in only
FormatterNeeds PrettierBuilt-in
Type-awareFull support~85% coverage
LanguagesJS/TS + pluginsJS/TS/JSON/CSS

When to Use ESLint

  • Need specific plugins (import sorting, testing rules)
  • Require full type-aware linting
  • Have complex dynamic configuration

When to Use Biome

  • Speed is critical (large codebase, CI)
  • Want unified linting + formatting
  • Don't need extensive plugin ecosystem

CI Integration

ESLint (GitHub Actions)

- name: Lint
  run: npx eslint . --max-warnings=0

# With caching
- name: Lint with cache
  run: npx eslint . --cache --cache-location node_modules/.cache/eslint

Biome (GitHub Actions)

- name: Setup Biome
  uses: biomejs/setup-biome@v2
  with:
    version: latest

- name: Run Biome
  run: biome ci .

Checklist

ESLint Setup

  • Using flat config (eslint.config.mjs)
  • Type-checked rules enabled
  • No deprecated eslintrc format
  • Strict TypeScript rules
  • CI caching configured

Biome Setup

  • biome.json configured
  • Recommended rules enabled
  • Formatter settings match team style
  • CI mode in pipeline

Metrics

MetricTarget
Lint warnings0
Lint errors0
Type coverage> 95%
Lint time (CI)< 30s

Anti-Patterns

Anti-PatternWhy It's BadCorrect Approach
Using ESLint without type checkingMisses 50% of TS issuesUse recommendedTypeChecked
Biome + ESLint both linting same filesDuplicate work, conflictsChoose one per file type
No ignores in flat configLints dist/, node_modules/Add ignores at top of config
Type checking all JS filesSlow, JS has no typesLimit to **/*.ts files only
Not using Biome CI modeDifferent results locally vs CIUse biome ci . in pipelines
Mixing .eslintrc and flat configConfusing, deprecated patternMigrate fully to flat config

Quick Troubleshooting

IssueLikely CauseSolution
ESLint not finding typesprojectService not enabledAdd projectService: true to parserOptions
Biome migration creates 1000+ errorsStricter rules than ESLintUse --write to auto-fix, adjust rules
Linting takes 2+ minutesType checking entire codebaseUse files: ['**/*.ts'] for type rules
Biome doesn't support plugin XLimited plugin ecosystemStick with ESLint or find alternative
Flat config not recognizedWrong file nameMust be eslint.config.mjs (not .js)
Rules overriding each otherOrder in config arrayLater configs override earlier ones

Related Skills

发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

Sep 24, 2026

分类

未分类

许可证

MIT

源路径

skills/quality/eslint-biome

默认分支

main

最新提交

9496306

Tree SHA

fe4e2f1