Claude Code hooks : éviter le drift avec lint et tests
Automatise lint, tests et garde-fous avec Claude Code hooks : exemples concrets, limites et config minimale pour un repo propre.
Claude Code peut écrire vite. Très vite. Le problème, c’est qu’un repo peut dériver tout aussi vite si rien ne vérifie ce que l’agent vient de faire.
C’est là que les Claude Code hooks deviennent utiles : ils branchent des commandes, des endpoints HTTP ou des prompts LLM à des moments précis du cycle de vie de Claude Code. Résultat : tu peux lancer du lint, des tests et des garde-fous au bon moment, sans attendre qu’une CI ou qu’un humain rattrape le coup.
Le vrai sujet n’est donc pas “est-ce que Claude sait coder ?”. Le vrai sujet, c’est : est-ce que ton repo reste propre quand Claude code à ta place ?
Claude Code hooks : la brique qu’il te manquait
La doc officielle décrit les hooks comme des automatisations déclenchées à des points précis de la session Claude Code. En pratique, ça veut dire que tu peux réagir à des événements comme PreToolUse, PostToolUse, Stop, Notification, SessionStart ou ConfigChange.
Le point important : les hooks ne remplacent pas ton contexte, ils le rendent exécutable.
| Brique | Rôle | Ce que ça règle |
|---|---|---|
| CLAUDE.md | contexte de travail | conventions, commandes, structure du repo |
| Claude Code plugins | distribution | empaqueter des workflows réutilisables |
| Hooks | automatisation locale | lint, tests, protection, notifications |
Si tu veux remettre en place le contexte du repo, je te conseille de relire aussi CLAUDE.md minimal pour monorepo pnpm — template prêt à copier. Si tu veux comprendre la couche distribution, regarde Claude Code plugins : l’app store d’Anthropic.
La nuance est simple :
- CLAUDE.md dit à Claude comment travailler.
- Hooks disent à Claude ce qu’il faut vérifier pendant qu’il travaille.
- Plugins servent à partager ce paquet de règles plus largement.
C’est exactement pour ça que les hooks sont intéressants pour un repo qui vit vraiment : ils ne décorent pas le workflow, ils l’empêchent de partir en vrille.
Les 3 hooks qui valent vraiment le coup
Tu peux faire beaucoup de choses avec Claude Code hooks. Mais pour un repo sain, trois patterns couvrent déjà l’essentiel.
| Hook | Quand il se déclenche | Ce qu’il doit faire | Pourquoi c’est utile |
|---|---|---|---|
| PostToolUse | après une édition de fichier | formater / lint le fichier touché | évite le code sale avant qu’il s’accumule |
| Stop | quand la session s’arrête | lancer un test ciblé ou un smoke test | attrape les régressions tôt |
| PreToolUse | avant une opération sensible | bloquer les fichiers protégés | réduit le risque de dégâts |
1) PostToolUse : corriger tout de suite ce que Claude vient d’écrire
La doc officielle montre exactement ce pattern : un hook PostToolUse avec le matcher Edit|Write pour lancer une commande sur les fichiers modifiés. L’exemple Anthropic utilise prettier, ce qui est logique : tu veux fermer la boucle de qualité juste après l’écriture.
Le réflexe à avoir est simple :
- si Claude modifie un fichier, le hook formate ce fichier ;
- s’il touche un composant UI, le hook peut aussi lancer un lint rapide ;
- s’il change un fichier de config, le hook peut vérifier le format.
L’idée n’est pas de faire une CI miniature. L’idée est de garder le retour immédiat.
Exemple minimal :
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/format-changed-file.sh"
}
]
}
]
}
}
Et le script associé :
#!/usr/bin/env bash
set -euo pipefail
file_path="$(jq -r '.tool_input.file_path // empty')"
if [ -z "$file_path" ]; then
exit 0
fi
pnpm exec prettier --write "$file_path"
Le but est d’avoir un effet immédiat : Claude écrit, le hook nettoie.
2) Stop : lancer un test ciblé au bon moment
Le pire piège, c’est de transformer les hooks en machine à lancer une suite de tests complète à chaque micro-action. Mauvaise idée. Les hooks doivent rester rapides.
Le bon usage de Stop, c’est de lancer un test ciblé ou un smoke test quand la session se calme. Tu catches plus tôt les erreurs de logique, sans faire exploser le temps de boucle.
Dans les docs, Claude Code pousse déjà l’idée d’un hook qui exécute des tâches après changement de fichiers. Le vrai sens produit derrière ça, c’est : donne au modèle un feedback utile, mais pas paralysant.
Dans un repo sérieux, je préfère ce schéma :
PostToolUsepour le formatage rapide ;Stoppour les tests ciblés ;- CI pour la validation complète.
Exemple :
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/run-targeted-tests.sh"
}
]
}
]
}
}
Et côté script, tu restes pragmatique : tu peux lancer un test de package, un smoke test, ou un subset de ta suite.
Le point clé : les hooks servent à réduire le temps entre erreur et correction. Ils ne doivent pas te faire attendre deux minutes à chaque arrêt de session.
3) PreToolUse : protéger ce qui ne doit pas être touché
C’est le garde-fou le plus sous-estimé.
Claude Code est bon pour éditer vite. Mais dans un vrai projet, certains fichiers ne doivent pas être modifiés sans intention claire : .env, fichiers d’infra, migrations sensibles, secrets, configs de prod, docs légales.
Le pattern PreToolUse est parfait pour ça : avant l’action, tu vérifies la cible. Si elle est sensible, tu bloques.
La doc officielle donne un exemple de hook de protection de fichiers via script. C’est exactement le genre de protection qui évite un accident bête en plein refactor.
Exemple :
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh"
}
]
}
]
}
}
Et le script :
#!/usr/bin/env bash
set -euo pipefail
file_path="$(jq -r '.tool_input.file_path // empty')"
case "$file_path" in
.env|.env.*|infra/prod/*|secrets/*|prisma/migrations/*)
echo "Fichier protégé: $file_path"
exit 2
;;
esac
Le message à retenir est simple : les hooks ne servent pas qu’à accélérer le travail, ils servent aussi à limiter le blast radius.
Où mettre les hooks sans te compliquer la vie
La doc distingue plusieurs emplacements. Et c’est important, parce que le scope change selon l’endroit où tu ranges la règle.
| Emplacement | Portée | Partageable ? |
|---|---|---|
~/.claude/settings.json | tous tes projets | non |
.claude/settings.json | un projet | oui |
.claude/settings.local.json | un projet | non, gitignored |
plugins/hooks/hooks.json | si le plugin est activé | oui |
| frontmatter d’un skill ou d’un agent | pendant son exécution | oui |
Mon conseil est simple :
- commence en
.claude/settings.local.jsonsi tu testes pour toi ; - passe en
.claude/settings.jsonquand la règle devient utile à toute l’équipe ; - garde les hooks de plugin pour ce qui doit vraiment être distribué.
Cette hiérarchie évite le chaos classique : chacun invente ses propres automatisations locales, puis personne ne sait ce qui tourne vraiment.
Pourquoi c’est le bon moment pour s’y mettre
Claude Code n’est plus un petit outil de niche qu’on bidouille en local. L’écosystème s’est déjà structuré autour des extensions, des plugins et des garde-fous.
Quelques chiffres parlent d’eux-mêmes :
- le dépôt officiel
anthropics/claude-plugins-officialest à 27 063 étoiles au moment où j’écris ces lignes ; - ce repo contient 36 plugins internes maintenus par Anthropic ;
- et 15 plugins externes venant de partenaires ou de la communauté.
Autrement dit, Claude Code est en train de devenir une plateforme. Les plugins distribuent les workflows. Les hooks les font respecter localement.
C’est ça, le vrai intérêt du moment : tu n’as plus à choisir entre “agent puissant” et “repo propre”. Tu peux avoir les deux, à condition d’installer les bons garde-fous.
Les pièges à éviter
Les hooks sont puissants. Et comme d’habitude, plus c’est puissant, plus ça peut devenir bête si tu l’utilises mal.
1) Ne transforme pas les hooks en CI
Si tu lances une grosse suite de tests après chaque micro-action, tu vas juste ralentir l’agent et te dégoûter de l’outil.
Garde cette règle en tête :
- hooks = feedback rapide ;
- CI = vérité finale.
2) Ne mets pas de logique floue dans un hook
Le hook doit être déterministe. Si tu commences à y injecter trop de logique métier, tu vas créer un système impossible à déboguer.
Le bon pattern :
- un hook court ;
- un script lisible ;
- une responsabilité unique.
3) Ne rends pas le système fragile à cause d’un matcher trop large
Edit|Write est pratique, mais pas magique. Si tu l’appliques à tout sans réfléchir, tu vas déclencher des commandes inutiles sur des fichiers qui n’en ont pas besoin.
Affine les matchers dès que tu vois que le coût monte.
4) N’oublie pas le mode d’arrêt d’urgence
La doc permet aussi de désactiver les hooks quand il faut reprendre la main. C’est utile si tu testes un nouveau flux et que tu veux revenir à un comportement neutre.
Le but n’est pas d’enfermer ton équipe dans un système de règles. Le but est d’avoir des garde-fous qui rendent le quotidien meilleur.
Le setup minimal que je recommande
Si tu veux partir sans te tromper, fais juste ça :
- crée un fichier
settings.local.jsonousettings.json; - ajoute un
PostToolUsepour formater le fichier touché ; - ajoute un
Stoppour lancer un test ciblé ; - ajoute un
PreToolUsepour bloquer les fichiers sensibles ; - laisse la CI faire la validation complète.
C’est largement suffisant pour obtenir un vrai gain.
Le vrai bénéfice, ce n’est pas seulement d’automatiser trois commandes. C’est d’installer une discipline : Claude code, mais le repo garde des limites.
Ce qu’il faut retenir
- Claude Code hooks servent à exécuter des garde-fous au bon moment, pas à remplacer ton contexte.
- Le trio utile, c’est format après édition, tests à l’arrêt, protection des fichiers sensibles.
- Pour un repo sérieux, les hooks complètent CLAUDE.md et les plugins ; ils ne les remplacent pas.
Questions fréquentes
CLAUDE.md suffit-il si j’ai déjà des hooks ?
Non. CLAUDE.md donne le contexte. Les hooks appliquent les règles pendant l’exécution. Les deux se complètent.
Faut-il mettre les hooks dans le repo ?
Seulement si la règle doit être partagée. Sinon, commence en local avec settings.local.json pour éviter d’imposer des automatisations à tout le monde trop tôt.
Est-ce que je dois lancer les tests complets dans un hook ?
Non, pas par défaut. Lance un test ciblé ou un smoke test dans le hook, et garde la suite complète pour la CI.
Si tu veux comprendre la couche “contexte”, relis CLAUDE.md minimal pour monorepo pnpm — template prêt à copier. Si tu veux voir comment Anthropic commence à distribuer ces workflows à grande échelle, l’article sur Claude Code plugins : l’app store d’Anthropic complète bien celui-ci.