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
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.
# 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
{
"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
{
"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
{
"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"
}
}
#!/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