Code-Qualität ist kein Zufall — sie ist das Ergebnis konsequenter Tooling-Entscheidungen. Mit ESLint 9.x und der neuen Flat Config hat sich das TypeScript-Ökosystem 2026 fundamental verändert. Claude Code versteht diese Änderungen und kann komplette, produktionsreife Linting-Konfigurationen generieren, warten und in bestehende Projekte integrieren — ohne stundenlange Dokumentationsrecherche.

Dieser Leitfaden zeigt dir die sechs wichtigsten Konfigurationsbereiche, die Claude Code für TypeScript-Teams automatisiert: von der neuen Flat Config über TypeScript strict mode bis hin zu Monorepo-Setups mit GitHub Actions CI.

1. ESLint Flat Config — die neue Ära

ESLint 9.x hat mit der Flat Config das Konfigurationsmodell grundlegend überarbeitet. Die alten .eslintrc.json- und .eslintrc.js-Dateien sind deprecated. Claude Code kennt beide Systeme und migriert bestehende Projekte sicher auf das neue Format.

📄

Eine Datei: eslint.config.ts

Kein Cascading mehr über Verzeichnisse — eine Konfigurationsdatei für das gesamte Projekt.

🔌

Native ESM-Imports

Plugins werden direkt importiert, kein String-basiertes Plugin-Laden mehr über die plugins-Eigenschaft.

🎯

Explizites Targeting

files-Glob-Pattern direkt im Config-Objekt — keine versteckten .eslintignore-Dateien mehr.

Bessere Performance

Flacheres Parsing, weniger Filesystem-Lookups, schnellere Lint-Läufe auch in großen Monorepos.

Flat Config vs. alte .eslintrc — Vergleich

Feature .eslintrc (alt) eslint.config.ts (neu)
Format JSON / YAML / JS ESM TypeScript
Plugin-Import String-Referenz Direkter ES-Import
Verzeichnis-Cascading Automatisch Explizit via files
TypeScript-Typisierung Nur mit @types/eslint Nativ via defineConfig
Ignore-Dateien .eslintignore ignores-Array im Config
Extends String-Array Spread-Operator auf Config-Arrays

Basis-Konfiguration mit defineConfig

eslint.config.ts
import { defineConfig } from 'eslint/config'; import tsPlugin from '@typescript-eslint/eslint-plugin'; import tsParser from '@typescript-eslint/parser'; import js from '@eslint/js'; import globals from 'globals'; export default defineConfig([ // Globale Ignores (ersetzt .eslintignore) { ignores: [ 'dist/**', 'node_modules/**', 'coverage/**', '**/*.d.ts', '.next/**', ], }, // JavaScript-Basis-Regeln js.configs.recommended, // TypeScript-Dateien { files: ['**/*.{ts,tsx}'], languageOptions: { parser: tsParser, parserOptions: { project: './tsconfig.json', tsconfigRootDir: import.meta.dirname, }, globals: { ...globals.browser, ...globals.node, ...globals.es2022, }, }, plugins: { '@typescript-eslint': tsPlugin, }, rules: { ...tsPlugin.configs['recommended-type-checked'].rules, }, }, // Test-Dateien: relaxiertere Regeln { files: ['**/*.{spec,test}.{ts,tsx}', 'tests/**'], rules: { '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-unsafe-assignment': 'off', }, }, ]);

Migration von .eslintrc zu Flat Config

Claude Code kann bestehende .eslintrc-Dateien automatisch in Flat Config konvertieren. Der Befehl dafür:

# ESLint offizielles Migrations-Tool npx @eslint/migrate-config .eslintrc.json # Oder Claude Code direkt fragen: # "Migriere meine .eslintrc.json zu eslint.config.ts mit Flat Config"

Claude Code Vorteil: Claude kennt alle Breaking Changes zwischen ESLint 8.x und 9.x. Es erkennt deprecated Rules, schlägt Alternativen vor und warnt vor Plugin-Inkompatibilitäten — ohne dass du die ESLint-Migration-Docs durchlesen musst.

2. TypeScript-Integration tief konfigurieren

Der @typescript-eslint-Stack ist das Herzstück jeder TypeScript-Linting-Konfiguration. Die type-aware Rules nutzen den TypeScript-Compiler direkt und fangen Fehler, die normale ESLint-Regeln übersehen. Claude Code konfiguriert diesen Stack vollständig — inklusive der oft vergessenen tsconfig.json-Verknüpfung.

Benötigte Pakete @typescript-eslint

Alle drei Pakete werden für den vollständigen TypeScript-Stack benötigt: parser, plugin und typed-linting.

Terminal — Installation
# TypeScript-ESLint Stack installieren npm install --save-dev \ @typescript-eslint/parser \ @typescript-eslint/eslint-plugin \ typescript-eslint \ eslint \ typescript # Alternativ: pnpm pnpm add -D @typescript-eslint/parser @typescript-eslint/eslint-plugin typescript-eslint

Type-aware Rules konfigurieren

Type-aware Rules sind mächtiger — und langsamer. Claude Code hilft dir, die richtige Balance zwischen Vollständigkeit und Performance zu finden:

eslint.config.ts — Type-aware Konfiguration
import tseslint from 'typescript-eslint'; export default tseslint.config( // Empfohlene type-aware Regeln ...tseslint.configs.recommendedTypeChecked, // Für maximale Strenge: // ...tseslint.configs.strictTypeChecked, { languageOptions: { parserOptions: { project: true, // Automatisch tsconfig.json finden tsconfigRootDir: import.meta.dirname, }, }, rules: { // Keine any-Typen erlauben '@typescript-eslint/no-explicit-any': 'error', // Floating Promises müssen behandelt werden '@typescript-eslint/no-floating-promises': 'error', // Unsafe-Operationen mit any '@typescript-eslint/no-unsafe-assignment': 'error', '@typescript-eslint/no-unsafe-member-access': 'error', '@typescript-eslint/no-unsafe-call': 'error', '@typescript-eslint/no-unsafe-return': 'error', // Return-Types explizit angeben '@typescript-eslint/explicit-function-return-type': [ 'warn', { allowExpressions: true, allowTypedFunctionExpressions: true, }, ], // Awaited-Typen korrekt verwenden '@typescript-eslint/await-thenable': 'error', // Konsistente Type-Imports '@typescript-eslint/consistent-type-imports': [ 'error', { prefer: 'type-imports', fixStyle: 'inline-type-imports' }, ], // Enum korrekt nutzen '@typescript-eslint/prefer-enum-initializers': 'error', }, }, );

tsconfig.json für ESLint optimieren

tsconfig.json
{ "compilerOptions": { "target": "ES2022", "module": "ESNext", "moduleResolution": "Bundler", "lib": ["ES2022", "DOM", "DOM.Iterable"], // Strict-Optionen (siehe Abschnitt 3) "strict": true, "noUncheckedIndexedAccess": true, "exactOptionalPropertyTypes": true, // Wichtig für ESLint type-aware rules "skipLibCheck": true, "resolveJsonModule": true, "isolatedModules": true, "verbatimModuleSyntax": true }, "include": ["src/**/*", "eslint.config.ts"], "exclude": ["node_modules", "dist"] }

Performance-Hinweis: Type-aware Rules erfordern eine vollständige TypeScript-Compilation. In großen Projekten kann das ESLint verlangsamen. Claude Code empfiehlt dann ein separates tsconfig.eslint.json, das nur die relevanten Dateien einschließt.

3. TypeScript Strict Mode vollständig aktivieren

Der strict-Flag in TypeScript ist nur der Anfang. 2026 gibt es weitere Compiler-Optionen, die produktionsreife Codebases deutlich robuster machen. Claude Code aktiviert diese schrittweise und erklärt bei jedem Schritt, welche Fehlerklassen damit verhindert werden.

Was strict: true wirklich aktiviert Strict

Der strict-Flag ist eine Kurzform für 8 separate Optionen: strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitAny, noImplicitThis, alwaysStrict und useUnknownInCatchVariables.

Die vollständige Strict-Konfiguration 2026

tsconfig.json — Vollständige Strict-Optionen
{ "compilerOptions": { // === STRICT BASE (alle 8 Sub-Flags) === "strict": true, // === ZUSÄTZLICHE STRICT-OPTIONEN === // Array-Index-Zugriff gibt T | undefined zurück // Verhindert: arr[0].property wenn arr leer sein könnte "noUncheckedIndexedAccess": true, // Optional Properties müssen wirklich optional sein // { prop?: string } !== { prop: string | undefined } "exactOptionalPropertyTypes": true, // Nicht genutzte Locals sind Fehler "noUnusedLocals": true, "noUnusedParameters": true, // Alle Switch-Fälle müssen return/break haben "noFallthroughCasesInSwitch": true, // Fehlende Properties in Overrides "noImplicitOverride": true, // Property-Zugriff über Index-Typen immer prüfen "noPropertyAccessFromIndexSignature": true, // Alle Code-Pfade müssen einen Wert zurückgeben "noImplicitReturns": true } }

Fehlerklassen die Strict Mode verhindert

1

strictNullChecks — Null-Dereferenzierung

Verhindert Cannot read properties of undefined — der häufigste Laufzeit-Fehler in JavaScript-Projekten.

2

noUncheckedIndexedAccess — Array-Sicherheit

const first = arr[0] hat den Typ string | undefined, nicht string. Zwingt zu expliziter Null-Behandlung.

3

exactOptionalPropertyTypes — Interface-Präzision

Unterscheidet zwischen "Eigenschaft existiert nicht" und "Eigenschaft ist undefined". Kritisch für API-Typen.

4

noImplicitOverride — Klassen-Sicherheit

Methoden die Base-Class-Methoden überschreiben müssen explizit override markiert werden. Verhindert stille Brüche bei Refactoring.

Claude Code beim Strict-Mode-Migration

Strict Mode in einer bestehenden Codebase zu aktivieren erzeugt oft hunderte Fehler. Claude Code geht systematisch vor:

# Anzahl der Fehler ermitteln npx tsc --strict --noEmit 2>&1 | grep "error TS" | wc -l # Claude Code Workflow für Migration: # 1. tsconfig: strict: true setzen # 2. tsc --noEmit ausführen → Fehler-Liste # 3. Fehler nach Kategorie gruppieren # 4. Systematisch von einfach nach komplex lösen # 5. noUncheckedIndexedAccess zuletzt (größte Impact)

4. Prettier-Integration ohne Konflikte

ESLint und Prettier können sich in die Quere kommen, wenn beide Formatierungsregeln definieren. Der richtige Setup deaktiviert ESLint-Formatierungsregeln komplett und überlässt Prettier das Formatting. Claude Code konfiguriert dieses Zusammenspiel fehlerfrei.

Zwei Pakete, eine Aufgabe Prettier

eslint-config-prettier deaktiviert ESLint-Regeln die mit Prettier kollidieren. eslint-plugin-prettier integriert Prettier als ESLint-Regel (optional, aber nützlich für einheitliche Fehler-Reports).

Terminal — Prettier-Stack installieren
npm install --save-dev \ prettier \ eslint-config-prettier \ eslint-plugin-prettier

Prettier-Konfiguration

.prettierrc.json
{ "semi": true, "singleQuote": true, "trailingComma": "all", "tabWidth": 2, "printWidth": 100, "bracketSpacing": true, "arrowParens": "always", "endOfLine": "lf", "importOrder": [ "^(react|next)(.*)", "<THIRD_PARTY_MODULES>", "^@/(.*)$", "^[./]" ], "importOrderSeparation": true, "plugins": ["@trivago/prettier-plugin-sort-imports"] }

ESLint + Prettier in Flat Config kombinieren

eslint.config.ts — mit Prettier
import prettierConfig from 'eslint-config-prettier'; import prettierPlugin from 'eslint-plugin-prettier'; import tseslint from 'typescript-eslint'; export default tseslint.config( // TypeScript-Konfiguration (aus Abschnitt 2) ...tseslint.configs.recommendedTypeChecked, { plugins: { prettier: prettierPlugin, }, rules: { // Prettier als ESLint-Regel ausführen 'prettier/prettier': 'error', }, }, // ZULETZT: eslint-config-prettier deaktiviert kollidierende Regeln // Reihenfolge ist kritisch — muss das letzte Config-Objekt sein! prettierConfig, );

VS Code Format-on-Save konfigurieren

.vscode/settings.json
{ "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" }, "eslint.validate": [ "javascript", "javascriptreact", "typescript", "typescriptreact" ], "typescript.tsdk": "node_modules/typescript/lib" }

Best Practice: Prettier formatiert, ESLint linted. Nie beide für dasselbe Ziel nutzen. Claude Code erkennt, wenn Regeln wie max-len oder indent im ESLint-Config aktiv sind, und deaktiviert diese automatisch zugunsten von Prettier.

5. Custom Rules & spezialisierte Plugins

Standard-Regeln reichen oft nicht. Claude Code kennt das gesamte ESLint-Plugin-Ökosystem und hilft beim Schreiben eigener Custom Rules — von einfachen Mustern bis zu AST-basierten Analysen.

Empfohlene Plugins für TypeScript-Projekte Plugins

Diese Plugins decken die häufigsten Code-Qualitäts-Probleme in TypeScript-Projekten ab und ergänzen den @typescript-eslint-Stack sinnvoll.

📦

eslint-plugin-import

Import-Reihenfolge, zirkuläre Abhängigkeiten, ungenutzte Imports, Path-Aliase prüfen.

⚛️

eslint-plugin-react-hooks

Rules of Hooks durchsetzen, exhaustive-deps für useEffect und useCallback.

🦄

eslint-plugin-unicorn

Moderne JavaScript-Patterns erzwingen: prefer-array-flat-map, no-array-for-each und viele mehr.

eslint-plugin-jsx-a11y

Accessibility-Regeln für JSX-Elemente — wichtig für barrierefreie React-Anwendungen.

Plugin-Konfiguration in Flat Config

eslint.config.ts — erweiterte Plugin-Konfiguration
import importPlugin from 'eslint-plugin-import'; import reactHooks from 'eslint-plugin-react-hooks'; import unicorn from 'eslint-plugin-unicorn'; import jsxA11y from 'eslint-plugin-jsx-a11y'; export default [ // Import-Regeln { plugins: { import: importPlugin }, rules: { 'import/no-duplicates': 'error', 'import/no-cycle': ['error', { maxDepth: 3 }], 'import/no-unused-modules': 'warn', 'import/order': [ 'error', { groups: [ 'builtin', 'external', 'internal', 'parent', 'sibling', 'index' ], 'newlines-between': 'always', alphabetize: { order: 'asc' }, }, ], }, }, // React Hooks (nur für .tsx Dateien) { files: ['**/*.tsx'], plugins: { 'react-hooks': reactHooks }, rules: { 'react-hooks/rules-of-hooks': 'error', 'react-hooks/exhaustive-deps': 'warn', }, }, // Unicorn — modernes JS erzwingen { plugins: { unicorn }, rules: { 'unicorn/prefer-array-flat-map': 'error', 'unicorn/prefer-string-slice': 'error', 'unicorn/no-array-for-each': 'error', 'unicorn/prefer-module': 'error', 'unicorn/prefer-top-level-await': 'warn', }, }, ];

Custom Rule schreiben — Praxisbeispiel

Claude Code kann projektspezifische ESLint-Regeln generieren. Hier ein Beispiel: eine Regel die verhindert, dass console.log in Produktionscode bleibt:

eslint-rules/no-debug-console.ts
import type { Rule } from 'eslint'; const noDebugConsole: Rule.RuleModule = { meta: { type: 'suggestion', docs: { description: 'Verbietet console.log in Produktionscode', recommended: true, }, messages: { noConsoleLog: 'console.log entfernen vor Commit. Nutze logger.debug() stattdessen.', }, schema: [], fixable: 'code', }, create(context) { return { CallExpression(node) { if ( node.callee.type === 'MemberExpression' && node.callee.object.type === 'Identifier' && node.callee.object.name === 'console' && node.callee.property.type === 'Identifier' && node.callee.property.name === 'log' ) { context.report({ node, messageId: 'noConsoleLog', fix(fixer) { return fixer.remove(node.parent); }, }); } }, }; }, }; export default noDebugConsole;

Custom Rule in Flat Config einbinden

import noDebugConsole from './eslint-rules/no-debug-console'; export default [ { plugins: { 'local-rules': { rules: { 'no-debug-console': noDebugConsole, }, }, }, rules: { 'local-rules/no-debug-console': 'error', }, }, ];

6. Monorepo & CI-Pipeline aufsetzen

Monorepos brauchen eine geteilte ESLint-Konfiguration plus workspace-spezifische Overrides. Claude Code generiert das gesamte Setup: shared config package, lint-staged Hooks, Husky und GitHub Actions CI.

Monorepo-Architektur Monorepo

Ein @acme/eslint-config-Package enthält die gemeinsame Basis. Jede App/Lib erweitert diese und fügt nur projektspezifische Overrides hinzu — kein Copy-Paste zwischen Paketen.

Shared ESLint Config Package

packages/eslint-config/package.json
{ "name": "@acme/eslint-config", "version": "1.0.0", "type": "module", "exports": { ".": "./src/index.ts", "./react": "./src/react.ts", "./node": "./src/node.ts" }, "peerDependencies": { "eslint": "^9.0.0", "typescript": "^5.0.0" }, "dependencies": { "@eslint/js": "^9.0.0", "@typescript-eslint/eslint-plugin": "^8.0.0", "@typescript-eslint/parser": "^8.0.0", "typescript-eslint": "^8.0.0", "eslint-config-prettier": "^10.0.0" } }
packages/eslint-config/src/index.ts — Basis-Config
import tseslint from 'typescript-eslint'; import prettierConfig from 'eslint-config-prettier'; import js from '@eslint/js'; import type { ConfigArray } from 'typescript-eslint'; export const baseConfig = (tsconfigPath: string): ConfigArray => tseslint.config( js.configs.recommended, ...tseslint.configs.strictTypeChecked, { languageOptions: { parserOptions: { project: tsconfigPath, }, }, rules: { '@typescript-eslint/consistent-type-imports': 'error', '@typescript-eslint/no-floating-promises': 'error', 'no-console': 'warn', }, }, prettierConfig, );

App-spezifische eslint.config.ts

apps/web/eslint.config.ts
import { baseConfig } from '@acme/eslint-config'; import { reactConfig } from '@acme/eslint-config/react'; export default [ ...baseConfig('./tsconfig.json'), ...reactConfig, // App-spezifische Overrides { rules: { 'no-console': 'off', // Web-App darf console nutzen }, }, ];

lint-staged & Husky Pre-Commit Hook

package.json — lint-staged Konfiguration
{ "lint-staged": { "**/*.{ts,tsx}": [ "eslint --fix --max-warnings 0", "prettier --write" ], "**/*.{js,mjs,cjs}": [ "eslint --fix", "prettier --write" ], "**/*.{json,md,yaml,yml}": [ "prettier --write" ] }, "scripts": { "lint": "eslint . --max-warnings 0", "lint:fix": "eslint . --fix", "format": "prettier --write .", "format:check": "prettier --check .", "prepare": "husky" } }
.husky/pre-commit
#!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" # TypeScript-Typen prüfen npx tsc --noEmit # Nur gestagte Dateien linten npx lint-staged

GitHub Actions CI-Pipeline

CI-Strategie CI/CD

Die CI-Pipeline prüft TypeScript-Typen, ESLint und Prettier-Formatierung in parallelen Jobs. Nur wenn alle drei bestehen, darf ein PR gemergt werden.

.github/workflows/code-quality.yml
name: Code Quality on: push: branches: [main, develop] pull_request: branches: [main] jobs: typecheck: name: TypeScript Type Check runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' - run: npm ci - run: npx tsc --noEmit lint: name: ESLint runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' - run: npm ci - run: npx eslint . --max-warnings 0 --format github-actions format: name: Prettier Format Check runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' - run: npm ci - run: npx prettier --check . quality-gate: name: Quality Gate needs: [typecheck, lint, format] runs-on: ubuntu-latest steps: - run: echo "All quality checks passed ✓"

Monorepo: Root-Level Lint für alle Workspaces

# Alle Workspaces parallel linten (pnpm) pnpm -r --parallel exec eslint . --max-warnings 0 # Mit Turborepo (empfohlen für große Monorepos) # turbo.json: { "tasks": { "lint": { "dependsOn": ["^build"], "outputs": [], "cache": true } } }

Turborepo + ESLint Cache: Turborepo cached ESLint-Ergebnisse pro Package. Nur geänderte Packages werden neu gelinted. In großen Monorepos reduziert das die CI-Zeit um 70-90%.

Zusammenfassung: Claude Code als TypeScript-Linting-Experte

Die sechs Konfigurationsbereiche in diesem Leitfaden decken den vollständigen Stack produktionsreifer TypeScript-Projekte ab. Claude Code kennt alle Details: von den Breaking Changes in ESLint 9.x über die subtilen Unterschiede zwischen exactOptionalPropertyTypes und strictNullChecks bis hin zu Performance-Optimierungen für Monorepos mit Turborepo-Caching.

Statt stundenlang Dokumentationen zu durchsuchen und Konfigurationen zu debuggen, beschreibst du Claude Code dein Projektsetup — und bekommst eine vollständige, getestete Konfiguration zurück. Mit Erklärungen zu jeder Regel und Best-Practice-Empfehlungen für dein spezifisches Tech-Stack.

Sofortiger Setup

Komplette ESLint + TypeScript Konfiguration in Minuten statt Stunden — inkl. Monorepo und CI.

🔍

Regel-Erklärungen

Claude Code erklärt warum jede Regel wichtig ist — du lernst, nicht nur konfigurierst.

🔄

Automatische Migration

Von .eslintrc zu Flat Config, von ESLint 8 zu 9, von partial strict zu full strict — schrittweise und sicher.

🛡️

Custom Rules on Demand

Projektspezifische ESLint-Regeln für deine Patterns — AST-basiert und vollständig typisiert.

Jetzt Claude Code ausprobieren

Konfiguriere deinen TypeScript-Stack in Minuten — ESLint Flat Config, Strict Mode, Prettier und CI inklusive.

Kostenlosen Trial starten