# Claude Code Hooks für Einsteiger: Wiederkehrende Aufgaben automatisieren

> Ein umfassender praktischer Leitfaden zur Einrichtung von Hooks in Claude Code: Automatisches Linting, Formatierung, präventive Prüfungen vor dem Commit, Benachrichtigungen und Headless-Automatisierung.

## 1. Was sind Hooks in Claude Code und wofür werden sie benötigt?

Bei der Arbeit mit einem KI-Assistenten im Terminal sind Entwickler oft gezwungen, dieselben Routinebefehle zu wiederholen: *"Führe jetzt ESLint aus"*, *"Formatiere den Code mit Prettier"*, *"Prüfe die Typen vor dem Commit"*. Selbst wenn diese Regeln in den Systemanweisungen von `CLAUDE.md` definiert sind, kann das Sprachmodell sie gelegentlich vergessen oder aufgrund von Token-Einsparungen überspringen.

**Hooks** in Claude Code lösen dieses Problem radikal: Es handelt sich um deterministische Trigger, die Systembefehle oder Skripte automatisch an exakten Punkten im Lebenszyklus des Assistenten aufrufen.

Die Logik der Hooks ist einfach:
> **Wenn Claude Ereignis X ausgeführt hat → garantiert das Betriebssystem die Ausführung von Aktion Y.**

```mermaid
flowchart LR
    subgraph Текстова_інструкція["CLAUDE.md (Ймовірнісна)"]
        A["Промпт: 'Завжди запускай лінтер'"] --> B{"Модель пам'ятає?"}
        B -->|Іноді| C["Запуск перевірки"]
        B -->|Пропустила| D["Помилки накопичуються"]
    end
    subgraph Нативний_Hook["Hooks у settings.json (Детермінована)"]
        E["Подія: Редагування файлу"] --> F["Автоматичний тригер ОС"]
        F --> G["Гарантоване виконання npx eslint"]
    end
```

### Vergleich der Automatisierungsansätze

| Merkmal | Manuelle Prompts | Anweisungen in CLAUDE.md | Native Hooks |
| :--- | :--- | :--- | :--- |
| **Zuverlässigkeit der Ausführung** | Niedrig (abhängig vom Gedächtnis des Menschen) | Mittel (wahrscheinlichkeitsbasiertes Verhalten des LLM) | 100 % (deterministische Ereignisüberwachung) |
| **Token-Verbrauch** | Hoch (jedes Mal werden Abfrage-Tokens verbraucht) | Mittel (Regel wird in jeden Kontext geladen) | Null (wird lokal in der Shell ausgeführt) |
| **Reaktionsgeschwindigkeit** | Langsam (manuelle Befehlseingabe) | Erfordert eine zusätzliche Generierungsrunde | Sofort (nativer Prozessaufruf) |
| **Blockierungsmöglichkeit** | Nicht vorhanden | Nicht vorhanden | Vorhanden (ein Exit-Code ungleich null stoppt die Aktion) |

> [!NOTE]
> Hooks für Claude Code werden im JSON-Format in der Datei `.claude/settings.json` auf Ebene eines einzelnen Repositorys oder global in `~/.claude/settings.json` konfiguriert.

---

## 2. Ereignis-Lebenszyklus: PreToolUse, PostToolUse, Notification, Stop

Claude Code bietet vier grundlegende Überwachungspunkte (Ereignisse), an die automatisierte Befehle gebunden werden können.

```mermaid
sequenceDiagram
    autonumber
    actor Dev as Розробник
    participant Agent as Claude Code
    participant Hook as Система Hooks
    participant Tool as Інструмент (Bash/Edit/Write)

    Dev->>Agent: Запит на модифікацію коду
    Agent->>Hook: Спроба виклику інструмента
    Note over Hook: PreToolUse Hook
    Hook-->>Agent: Перевірка пройдена (Exit Code 0)
    Agent->>Tool: Виконання операції
    Tool-->>Agent: Результат успішний
    Agent->>Hook: Подія завершення операції
    Note over Hook: PostToolUse Hook
    Hook-->>Agent: Результат лінтингу / форматування
    Agent->>Hook: Завершення відповіді моделі
    Note over Hook: Stop Hook (Сповіщення)
    Agent-->>Dev: Фінальна відповідь
```

### Wichtige Auslösepunkte

1. **`PreToolUse` (Vor der Verwendung des Tools):** Wird *bevor* der Agent eine Aktion ausführt ausgelöst. Wenn der Hook-Befehl einen Fehler zurückgibt (Exit-Code ungleich 0), wird die Ausführung der Aktion blockiert. Dies ist der ideale Ort für Schutzprüfungen vor Commits oder Pushes.
2. **`PostToolUse` (Nach der Verwendung des Tools):** Wird *unmittelbar nach* der erfolgreichen Ausführung des Tools ausgelöst. Der beliebteste Trigger für die automatische Code-Formatierung (Prettier) oder das Linting geänderter Dateien (ESLint).
3. **`Notification` (Benachrichtigung):** Aktiviert, wenn der Assistent eine wichtige Systemnachricht senden oder eine zusätzliche Autorisierung anfordern muss.
4. **`Stop` (Beendigung der Antwort):** Wird in dem Moment ausgelöst, in dem Claude Code die Generierung der Antwort vollständig abgeschlossen hat und auf die nächste Benutzernachricht wartet. Wird zur Wiedergabe von Audiosignalen und Desktop-Benachrichtigungen verwendet.

![Auslösepunkte von Hooks im Lebenszyklus](/api/guides-media/automation/hooks-automation-guide-for-beginners/images/hooks-automation-guide-for-beginners-extra-02.webp)

---

## 3. Konfigurationsstruktur in settings.json und Matcher-Syntax

Die Hook-Konfiguration wird in der Datei `.claude/settings.json` gespeichert. Falls diese Datei noch nicht im Stammverzeichnis Ihres Projekts vorhanden ist, erstellen Sie sie.

### Grundlegende Konfigurationssyntax

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'Починається редагування файлу...'"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'Bash-команда завершена успішно'"
          }
        ]
      }
    ]
  }
}
```

### Funktionsweise des Feldes Matcher

Das Feld `matcher` bestimmt, auf welches spezifische Tool des Agents ein bestimmter Hook reagieren soll:

- `"Edit"` – überwacht die Änderung bereits vorhandener Dateien.
- `"Write"` – wird beim Erstellen einer neuen Datei oder beim vollständigen Überschreiben ausgelöst.
- `"Bash"` – reagiert auf die Ausführung beliebiger Konsolenbefehle.
- `"Bash(git commit*)"` – ein gezieltes Muster, das Bash-Aufrufe filtert, die mit dem Befehl `git commit` beginnen.
- `"*"` – universeller Selektor (Wildcard), der auf jedes Tool des Agents reagiert.

> [!TIP]
> Die `matcher`-Muster unterscheiden zwischen Groß- und Kleinschreibung. Verwenden Sie die Standardnamen der Claude Code Tools: `Edit`, `Write`, `Bash`, `Glob`, `Grep`.

---

## 4. Automatisches Linting und Formatieren (ESLint + Prettier)

Das praktischste tägliche Szenario ist die Delegation der Formatierung und der primären Stilprüfung an die Utilities `Prettier` und `ESLint`. Dadurch wird sichergestellt, dass der Code immer in einem perfekten Zustand im Repository gespeichert wird.

### Einrichtung von PostToolUse für ESLint und Prettier

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx eslint --fix \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
          }
        ]
      },
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}
```

### Analyse der Sicherheitsflags im Befehl

- `"$CLAUDE_FILE_PATH"` – eine dynamische Umgebungsvariable, in die Claude automatisch den vollständigen Pfad zur Datei einfügt, sobald diese vom Agenten geändert wurde.
- `2>/dev/null` – unterdrückt überflüssige Service-Fehlerausgaben des stderr-Streams, um das Terminal nicht zu überlasten.
- `|| true` – eine kritisch wichtige bash-Konstruktion. Sie stellt sicher, dass der Hook selbst dann mit Code `0` endet und die weitere Arbeit des Agenten nicht stoppt, wenn der Linter nicht behebbare Fehler findet und Code `1` zurückgibt.

```mermaid
flowchart TD
    A["Claude викликає Edit"] --> B["Файл збережено на диску"]
    B --> C["PostToolUse тригер"]
    C --> D["npx eslint --fix $CLAUDE_FILE_PATH"]
    D --> E{"Успішно або || true"}
    E --> F["Агент продовжує вирішувати задачу"]
```

---

## 5. Schutzbarrieren vor git commit (TypeCheck + Tests)

Während wir für die Formatierung weiche Hooks mit `|| true` verwendet haben, erfordert die Fixierung von Änderungen im Versionskontrollsystem strenge Qualitätskontrollen (Quality Gate).

Mit `PreToolUse` kann das Erstellen eines Commits blockiert werden, wenn im Projekt TypeScript-Kompilierungsfehler vorliegen oder Unit-Tests fehlschlagen.

### Einrichtung eines blockierenden Pre-commit-Hooks

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(git commit*)",
        "hooks": [
          {
            "type": "command",
            "command": "npm run typecheck && npm run lint"
          }
        ]
      }
    ]
  }
}
```

### Was passiert bei der Erkennung von Fehlern

1. Claude formuliert den Befehl `git commit -m "..."`.
2. Vor dessen Ausführung aktiviert das System `PreToolUse`.
3. Validierungsbefehle werden gestartet: `npm run typecheck` und `npm run lint`.
4. **Wenn ein Fehler erkannt wird:** Gibt der Prozess einen Exit-Code ungleich null zurück (Exit-Code 1).
5. Claude Code fängt die Ausgabe des Compiler-Fehlers direkt in seinem Kontext ab.
6. Anstelle eines fehlerhaften Commits analysiert der Assistent den Fehlertext, korrigiert die Typen im Code automatisch und unternimmt einen erneuten sauberen Commit-Versuch.

> [!IMPORTANT]
> Beachten Sie: Verwenden Sie in blockierenden Prüfungen von `PreToolUse` **niemals** `|| true`, da sonst die Prüfung immer als erfolgreich gewertet wird und die Schutzbarriere außer Kraft gesetzt wird.

---

## 6. Audio- und Desktop-Benachrichtigungen bei Abschluss von Aufgaben (Stop Hook)

Komplexe Refactorings oder die Ausführung eines vollständigen Testsatzes können 2 bis 10 Minuten dauern. Statt ununterbrochen ins Terminal zu schauen, richten Sie Benachrichtigungen über das Ereignis `Stop` ein.

:::tabs
@tab macOS
```json
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "afplay /System/Library/Sounds/Glass.aiff && osascript -e 'display notification \"Завдання виконано!\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}
```
@tab Linux (Ubuntu / Debian)
```json
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "paplay /usr/share/sounds/freedesktop/stereo/complete.oga 2>/dev/null || notify-send 'Claude Code' 'Завдання успішно виконано!'"
          }
        ]
      }
    ]
  }
}
```
@tab Windows (WSL / PowerShell)
```json
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "powershell.exe -c \"[System.Media.SystemSounds]::Asterisk.Play(); [System.Console]::Beep(800, 250)\""
          }
        ]
      }
    ]
  }
}
```
:::

> [!TIP]
> Die Benachrichtigung wird nur ausgelöst, wenn der Agent die Generierung der endgültigen Antwort vollständig abschließt, nicht zwischenzeitlichen Tool-Aufrufen.

---

## 7. Kontextübergabe über Umgebungsvariablen

Damit Automatisierungsskripte flexibel und adaptiv sind, exportiert Claude Code Metadaten der aktuellen Operation automatisch in System-Umgebungsvariablen (Environment Variables).

![Umgebungsvariablen von Claude Code für Hooks](/api/guides-media/automation/hooks-automation-guide-for-beginners/images/hooks-automation-guide-for-beginners-extra-01.webp)

### Nachschlagewerk der System-Umgebungsvariablen von Claude Code

| Umgebungsvariable | Werttyp | Beschreibung und Beispielinhalt |
| :--- | :--- | :--- |
| **`$CLAUDE_FILE_PATH`** | Absoluter Pfad | Pfad zur spezifischen Datei, die gerade erstellt oder bearbeitet wird (`/Users/dev/project/src/index.ts`) |
| **`$CLAUDE_TOOL_NAME`** | Text-Identifier | Name des Tools, das das Ereignis initiiert hat (`Edit`, `Write`, `Bash`) |
| **`$CLAUDE_PROJECT_DIR`** | Absoluter Pfad | Wurzelverzeichnis des Projekts, in dem die aktuelle Claude Code Sitzung läuft |

### Beispiel eines kontextbezogenen Bash-Skripts für einen Hook

Erstellen wir ein Skript `.claude/hooks/smart-validator.sh`:

```bash
#!/usr/bin/env bash
set -e

# Перевіряємо, чи існує файл і яке у нього розширення
if [[ -f "$CLAUDE_FILE_PATH" ]]; then
  case "$CLAUDE_FILE_PATH" in
    *.ts|*.tsx)
      echo "⚡ Валідація TypeScript файлу: $CLAUDE_FILE_PATH"
      npx eslint --fix "$CLAUDE_FILE_PATH" || true
      ;;
    *.json)
      echo "🔍 Перевірка валідності JSON..."
      jq empty "$CLAUDE_FILE_PATH" 2>/dev/null || echo "Помилка формату JSON!"
      ;;
    *.md)
      echo "📝 Оновлено документацію: $(basename "$CLAUDE_FILE_PATH")"
      ;;
  esac
fi
```

Nun reicht es aus, in `.claude/settings.json` den Aufruf dieses Skripts anzugeben:

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/smart-validator.sh"
          }
        ]
      }
    ]
  }
}
```

---

## 8. Das „CI-in-a-Loop“-Pattern: kontinuierliches Feedback

In der traditionellen Entwicklung ohne Hooks entsteht ein Bruchmuster: Der Agent nimmt Änderungen an Dutzenden von Dateien vor, woraufhin ein Projekt-Build startet, der eine Lawine von 40 Typfehlern ausgibt. Dem Agenten fällt es schwer herauszufinden, welche genau diese Änderung zum Bruch geführt hat.

**CI-in-a-Loop (Kurzer Feedback-Zyklus)** dreht diesen Prozess um:

```mermaid
flowchart TD
    A["Claude вносить правку в код"] --> B["Миттєвий запуск tsc"]
    B --> C{"Є помилка?"}
    C -->|Так| D["Claude бачить 1 точкову помилку"]
    D --> E["Миттєвий фікс за 5 секунд"]
    E --> B
    C -->|Ні| F["Перехід до наступного рядка/файлу"]
```

### Konfiguration des zyklischen TypeScript-Audits

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx tsc --noEmit 2>&1 | head -n 20 || true"
          }
        ]
      }
    ]
  }
}
```

### Warum `head -n 20` zwingend erforderlich ist

Wenn die Compiler-Ausgabe Hunderte von Logzeilen zurückgibt, landen diese im Modellkontext und können das Token-Limit überschreiten. Die Einschränkung durch `head -n 20` zeigt die ersten kritischsten Fehler an und gibt dem Modell eine präzise Orientierungshilfe für sofortige Korrekturen, ohne die Sitzung zu überlasten.

---

## 9. Headless-Automatisierung: Modus -p, Cron und Git Hooks

Hooks können mit dem autonomen (Headless-)Modus von Claude Code kombiniert werden – dem Flag `-p` (print/prompt). Dies ermöglicht die vollständige Automatisierung von Aufgaben ohne menschliches Zutun.

```mermaid
flowchart LR
    A["Розклад Cron (02:00)"] --> B["Скрипт nightly-audit.sh"]
    B --> C["claude -p 'Run test suite, fix bugs, commit'"]
    C --> D["Хуки PostToolUse контролюють код"]
    D --> E["Автоматичний Push результату"]
```

### Autonomes Skript für nächtliche Audits (nightly-audit.sh)

```bash
#!/usr/bin/env bash
cd /var/www/my-project

# Запуск Claude Code в автономному режимі з фіксованим завданням
claude -p "Run full test suite. If any tests fail, inspect the stack trace and fix them. Ensure typecheck passes. Finally, commit all fixes with a conventional commit." >> /var/log/claude-audit.log 2>&1
```

### Planung der Ausführung über Cron

Öffnen Sie den Task-Planer (`crontab -e`) und konfigurieren Sie die Ausführung jede Nacht um 03:00 Uhr:

```text
0 3 * * * /usr/local/bin/nightly-audit.sh
```

### Start der Prüfung im nativen Git Hook (.git/hooks/post-merge)

Um nach jedem Empfang von Updates via `git pull` automatisch eine Kompatibilitätsanalyse zu starten:

```bash
#!/usr/bin/env bash
# .git/hooks/post-merge
echo "🚀 Запуск автоматичної перевірки залежностей через Claude..."
claude -p "Check if package.json was updated. If so, run npm install, verify build, and report summary."
```

Vergessen Sie nicht, dem Skript Ausführungsrechte zu geben: `chmod +x .git/hooks/post-merge`.

---

## 10. Beste Engineering-Praktiken und Sicherheitsregeln für Hooks

Falsch konfigurierte Hooks können die Ausführung in eine Endlosschleife treiben oder die Terminalarbeit blockieren. Halten Sie sich an vier grundlegende Regeln der Engineering-Hygiene.

### Vier Regeln für das sichere Design von Hooks

1. **Extreme Geschwindigkeit:** Hooks mit dem Ereignis `PostToolUse` werden nach jeder Dateänderung ausgeführt. Wenn ein Hook länger als 1–2 Sekunden dauert, wird die interaktive Arbeit mit Claude langsam und unbequem. Führen Sie schwere E2E-Tests nur in `PreToolUse` vor dem Commit aus, aber nicht nach jedem `Edit`.
2. **Pflichtprotokollierung der Ausgabe:** Leiten Sie die Ausgabe diagnostischer Skripte immer in eine temporäre Log-Datei um:
   ```bash
   "command": "bash .claude/hooks/check.sh >> /tmp/claude-hooks.log 2>&1 || true"
   ```
   Wenn ein Hook aufhört zu feuern, können Sie sofort `/tmp/claude-hooks.log` öffnen und die Ursache finden.
3. **Isoliertes Testen im reinen Terminal:** Bevor Sie einen Befehl zu `settings.json` hinzufügen, führen Sie ihn manuell in einer normalen Shell aus. Wenn der Befehl in der Konsole einen Fehler wirft, wird er garantiert die Claude Code Sitzung brechen.
4. **Verhindern unendlicher Rekursion:** Konfigurieren Sie niemals einen Befehl in `PostToolUse`, der selbst Projektdateien ohne Ignorier-Flags ändert (z. B. ein Drittanbieter-Skript, das einen erneuten `Edit` aufruft), da der Agent sonst in eine ewige Aufrufschleife gerät.

> [!WARNING]
> Führen Sie über Hooks keine Befehle aus, die auf interaktive Eingaben des Benutzers warten (z. B. Bestätigungen wie `read -p` oder `sudo` mit Passwortabfrage). Dies führt dazu, dass der Terminalprozess hängt.

---

## 11. Praktischer Workshop, Spickzettel und abschließende Checkliste

Für einen schnellen Start in Ihrem eigenen Projekt nutzen Sie den fertigen zusammengefassten Spickzettel und die geprüfte Production-Konfiguration.

![Spickzettel zur Auswahl des Hook-Typs für die Automatisierung](/api/guides-media/automation/hooks-automation-guide-for-beginners/images/hooks-automation-guide-for-beginners-extra-03.webp)

### Fertige Konfigurationsdatei `.claude/settings.json`

Kopieren Sie diese Referenzkonfiguration in den Ordner `.claude` Ihres Projekts:

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(git commit*)",
        "hooks": [
          {
            "type": "command",
            "command": "npm run typecheck && npm test"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
          }
        ]
      },
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Роботу завершено!\" with title \"Claude Code\"' 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}
```

### Schnelle Selbstüberprüfung

> **1. Worin unterscheidet sich `PreToolUse` grundsätzlich von `PostToolUse`?**
>
> > [!TIP]
> > **Antwort:** `PreToolUse` wird *vor* der Ausführung der Tool-Aktion gestartet und kann diese bei einem Exit-Code ungleich null blockieren. `PostToolUse` wird *nach* dem erfolgreichen Abschluss der Operation gestartet und dient der Formatierung oder dem Linting.

> **2. Warum wird in Formatierungs-Hooks `|| true` hinzugefügt?**
>
> > [!TIP]
> > **Antwort:** Damit Fehler des Linters oder Formatters keinen kritischen Status zurückgeben und den Generierungsprozess der Agentenantwort nicht stoppen.

> **3. Welche Umgebungsvariable enthält den Pfad zur gerade bearbeiteten Datei?**
>
> > [!TIP]
> > **Antwort:** Die Variable `$CLAUDE_FILE_PATH`.

### Abschließende Checkliste für die Implementierung von Hooks

- [ ] Verzeichnis `.claude/` und Datei `settings.json` im Projektstammverzeichnis erstellt.
- [ ] Automatische Formatierung geänderter Dateien über `PostToolUse` + `Prettier` eingerichtet.
- [ ] Schutzbarriere `PreToolUse` für `Bash(git commit*)` mit `typecheck`-Prüfung hinzugefügt.
- [ ] Akustische oder Bildschirmbenachrichtigung für das Ereignis `Stop` verbunden.
- [ ] Alle Hook-Befehle vor dem Speichern in der Konfiguration manuell im Terminal getestet.
- [ ] Geprüft, dass keine interaktiven Befehle enthalten sind, die auf Eingaben wie `[y/N]` oder Passwörter warten.