ai-machine-learning

Claude Code Hooks: Den kompletta utvecklarguiden med produktionsklara exempel

Skriven av Mert Batur
Apr 5, 2026
15 läsning
Claude Code Hooks: Den kompletta utvecklarguiden med produktionsklara exempel

Claude Code Hooks: Den kompletta utvecklarguiden med produktionsklara exempel

Claude Code är utmärkt på att skriva kod, men det är ändå ett probabilistiskt system. Du kan be det köra Prettier efter varje filredigering. Du kan lägga in den instruktionen i din CLAUDE.md. Och ibland glömmer det... ändå. Claude Code hooks löser det här genom att ge dig deterministisk, garanterad kontroll över vad som händer före, under och efter varje åtgärd som Claude utför.

Jag har konfigurerat hooks i dussintals projekt under de senaste månaderna, och de har tyst blivit den viktigaste delen av min Claude Code-konfiguration. Den här guiden täcker allt från grunderna till ett produktionsklart startpaket som du kan använda i vilket projekt som helst idag. Om du har använt Claude Code tillsammans med verktyg som Cursor eller Copilot vet du redan värdet av anpassning -- hooks tar det ett steg längre.

Vad är Claude Code Hooks (och varför ska du bry dig)?

Claude Code hooks är användardefinierade skalkommandon, HTTP-endpoints eller LLM-prompter som körs automatiskt vid specifika punkter i Claude Codes livscykel. Enligt Anthropics officiella dokumentation aktiveras hooks deterministiskt varje gång -- till skillnad från promptinstruktioner som Claude kan ignorera -- och ger dig garanterad kontroll över formattering, säkerhet, notiser och arbetsflödesautomatisering.

Det probabilistiska problemet

Här är det knepiga med CLAUDE.md-instruktioner: de är förslag, inte kontrakt. Du kan skriva "kör alltid npx prettier --write efter redigering av TypeScript-filer" i din projektkonfiguration, och Claude följer det för det mesta. Men "för det mesta" räcker inte när du tillämpar kodformattering i ett team, eller blockerar pushar till produktion, eller loggar varje skalkommando för en säkerhetsrevision.

Det här är den grundläggande spänningen i alla AI-kodverktyg. Claude är en språkmodell -- den arbetar med sannolikheter. Din context engineering kan styra beteendet, men kan inte garantera det.

Hur hooks löser det här

Hooks kringgår LLM:en helt. De är skalskript, HTTP-anrop eller AI-utvärderingar som aktiveras vid specifika livscykelhändelser -- innan ett verktyg körs (PreToolUse), efter att det är klart (PostToolUse), när ett meddelande visas, när en session startar, eller när Claude slutar. Tänk på dem som Git-hooks, men för din AI-kodassistent.

Det finns fyra hook-typer: command (skalskript), HTTP (webhook POST-förfrågningar), prompt (enstaka Claude ja/nej-utvärderingar) och agent (skapar en underagent med verktygsåtkomst). Vi går igenom varje typ senare -- command-hooks hanterar ungefär 90 % av vad du behöver.

Hur Claude Code Hooks fungerar: Livscykelflödet

Claude Code hooks körs i ett definierat livscykelflöde: en händelse aktiveras (t.ex. PreToolUse), matcharen kontrollerar om hooken gäller, hook-skriptet körs och tar emot JSON via stdin, och exit-koden avgör vad som händer härnäst. Exit-kod 0 innebär att fortsätta, exit-kod 2 innebär att blockera åtgärden. Det här flödet är detsamma oavsett vilken hook-typ du använder.

Händelse -> Matchare -> Hook -> Exit-kod (det 4-stegsflödet)

Så här fungerar varje hook-körning:

text
1. HÄNDELSE AKTIVERAS   t.ex. PreToolUse(Write)
       |
2. MATCHARE KONTROLLERAR  Matchar "Write" hookens matcharmönster?
       |
3. HOOK KÖRS            Skalskript körs, tar emot JSON via stdin
       |
4. EXIT-KOD BESTÄMMER   0 = fortsätt | 2 = blockera | annat = fel

JSON:en som kommer via stdin innehåller allt om händelsen: tool_name, tool_input (filsökväg, innehåll, kommando) och sessionsmetadata. Ditt skript läser denna JSON, utför den logik det behöver och avslutar med lämplig kod.

För PreToolUse-hooks är exit-kod 2 den kraftfulla -- den blockerar åtgärden helt och skickar ditt stdout-meddelande tillbaka till Claude som feedback. Claude ser ditt meddelande och kan justera sitt tillvägagångssätt.

Konfigurationsomfång: Användare, projekt och lokalt

Hooks finns i settings.json på tre nivåer:

OmfångFilCommitted till Git?Användningsfall
Användare~/.claude/settings.jsonNejPersonliga standardinställningar (notiser, formatteringsinställningar)
Projekt.claude/settings.jsonJaTeam-delade hooks (filskydd, testkörnare, linting)
Lokalt.claude/settings.local.jsonNej (gitignorerad)Personliga overrides för det här projektet

Projektinställningar är mest användbara för team. Lägg in dina hooks i .claude/settings.json, commita det, och varje utvecklare i teamet får samma skyddsräcken automatiskt.

Fältet if: Detaljerad filtrering

Sedan Claude Code v2.1.85 stöder hooks ett if-fält som låter dig filtrera på verktygsargument -- inte bara verktygsnamn. Som dokumenterat i Anthropics hooks-referens innebär det att du kan skriva en hook som bara aktiveras på Bash-kommandon som matchar git push, istället för att aktiveras vid varje enskilt Bash-anrop.

json
{
  "matcher": "Bash",
  "if": "tool_input.command matches 'git push'",
  "hooks": [{ "type": "command", "command": "./scripts/check-branch.sh" }]
}

Det här var en game-changer. Innan if var du tvungen att antingen matcha för brett (varje Bash-kommando) eller göra filtreringen inuti ditt skript (rörigt).

Alla Claude Code Hook-händelser: Snabbreferenstabell

Claude Code tillhandahåller över 20 hook-händelser i sin livscykel, dokumenterade i den officiella hooks-referensen och Claude Code-ändringsloggen. De vanligast använda är PreToolUse, PostToolUse, Notification och Stop -- men nyare händelser som ConfigChange och FileChanged öppnar upp avancerade automatiseringsmönster.

Här är den kompletta referensen:

HändelseNär den aktiverasKan blockera?Vanligt användningsfall
PreToolUseInnan ett verktyg körsJa (exit 2)Blockera farliga kommandon, skydda filer
PostToolUseEfter att ett verktyg är klartNejAutoformattera, kör tester, logga åtgärder
NotificationNär Claude skickar ett meddelandeNejSkrivbordsvarningar, Slack-meddelanden
StopNär Claude avslutar ett svarNejStädning, sammanfattningsgenerering
SessionStartVid sessionsinitialiseringNejInjicera kontext, ställ in miljö
UserPromptSubmitNär användaren skickar en promptJa (exit 2)Inmatningsvalidering, innehållsfiltrering
PreCompactInnan kontextkomprimeringNejSpara tillstånd innan minnet trimmas
PostCompactEfter kontextkomprimeringNejInjicera om kritisk kontext
ConfigChangeNär inställningar ändrasNejHeta omladdning av miljövariabler
FileChangedNär en bevakad fil ändrasNejUtlösa byggen, invalidera cacher
TaskCreatedNär en ny uppgift skapasNejUppgiftsspårning, resursallokering
PermissionDeniedNär en behörighetskontroll misslyckasNejRevisionsloggning, avisering om blockerade åtgärder
WorktreeCreateNär ett nytt Git-arbetstree skapasNejInitiera arbetstreespecifika inställningar
SubagentStartNär en underagent skapasNejÖvervaka underagentaktivitet
SubagentStopNär en underagent är klarNejValidera underagentens utdata

Proffstips: Du kommer att använda PreToolUse och PostToolUse för 80 % av dina hooks. SessionStart är näst mest användbar -- den är perfekt för att injicera projektkontexten som Claude behöver i början av varje session.

De 4 Claude Code Hook-typerna förklarade

Claude Code stöder fyra hook-hanteringstyper: command-hooks kör skalskript, HTTP-hooks POSTar till URL:er, prompt-hooks ställer Claude en ja/nej-fråga, och agent-hooks skapar en underagent med verktygsåtkomst. I vår erfarenhet hanterar command-hooks 90 % av användningsfallen. Använd HTTP för externa integrationer, prompt- och agent-hooks för nyanserade beslut som kräver AI-omdöme.

TypHastighetKomplexitetBäst förExempel
CommandSnabbLågFormattering, blockering, loggningKör Prettier efter filredigering
HTTPMedelMedelExterna tjänster, webhooksPOST till Slack vid avslut
PromptLångsamMedelSubjektiva beslut"Är den här koden säker att köra?"
AgentLångsammastHögKomplex filmedveten verifieringKontrollera om ny kod följer projektmönster

Command-hooks (arbetshästen)

Command-hooks kör ett skalkommando och använder exit-koden för att avgöra utfallet. De tar emot händelsens JSON-data via stdin.

json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "jq -r '.tool_input.command' | grep -q 'rm -rf /' && exit 2 || exit 0"
      }]
    }]
  }
}

Det här är vad du använder för formattering, filskydd, notiser och de flesta automatiseringar. Snabbt, enkelt och förutsägbart.

HTTP-hooks (externa integrationer)

HTTP-hooks skickar en POST-förfrågan till en URL med händelsens JSON som body. Svarsstatuskoden avgör utfallet (200 = fortsätt, 403 = blockera).

json
{
  "hooks": {
    "Stop": [{
      "matcher": "",
      "hooks": [{
        "type": "http",
        "url": "https://your-api.com/claude-webhook"
      }]
    }]
  }
}

Utmärkt för att skicka händelser till Slack, Discord, PagerDuty eller en anpassad instrumentpanel. Du kan också använda det här för att fråga en extern policymotor innan du tillåter en verktygskörning.

Prompt-hooks (AI-drivna beslut)

Prompt-hooks skickar händelsedata till Claude självt för en enstaka ja/nej-utvärdering. Claude returnerar ett JSON-svar med "decision": "allow" eller "decision": "block" plus motivering.

json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "prompt",
        "prompt": "Is this bash command safe to run in a production environment? Consider: does it modify system files, delete data, or access sensitive credentials?"
      }]
    }]
  }
}

Använd dessa sparsamt. De lägger till latens (ett helt LLM-anrop per hook-körning) och kostar pengar. Men för genuint subjektiva säkerhetskontroller -- som "verkar den här databasmigrationen destruktiv?" -- är de svåra att slå. Om du är nyfiken på att byta Claude Code-modeller följer modellen som används för prompt-hooks din aktuella sessionsmodell.

Agent-hooks (verktygsassisterad verifiering)

Agent-hooks skapar en underagent med tillgång till Read-, Grep- och Glob-verktyg. Underagenten kan inspektera filer innan den fattar sitt beslut.

json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Write",
      "hooks": [{
        "type": "agent",
        "prompt": "Check if the file being written follows the project's naming conventions and import patterns. Read .claude/CONVENTIONS.md for the rules."
      }]
    }]
  }
}

Det här är den kraftfullaste hook-typen, men också den långsammaste. Reservera den för högrisk-kontroller där du behöver filkontext för att fatta ett bra beslut.

7 produktionsklara Claude Code Hook-exempel (klara att kopiera)

De mest användbara Claude Code-hooks inkluderar autoformattering med Prettier eller Black efter filredigering, blockering av skrivningar till skyddade filer, skrivbordsnotiser vid uppgiftsavslut, injicering av projektkontexten vid sessionsstart, körning av tester efter kodändringar, tillämpa grenskydd och granskning av all verktygsamvändning. Jag har kört varianter av dessa i varje projekt under de senaste tre månaderna.

Varje exempel nedan är ett komplett settings.json-utdrag som du kan lägga in i din .claude/settings.json. Community-samlingar som awesome-claude-code har ännu fler mönster.

1. Autoformattera vid sparande

json
{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Write|Edit",
      "hooks": [{
        "type": "command",
        "command": "FILE=$(jq -r '.tool_input.file_path // .tool_input.file' /dev/stdin); case \"$FILE\" in *.ts|*.tsx|*.js|*.jsx) npx prettier --write \"$FILE\" 2>/dev/null;; *.py) black \"$FILE\" 2>/dev/null;; esac; exit 0"
      }]
    }]
  }
}

Den här aktiveras efter varje Write eller Edit, extraherar filsökvägen från stdin JSON och kör lämplig formatterare. exit 0 i slutet säkerställer att hooken aldrig blockerar -- formatteringsfel bör inte stoppa Claude.

Proffstips: Lägg till *.go med gofmt och *.rs med rustfmt om du jobbar med flera språk.

2. Blockera skrivningar till skyddade filer

json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Write|Edit",
      "if": "tool_input.file_path matches '(\\.env|\\.env\\.local|package-lock\\.json|yarn\\.lock|pnpm-lock\\.yaml)'",
      "hooks": [{
        "type": "command",
        "command": "echo '{\"message\": \"BLOCKED: This file is protected. Edit it manually.\"}' && exit 2"
      }]
    }]
  }
}

Exit-kod 2 blockerar åtgärden och skickar JSON-meddelandet tillbaka till Claude. Claude ser feedbacken och justerar -- vanligtvis meddelar den dig att den ville ändra filen och ber dig göra det manuellt. if-fältet förhindrar att detta aktiveras vid varje enskilt Write.

3. Skrivbordsnotis vid avslut

json
{
  "hooks": {
    "Notification": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "MSG=$(jq -r '.message // \"Claude Code task finished\"' /dev/stdin); if [ \"$(uname)\" = 'Darwin' ]; then osascript -e \"display notification \\\"$MSG\\\" with title \\\"Claude Code\\\"\"; else notify-send 'Claude Code' \"$MSG\"; fi; exit 0"
      }]
    }]
  }
}

Fungerar på macOS (osascript) och Linux (notify-send). Den tomma matcharen innebär att den aktiveras vid alla notiser. Det här är genuint användbart när du startar en lång uppgift och byter till ett annat fönster.

4. Kontextinjicering vid sessionsstart

json
{
  "hooks": {
    "SessionStart": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "echo '{\"message\": \"Project: '\"$(basename $(pwd))\"' | Branch: '\"$(git branch --show-current 2>/dev/null || echo none)\"' | Last commit: '\"$(git log --oneline -1 2>/dev/null || echo none)\"'\"}'; exit 0"
      }]
    }]
  }
}

Det här injicerar aktuellt projektnamn, Git-gren och senaste commit i varje session. Claude tar emot den här kontexten automatiskt -- du behöver inte berätta för den vilken gren du är på.

5. Kör tester automatiskt efter kodändringar

json
{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Write|Edit",
      "if": "tool_input.file_path matches '\\.(ts|tsx|js|jsx|py)$'",
      "hooks": [{
        "type": "command",
        "command": "FILE=$(jq -r '.tool_input.file_path' /dev/stdin); TEST_FILE=$(echo \"$FILE\" | sed 's/\\.[^.]*$/.test&/'); if [ -f \"$TEST_FILE\" ]; then npx jest \"$TEST_FILE\" --no-coverage 2>&1 | tail -5; fi; exit 0",
        "timeout": 30000
      }]
    }]
  }
}

Om en matchande testfil finns körs den automatiskt efter att Claude redigerat källkoden. tail -5 håller utdatan koncis och timeout förhindrar uppsvällda testsviter. Det här passar bra med ett AI-drivet kodgranskningsarbetsflöde.

6. Grensskydd (avancerat)

json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "if": "tool_input.command matches 'git push.*(main|master|production)'",
      "hooks": [{
        "type": "command",
        "command": "echo '{\"message\": \"BLOCKED: Direct push to protected branch. Use a feature branch and open a PR.\"}' && exit 2"
      }]
    }]
  }
}

Det här blockerar alla git push som riktar sig mot grenarna main, master eller production. Claude får feedbacken och föreslår att skapa en feature-gren istället.

7. Säkerhetsrevisionsloggning (avancerat)

json
{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "INPUT=$(cat /dev/stdin); CMD=$(echo \"$INPUT\" | jq -r '.tool_input.command'); echo \"[$(date -u +%Y-%m-%dT%H:%M:%SZ)] BASH: $CMD\" >> .claude/audit.log; exit 0"
      }]
    }]
  }
}

Loggar varje Bash-kommando som Claude kör till en revisionsfil med en UTC-tidsstämpel. Ovärderligt för säkerhetsgranskningar och för att förstå vad Claude faktiskt gjorde under en session. Håll .claude/audit.log i din .gitignore.

Hooks vs MCP vs Skills vs CLAUDE.md: När ska du använda vad?

Använd hooks för deterministisk automatisering som alltid måste köras (formattering, blockering, notiser). Använd MCP för att ge Claude tillgång till externa verktyg och data. Använd Skills för återanvändbara promptpaket. Använd CLAUDE.md för beteendestyrning och projektkontexten. Hooks är garanterade; allt annat är probabilistiskt. Det är den enstaka viktigaste distinktionen, och jag återkommer ständigt till den när jag rådger team.

Beslutsmatrisen

MekanismDeterministisk?När den körsBäst förExempel
HooksJaAutomatiskt vid livscykelhändelserTillämpning, automatisering, notiserAutoformattera, blockera filskrivningar
MCPNej (Claude bestämmer)När Claude anropar MCP-verktygetNya funktioner, extern dataåtkomstFråga en databas, sök i Notion
SkillsNej (användaren utlöser)När användaren anropar ett snedstreck-kommandoÅteranvändbara instruktionsuppsättningar/review för kodgranskningsarbetsflöde
CLAUDE.mdNej (vägledning)Läses vid sessionsstartProjektkontexten, kodningsstandarder"Använd Tailwind, skriv tester för all ny kod"

För en djupdykning i MCP, kolla vår MCP-guide. Om du kommer från Cursor är Cursors regelssystem ungefär analogt med CLAUDE.md -- men Cursor har inget som liknar hooks.

När de överlappar (och hur du väljer)

Här är flödesschemat jag använder:

  • "Måste det här hända varje enskild gång, utan undantag?" -- Hook. Formattera kod, blockera skyddade filer, skicka notiser. Noll tvetydighet.
  • "Behöver Claude en ny FÖRMÅGA som den inte har?" -- MCP-server. Kom åt en databas, anropa ett API, sök externa dokument.
  • "Vill jag ha återanvändbara INSTRUKTIONER för ett specifikt arbetsflöde?" -- Skill (snedstreck-kommando). Kodgranskningsmallar, driftsättningscheck-listor.
  • "Vill jag forma Claudes BETEENDE i det här projektet?" -- CLAUDE.md. Kodningsstandarder, arkitekturbeslut, föredragna bibliotek.

Verkliga exempel som klargör gränsen:

  • "Formattera alltid med Prettier" = Hook (det måste hända varje gång)
  • "Använd Prettier för formattering" i CLAUDE.md = Vägledning (Claude kan glömma det)
  • "Sök i våra företagsdokument" = MCP (ny förmåga)
  • "Följ vår stilguide vid kodgranskning" = Skill eller CLAUDE.md

Som beskrivs i Anthropics pluginannouncement är hooks en del av ett bredare plugin-ekosystem som även inkluderar MCP och Skills. De är designade för att komplettera varandra, inte konkurrera.

Startpaketet: Färdig Claude Code Hooks-konfiguration för vilket projekt som helst

En startkonfiguration för Claude Code-hooks bör inkludera autoformattering vid filredigering, notis vid uppgiftsavslut, filskydd för känsliga filer, kontextinjicering vid sessionsstart och en stop-hook för städning. Det här är exakt den konfiguration jag lägger in i varje nytt projekt -- anpassad för stacken, men strukturen är densamma.

Konfigurationen

json
{
  "hooks": {
    "SessionStart": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "echo '{\"message\": \"Project: '\"$(basename $(pwd))\"' | Branch: '\"$(git branch --show-current 2>/dev/null)\"' | Node: '\"$(node -v 2>/dev/null)\"'\"}'; exit 0"
      }]
    }],
    "PreToolUse": [{
      "matcher": "Write|Edit",
      "if": "tool_input.file_path matches '(\\.env|\\.env\\..+|.*lock\\.json|.*lock\\.yaml)'",
      "hooks": [{
        "type": "command",
        "command": "echo '{\"message\": \"Protected file. Edit manually.\"}' && exit 2"
      }]
    }],
    "PostToolUse": [{
      "matcher": "Write|Edit",
      "hooks": [{
        "type": "command",
        "command": "FILE=$(jq -r '.tool_input.file_path // .tool_input.file' /dev/stdin); case \"$FILE\" in *.ts|*.tsx|*.js|*.jsx) npx prettier --write \"$FILE\" 2>/dev/null;; *.py) black \"$FILE\" 2>/dev/null;; *.go) gofmt -w \"$FILE\" 2>/dev/null;; esac; exit 0"
      }]
    }],
    "Notification": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "MSG=$(jq -r '.message // \"Done\"' /dev/stdin); osascript -e \"display notification \\\"$MSG\\\" with title \\\"Claude Code\\\"\" 2>/dev/null || notify-send 'Claude Code' \"$MSG\" 2>/dev/null; exit 0"
      }]
    }],
    "Stop": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "echo '[STOP] '\"$(date +%H:%M:%S)\"'' >> .claude/session.log; exit 0"
      }]
    }]
  }
}

Hur du anpassar för din stack

StackFormatteringskommandoTestkommandoBevakade filändelser
Node/TypeScriptnpx prettier --writenpx jest --no-coverage.ts, .tsx, .js, .jsx
Pythonblackpytest -x.py
Gogofmt -wgo test ./....go
Rustrustfmtcargo test.rs

Byt ut format- och testkommandona i konfigurationen ovan för att matcha din stack. Strukturen är identisk.

Verifiera att dina hooks fungerar

Tre sätt att bekräfta att hooks är aktiva:

  1. /hooks-kommandot -- Skriv /hooks i Claude Code för att se alla registrerade hooks, deras matchare och deras status.
  2. Transkriptinspektion -- Efter att en hook aktiveras, kontrollera sessionstranskriptet. Hook-körningar visas med deras utdata och exit-kod.
  3. Snabb av/på-knapp -- Lägg till "disableAllHooks": true i din settings.json för att tillfälligt inaktivera alla hooks utan att radera konfigurationen. Ta bort det (eller sätt det till false) för att återaktivera.

CI/CD-integration: Claude Code Hooks i headless-läge

Claude Code hooks fungerar i headless-läge (claude -p) med vissa skillnader: Notification-hooks aktiveras fortfarande men du bör omdirigera till loggning istället för skrivbordsvarningar. PreToolUse-hooks med exit-kod 2 kan pausa headless-sessioner för mänsklig granskning. GitHub Actions använder anthropics/claude-code-action@v1 tillsammans med hooks för automatiserade arbetsflöden.

Beteende i headless-läge

Hook-händelseInteraktivt lägeHeadless-läge (-p)CI-rekommendation
PreToolUse (exit 2)Blockerar, visar meddelandePausar för --resumeAnvänd för obligatoriska mänskliga godkännanden
PostToolUseKörs normaltKörs normaltBehåll formatterare och loggare
NotificationSkrivbordsvarningAktiveras fortfarande (inget UI)Omdirigera till loggfil eller Slack-webhook
StopKör städningKör städningBra för CI-artefaktinsamling
SessionStartInjicerar kontextInjicerar kontextInjicera CI-miljövariabler

Den stora överraskningen i headless-läge: PreToolUse-hooks som avslutar med kod 2 misslyckas inte tyst. De pausar sessionen och låter dig återuppta med --resume, vilket ger dig ett mänskligt-i-loopen-mönster för CI-pipelines.

GitHub Actions-integration

Här är ett minimalt GitHub Actions-arbetsflöde som använder Claude Code med hooks. Som dokumenterat i den officiella GitHub Actions-guiden:

yaml
- name: Run Claude Code
  uses: anthropics/claude-code-action@v1
  with:
    prompt: "Review this PR and suggest improvements"
    allowed_tools: "Read,Grep,Glob"
  env:
    ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}

Dina .claude/settings.json-hooks följer med repot, så de aktiveras i CI precis som lokalt. Se bara till att hooks som förlitar sig på skrivbordsspecifika verktyg (som osascript) har fallbacks eller villkor.

Team-hookhantering

Ett mönster som fungerar bra för team:

  • .claude/settings.json (committat) -- Team-delade hooks: filskydd, formatterare, grensskydd. Alla i teamet får dessa.
  • .claude/settings.local.json (gitignorerad) -- Personliga hooks: notiseringsinställningar, anpassad loggning, experimentella hooks.
  • ~/.claude/settings.json (användareglobal) -- Dina standardinställningar för alla projekt: notiseringsstil, personliga formatteringsinställningar.

Det här speglar hur .editorconfig (committat) och lokala IDE-inställningar (personliga) fungerar. Som noterat av Angelo Limas CI/CD-guide ser team som standardiserar på delade hooks färre "fungerar på min maskin"-problem med Claude Code.

Felsökning av Claude Code Hooks och vanliga misstag

Vanliga Claude Code hooks-problem inkluderar hooks som inte aktiveras (kontrollera matcharstav och settings.json-plats), hooks som körs men inte blockerar (fel exit-kod -- använd 2, inte 1), oändliga loopar (Stop-hook utlöser sig själv) och långsam start (för många synkrona hooks). Det vanligaste misstaget jag ser är exit-kodsförvirring -- utvecklare använder exit 1 när de menar exit 2.

Hook aktiveras inte

Symptom: Du lade till en hook men ingenting händer när händelsen inträffar.

Åtgärder:

  • Matcharstavfel -- Matchare är skiftlägeskänsliga. "write" matchar inte Write-verktyget. Kontrollera exakta verktygsnamn med /hooks.
  • Fel inställningsfil -- Hooks i ~/.claude/settings.json visas inte i /hooks-utdatan för projektomfånget. Prova .claude/settings.json i projektroten.
  • JSON-syntaxfel -- Ett extra komma eller en saknad klammer inaktiverar tyst hela hooks-konfigurationen. Kör din settings.json genom jq . för att validera.
  • disableAllHooks: true -- Kontrollera om någon (eller en tidigare felsökningssession) lämnade den här flaggan på.

Hook körs men blockerar inte

Symptom: Din PreToolUse-hook körs, men åtgärden fortsätter ändå.

Åtgärder:

  • Fel exit-kod -- Exit-kod 1 betyder "fel" (hook misslyckades), inte "blockera." Använd exit 2 för att blockera en åtgärd. Det här snubblar nästan alla, som noterat i de officiella dokumenten.
  • Saknad stdout JSON -- För blockerande hooks, skicka ett JSON-meddelande så att Claude vet varför åtgärden blockerades: echo '{"message": "Blocked: reason"}'

Oändliga loopar

Symptom: Claude fortsätter att försöka med samma åtgärd, eller din maskin värms upp misstänkt.

Åtgärder:

  • Stop-hook utlöser åtgärder -- Om din Stop-hook skriver en fil eller kör ett kommando som får Claude att svara har du skapat en loop. Stop-hooks bör bara göra passiva saker: logga, notifiera, städa.
  • PostToolUse-hook orsakar redigeringar -- En PostToolUse-hook som modifierar en fil utlöser en ny PostToolUse-händelse. Skydda mot detta med specifika matchare eller if-fältet.

Prestandaproblem

Symptom: Claude tar märkbart längre tid att starta eller köra verktyg.

Åtgärder:

  • För många SessionStart-hooks -- Var och en körs synkront vid start. Håll dessa lätta (under 1 sekund var).
  • Tunga skript i heta sökvägar -- Hooks på PreToolUse och PostToolUse aktiveras ofta. Om ditt skript gör nätverksförfrågningar eller tung beräkning, lägg till ett timeout-fält (millisekunder) och överväg om det borde vara en HTTP-hook istället.
  • Ingen caching -- Om du kontrollerar samma sak upprepade gånger (som "är det här en skyddad gren?"), cacha resultatet i en tempfil istället för att köra Git-kommandon vid varje hook-anrop.

Vanliga frågor

Vad är Claude Code hooks och hur fungerar de?

Claude Code hooks är användardefinierade automatiseringsskript som körs vid specifika livscykelhändelser under en Claude Code-session. Du konfigurerar dem i settings.json med ett matcharmönster och en hanterare (skalkommando, HTTP-endpoint, prompt eller agent). När den matchande händelsen aktiveras körs hooken automatiskt och använder exit-koder för att kontrollera utfallet.

Hur konfigurerar jag hooks i Claude Code settings.json?

Lägg till ett "hooks"-objekt i någon av de tre konfigurationsplatserna: ~/.claude/settings.json (användareglobal), .claude/settings.json (projektdelad) eller .claude/settings.local.json (projektpersonlig). Varje händelsetyp mappar till en array av hook-definitioner med matcher, valfritt if-fält och en hooks-array som innehåller handlerobjekt med type och command eller url.

Vad är skillnaden mellan PreToolUse- och PostToolUse-hooks?

PreToolUse aktiveras innan ett verktyg körs, vilket ger dig möjligheten att blockera det med exit-kod 2. PostToolUse aktiveras efter att körningen är klar, användbart för formattering, testning eller loggning. PreToolUse är för förebyggande och grindvakter. PostToolUse är för validering och städning. Båda tar emot verktygets namn och indata som JSON via stdin.

Kan Claude Code hooks blockera farliga kommandon?

Ja. PreToolUse-hooks med exit-kod 2 blockerar vilken verktygskörning som helst. Du kan skydda känsliga filer från att skrivas, blockera skalkommandon som matchar farliga mönster som rm -rf eller git push main, och förhindra åtkomst till produktionsdatabaser. Blockeringsmeddelandet skickas tillbaka till Claude som feedback, så det kan justera sitt tillvägagångssätt.

Vilka hook-händelser finns tillgängliga i Claude Code?

Claude Code tillhandahåller 15+ händelser: PreToolUse och PostToolUse för verktygskörning, Notification för varningar, Stop för sessionsavslut, SessionStart för initialisering, UserPromptSubmit för inmatningsfiltrering, PreCompact och PostCompact för kontexthantering, och nyare händelser som ConfigChange, FileChanged, TaskCreated och PermissionDenied. Se den fullständiga referenstabellen i hook-händelsesektionen ovan.

Hur skiljer sig hooks från MCP-verktyg och Skills?

Hooks är deterministiska -- de aktiveras alltid vid matchande händelser oavsett vad Claude beslutar. MCP-verktyg utökar Claudes förmågor (databasåtkomst, API-anrop) men Claude väljer när de ska användas. Skills är återanvändbara instruktionspaket som anropas av snedstreck-kommandon. CLAUDE.md ger beteendevägledning. Använd hooks när något måste hända varje gång, MCP när Claude behöver nya förmågor.

Fungerar Claude Code hooks i headless-läge?

Ja, med förbehåll. Hooks aktiveras normalt i headless-läge (claude -p), men skrivbordsspecifika hooks som macOS-notiser behöver fallbacks. Viktigt: PreToolUse-hooks som avslutar med kod 2 kan pausa headless-sessioner för mänskligt godkännande via --resume. Det möjliggör mänskliga-i-loopen CI/CD-pipelines där vissa åtgärder kräver manuellt godkännande.

Hur många hooks är för många? Saktar hooks ner Claude Code?

Det finns ingen hård gräns, men varje synkron hook lägger till latens. SessionStart-hooks körs vid start, så håll dem snabba (under 1 sekund var). PreToolUse- och PostToolUse-hooks aktiveras vid varje matchande verktygsanrop -- tunga skript här ackumuleras snabbt. Jag rekommenderar att hålla det totala antalet hooks under 10-15, använda if-fältet för att begränsa omfånget och lägga till timeout-värden för att förhindra uppsvällda skript.

Kan jag använda hooks för att autoformattera kod med Prettier eller Black?

Ja -- det är det mest populära hook-användningsfallet. Skapa en PostToolUse-hook som matchar Write|Edit, extrahera filsökvägen från stdin JSON och kör lämplig formatterare baserat på filändelsen. Se exempel nummer ett i produktionsexemplen ovan för en komplett, klar-att-kopiera-konfiguration som hanterar TypeScript-, JavaScript- och Python-filer.

Är Claude Code hooks säkra? Vilka är säkerhetsriskerna?

Hooks körs med dina fulla användarbehörigheter -- det finns ingen sandlåda. En skadlig hook kan läsa dina SSH-nycklar, radera filer eller exfiltrera data. Använd bara hooks från betrodda källor, granska alla delade .claude/settings.json innan du accepterar dem i ditt projekt, och använd .claude/settings.local.json för personliga hooks som inte bör delas. För bredare AI-säkerhetsmönster, se vår LLM guardrails-guide.

Taggar

claude code hooksclaude codeutvecklarverktygAI-automatiseringarbetsflödesautomatiseringsettings.jsonPreToolUsePostToolUse

Dela denna artikel

Starta ditt projekt

Redo att bygga något utöver det vanliga?

Låt oss göra verklighet av din idé. Vårt team hjälper dig gärna att bygga mjukvara som gör skillnad.