
Claude Code Hooks: Den komplette guiden (2026)
En skill kan bli ignorert. Det er ikke en svakhet ved skills, det er hele designet: Claude leser beskrivelsen, avgjør om gjeldende oppgave matcher, og laster kroppen bare hvis den tror det. Det meste av tiden er den vurderingen riktig. Noen ganger er den ikke det, og oppgaven der det betyr mest, kodegjennomgangen rett før en sammenslåing, loggoppføringen som skal eksistere uansett, er nettopp oppgaven der «sannsynligvis» ikke er godt nok.
Hooks er den andre halvdelen av Claude Code. En hook er en skallkommando harnesset kjører når en spesifikk hendelse utløses, uansett om noen skill ville tenkt på det. Ingen modellvurdering sitter mellom hendelsen og kommandoen. Den kjører, hver gang, i rekkefølge, og exit-koden dens kan til og med stoppe Claude tvert. Har du noen gang ønsket å si «formater alltid denne filen etter en redigering» eller «la aldri Claude røre denne mappen», er en hook verktøyet bygget for den setningen.
Denne guiden dekker hva hooks er, settings.json-skjemaet bak dem, seks oppskrifter du kan lime inn i dag, hvordan hooks og skills jobber sammen, og feilmodusene som spiser en ettermiddag hvis du ikke vet du skal se etter dem.
Hva en hook faktisk er
Claude Code utløser navngitte hendelser under en økt: før et verktøy kjører, etter at et verktøy kjører, når Claude er ferdig med å svare, når en varsling ville blitt vist. En hook binder en skallkommando til én av disse hendelsene, valgfritt filtrert til spesifikke verktøy. Harnesset kjører kommandoen din, gir den kontekst som JSON på stdin, og leser deretter exit-koden for å avgjøre hva som skjer videre.
Hendelsene du kommer til å bruke mest:
- PreToolUse — utløses før et verktøykall utføres. En hook her kan blokkere kallet fullstendig.
- PostToolUse — utløses etter at et verktøykall er ferdig. Bra for formatering, testing eller logging av hva som nettopp skjedde.
- Stop — utløses når Claude er ferdig med sin tur og skal til å gi kontrollen tilbake til deg.
- Notification — utløses når Claude Code ville vist deg en systemvarsling (tillatelsesforespørsler, ledig-prompter).
- UserPromptSubmit — utløses når du sender en melding, før Claude ser den.
Det er mekanismen. Grunnen til at den betyr noe, er garantien den gir deg som en skill strukturelt ikke kan.
Mentalmodellen: deterministisk vs skjønnsmessig
Dette er den ene ideen verdt å huske hvis du ikke husker noe annet fra denne guiden.
En skill er skjønnsmessig. Claude leser beskrivelsen ved starten av en økt, og avgjør senere, basert på forespørselen din, om den skal laste og følge den. Gode skills trigges pålitelig, men «pålitelig» er fortsatt en sannsynlighet, ikke en garanti. Claude kan mistolke en tvetydig prompt, eller to skills kan ha overlappende beskrivelser som forvirrer matchingen, en feilmodus vi dekker mer inngående i vår guide til hvorfor skills ikke trigges.
En hook er deterministisk. Den spør ikke Claude om den skal kjøre. Den leser ikke en beskrivelse og vurderer relevans. Harnesset ser hendelsen, og kommandoen kjører, punktum. Hvis hendelsen er PostToolUse på Edit-verktøyet, kjører formatereren din etter hver redigering, inkludert den Claude gjorde mens den tenkte på noe helt annet.
Den forskjellen kartlegges direkte til når du bør gripe til hvilken:
| Skill | Hook | |
|---|---|---|
| Kjører når | Claude vurderer det relevant | Hver gang hendelsen utløses |
| Kan hoppes over | Ja, av en dårlig match eller opptatt kontekst | Nei |
| Best for | Vurdering, struktur, «hvordan gjøre X godt» | Håndhevelse, «X må alltid skje» |
| Feilmodus | Stille ikke-trigging | Stille dårlig exit-kode, eller blokkering av alt |
Hvis setningen du håndhever starter med «Claude bør alltid...» eller «Claude må aldri...», vil du ha en hook. Hvis den starter med «når Claude gjør X, bør den nærme seg det som...», vil du ha en skill. Å formatere kode etter hver redigering er en hook; å skrive idiomatisk Python er en skill. Å blokkere commits til main er en hook; å strukturere en god commit-melding er en skill.
Anatomien til en hook i settings.json
Hooks lever under hooks-nøkkelen i .claude/settings.json (prosjektnivå) eller ~/.claude/settings.json (brukernivå), en annen fil enn CLAUDE.md og verdt å ikke forveksle: CLAUDE.md er prosa Claude leser, settings.json er konfig harnesset utfører. Har du ikke satt opp noen av delene ennå, dekker vår CLAUDE.md-guide og vår fulle oppsettgjennomgang resten av stacken denne filen lever inne i. Her er et minimalt, men komplett hooks-eksempel, kommentert:
{
"hooks": {
// The event name — PreToolUse, PostToolUse, Stop, Notification, etc.
"PostToolUse": [
{
// matcher filters which tool calls trigger this hook.
// Omit it (or use "*") to match every tool.
"matcher": "Edit|Write",
"hooks": [
{
// "command" is currently the only hook type.
"type": "command",
// The shell command to run. Receives event JSON on stdin.
"command": "npx prettier --write \"$(echo $CLAUDE_TOOL_INPUT | jq -r .file_path)\"",
// Optional: kill the command if it hangs.
"timeout": 15
}
]
}
]
}
}
Noen ting verdt å påpeke fordi de snubler folk:
matcher-feltet opererer på verktøynavnet, ikke på filstier eller innhold. "Edit|Write" matcher Edit- og Write-verktøyene; "Bash" matcher skallkall. Trenger du å filtrere på filsti eller kommandoinnhold, gjør det inne i skriptet ditt ved å lese JSON-nyttelasten, ikke i matcheren.
Hver hendelsesnøkkel holder en array av matcher-blokker, og hver matcher-blokk holder en array av hook-kommandoer, så du kan feste flere kommandoer til én matcher, eller én kommando til flere matchere, uten å duplisere konfig.
Kommandoen mottar hendelsesnyttelasten som JSON på stdin: verktøynavn, verktøyinput, og for PostToolUse, verktøyets resultat. En hook som virker på den spesifikke filen som redigeres, leser den JSON-en i stedet for å anta at skallets arbeidsmappe forteller hele historien.
Exit-koder bærer mening. Exit 0 betyr «greit, fortsett». En ikke-null exit på en PreToolUse-hook blokkerer verktøykallet og gir stderr tilbake til Claude som en begrunnelse. En ikke-null exit på PostToolUse blir bare logget; verktøyet har allerede kjørt, så det er ingenting igjen å blokkere.
Seks oppskrifter du kan bruke i dag
Disse er bevisst smale. Kopier blokken, juster kommandoen, og bekreft at den gjør det du forventer på en engangsfil før du stoler på den i ekte arbeid.
1. Autoformater etter hver redigering
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "cd \"$CLAUDE_PROJECT_DIR\" && npx prettier --write . --ignore-unknown"
}
]
}
]
}
}
Kjører Prettier etter enhver redigering eller skriving. For store repoer, bytt ut den blanke . med en sti utledet fra hookens JSON-input slik at du bare formaterer den berørte filen.
2. Blokker redigeringer av beskyttede stier
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "python3 .claude/hooks/guard_paths.py"
}
]
}
]
}
}
guard_paths.py leser filstien fra stdin-JSON, sjekker den mot en nektliste (migrations/, .env, infra/prod/), og avslutter med 1 og en melding på stderr hvis den matcher. Dette er det nærmeste en hard tillatelsesgrense Claude Code har.
3. Kjør tester etter kildeendringer
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "cd \"$CLAUDE_PROJECT_DIR\" && npm test -- --onlyChanged --silent"
}
]
}
]
}
}
Gir Claude et umiddelbart signal når en redigering ødelegger en test, i stedet for å vente på at du merker det ved gjennomgang. Hold testkommandoen smal (--onlyChanged, en rask delmengde) ellers blir dette oppskrift seks i «når ikke»-seksjonen under.
4. Skrivebordsvarsling når Claude er ferdig
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude finished\" with title \"Claude Code\"'"
}
]
}
]
}
}
macOS-spesifikk (bytt til notify-send på Linux). Nyttig når du begynner å kjøre lengre autonome runder og slutter å følge med i terminalen hele tiden.
5. Logg hver bash-kommando
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.command' >> \"$CLAUDE_PROJECT_DIR/.claude/bash-history.log\""
}
]
}
]
}
}
En revisjonsspor som ikke avhenger av at du husker å sjekke transkriptet. På en delt maskin eller et repo med et samsvarskrav, er dette nær obligatorisk.
6. Lint-port før commit
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/block_bad_commit.sh"
}
]
}
]
}
}
block_bad_commit.sh leser stdin, sjekker om kommandoen er en git commit, og kjører i så fall linteren din først, og avslutter med ikke-null hvis den feiler. Det gjør «vær så snill å lint før du committer» fra en forespørsel Claude kan glemme til en regel den ikke kan komme forbi.
GRATIS STARTPAKKE
Setter du opp hooks sammen med dine første skills? Vi sender våre 3 høyest scorede skills pluss installasjonssjekklisten vi kjører før hver SkillProof-test. Gratis.
Hent den gratis startpakkenHooks og skills sammen
De konkurrerer ikke; de beste oppsettene bruker begge for det hver er god på. Et gjennomarbeidet eksempel: et team vi testet ville ha hver commit skrevet i deres husstil, imperativ form, et avgrenset prefiks, en kropp som forklarer hvorfor, og de ville også ha commits blokkert hvis diffen berørte en databasemigrasjon uten en matchende tilbakerullingsfil.
Stildelen er vurdering. Hva som teller som en god «hvorfor» varierer etter endring, og det finnes ikke noe skript som pålitelig skriver god prosa. Det er en skills jobb: noe som Git Workflow Coach lastet når Claude er i ferd med å committe, som lærer strukturen og gir eksempler på god versus lat commit-melding. Claude leser den, bruker vurdering, og skriver en melding som passer mønsteret uten å være en mal fylt ut. Hvis teamet også kjører streng rød-grønn-refaktor, er Test-Driven Development samme type vurdering-ikke-lov-tilføyelse: den former hvordan Claude nærmer seg arbeidet, noe en hook ikke kan gjøre.
Migrasjonsregelen er ikke vurdering, den er lov: enten finnes tilbakerullingsfilen eller den gjør ikke det, og teamet ville ikke ha «Claude bestemte at denne ikke trengte det» som et alternativ. Det er PreToolUse-hooken fra oppskrift seks, tilpasset til å sjekke etter den parede filen i stedet for å kjøre en linter, og blokkerer git commit-kallet fullstendig hvis den mangler.
Kjør dem sammen, og du får en god commit-melding som også er garantert å bestå migrasjonssjekken, fordi skillen håndterer delen som trenger en hjerne og hooken håndterer delen som trenger en vegg. Ingen av dem erstatter den andre. Skillen kan ikke garantere samsvar, og en hook som skriver «fix: various changes» på hver commit ville vært ubrukelig. Vår side med beste kodeskills rangerer vurderingssiden av denne paringen etter testet score, hvis du velger en første skill å kjøre sammen med hooksene dine.
Feilsøking av hooks
Hooks feiler stille oftere enn de feiler høylytt. Det som som regel går galt:
Sitering. Hook-kommandoer er skallstrenger inne i JSON-strenger, så et " som ikke er escapet, ødelegger JSON-parsingen før kommandoen din noensinne kjører. Er du i tvil, legg den faktiske logikken i en skriptfil og la hook-kommandoen bare kalle den (bash .claude/hooks/my-hook.sh) i stedet for å skrive inn en kompleks énlinjer.
Exit-koder som ikke betyr det du tror. Et hook-skript som treffer en urelatert feil (manglende avhengighet, nektet tillatelse) avslutter med ikke-null på samme måte som en hook som bevisst vil blokkere. Hvis en PreToolUse-hook begynner å blokkere hvert verktøykall og du ikke skrev den til å være så streng, sjekk om skriptet faktisk feiler i stedet for å vurdere.
PATH-antagelser. Hooks kjører i et skallmiljø som kanskje ikke matcher din interaktive terminal. En kommando som fungerer fint når du skriver den selv, kan feile inne i en hook fordi nvm, et virtuelt miljø, eller et verktøy installert via et skall-plugin ikke er på PATH i den konteksten. Bruk absolutte stier til binærfiler, eller kilde det riktige miljøet øverst i skriptet.
Stille stdin-antagelser. Hvis skriptet ditt forventer JSON på stdin og ikke får det, fordi du testet det ved å kjøre det direkte i stedet for å pipe inn en eksempel-nyttelast, vil det oppføre seg annerledes under harnesset enn det gjorde i terminalen din.
Tidsavbrudd. En hook uten tidsavbrudd som henger, vil henge hele runden. Sett et eksplisitt timeout på alt som rører nettverket eller en treg underprosess.
Når du ikke skal bruke hooks
Hooks er billige å skrive og lette å overbruke. Feilmodusen er ikke at en hook gjør feil ting, det er at en hook gjør riktig ting for ofte. En PostToolUse-hook som kjører hele testsuiten din etter hver eneste redigering, gjør en femsekunders endring til en to-minutters venting, gjentatt for hver redigering i en økt som gjør tjue av dem.
Tommelfingerregelen: hvis en hooks kommando tar mer enn ett eller to sekunder, smalne matcheren, smalne hva den sjekker, eller flytt den til en sjeldnere hendelse. Test-på-hver-redigering blir test-på-fil-skriving blir test-før-commit etter hvert som sjekken blir dyrere. Match hookens kostnad med hvor ofte hendelsen utløses, og vurder om en skill, som bare laster kontekst og ikke kjører en prosess, passer bedre for alt som ikke er strengt håndhevelse.
Det er også verdt å ikke gripe til en hook for å fikse en skills triggerproblem. Hvis en skill ikke trigges når den burde, er fiksen en bedre beskrivelse, ikke en hook, siden hooks kjører skallkommandoer og ikke kan laste skill-innhold. For den feilmodusen, se hvorfor skills ikke trigges.
SKILLPROOF-PAKKE
Å pare hooks med de riktige skillsene er mesteparten av et godt Claude Code-oppsett. Developer Toolkit bunter våre høyest scorede kodeskills, forhåndssjekket for triggerkonflikter, slik at skill-halvdelen av denne paringen er gjort for deg.
Hent Developer Toolkit — $10Ofte stilte spørsmål
Bremser hooks hver eneste Claude Code-økt?
Bare hendelsene du fester dem til, og bare så lenge kommandoen din tar. En hook på PostToolUse for Edit kjører én gang per redigering; en rask formaterer merkes knapt, en full testsuite kjennes på hver redigering, som er tilfellet dekket over under når du ikke skal bruke hooks.
Kan en hook stoppe Claude fra å gjøre noe helt?
Ja, det er hva PreToolUse-hooker er til for. Avslutt med ikke-null og verktøykallet blokkeres før det kjører, med stderr som regel gitt tilbake til Claude som begrunnelsen. Det er mekanismen bak oppskrift to (beskyttede stier) og oppskrift seks (lint-port).
Hvor legger jeg hooks-konfigen min, prosjekt eller brukerinnstillinger?
Prosjektnivå (.claude/settings.json, committet) hvis den skal gjelde for alle på det kodegrunnlaget: formatering, beskyttede stier, migrasjonssjekker. Brukernivå (~/.claude/settings.json) for en personlig preferanse, som skrivebordsvarslingen i oppskrift fire.
Hva er forskjellen mellom en hook og en skill som sier «formater alltid koden»?
Hooken kjører faktisk alltid. En skill som forteller Claude å alltid formatere kode, er fortsatt en instruksjon Claude leser og bestemmer seg for å følge; det er et sterkt puff, ikke en garanti, og det konkurrerer med andre ting i konteksten om oppmerksomhet på en gitt runde. Hvis «alltid» er et krav snarere enn en preferanse, bruk en hook.
Hooken min kjører ikke i det hele tatt. Hva er det første jeg bør sjekke?
Bekreft at innstillingsfilen er gyldig JSON (et etterhengende komma eller uescapet anførselstegn kan stille deaktivere hele hooks-blokken) og at hendelsesnavnet og matcheren er stavet nøyaktig som forventet; begge skiller mellom store og små bokstaver. Deretter, sjekk om du redigerte prosjektinnstillinger mens økten leser brukerinnstillinger, eller omvendt.
★ 9.6/10 × 3
Den gratis startpakken
De 3 skillsene med våre høyeste testscorer pluss installasjonssjekklisten — oppsettet vi selv ville lagt på en fersk maskin. Gratis, på e-post.