Los 2 hooks de Claude Code que uso (y los que borré)
Dos hooks que de verdad valen la pena: formatear al editar y frenar antes de un comando destructivo. Snippets listos para pegar.
- #claude-code
- #hooks
- #seguridad
Un hook en Claude Code es un comando que se dispara solo cuando pasa algo en tu sesión: al terminar de editar un archivo, antes de ejecutar un comando, al parar el agente. No lo escribes tú, no es un slash. Y ahí está el lío: el 90% de los que la gente copia de repos ni saben qué corren. Yo solo dejo encendidos dos. Aquí los tienes, con el porqué y los que dejaría fuera.
Cómo se montan (sintaxis real)
Los hooks viven en tu settings.json de Claude Code (~/.claude/settings.json para todo, o el .claude/settings.json del proyecto). La estructura es siempre la misma: el evento → un matcher (sobre qué herramienta dispara) → la lista de comandos.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "tu-comando-aquí"
}
]
}
]
}
}
Los eventos que usan los dos hooks de abajo:
PostToolUse— salta después de que una herramienta termina. Elmatcherfiltra por nombre de herramienta (Edit,Write,Bash…).PreToolUse— salta antes de ejecutar la herramienta. Si su comando sale con código distinto de 0, bloquea la acción. Este es el que sirve de freno.
Verifica los nombres exactos contra la doc oficial de tu versión de Claude Code (
docs.claude.com→ Claude Code → Hooks). La sintaxis de abajo es la que uso en mi config real, pero las claves de eventos pueden ajustarse entre versiones.
Hook 1 — Formatea y revisa al terminar de editar
El porqué: me ahorra el “ah, se me olvidó pasar el formateador”. En cuanto Claude toca un archivo, se formatea solo. Gana tiempo y no puede romper nada: riesgo cero.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx prettier --write \"$CLAUDE_FILE_PATHS\" 2>/dev/null; true"
}
]
}
]
}
}
- Cambia
npx prettier --writepor tu formateador real:ruff format,gofmt -w,cargo fmt, lo que uses. $CLAUDE_FILE_PATHSlo expone Claude Code con los archivos que acaba de tocar. Si tu versión no lo expone, formatea el proyecto entero (npx prettier --write .) — más lento, pero funciona.- El
; truedel final evita que un fallo del formateador marque la edición como errónea. Este hook no debe bloquear: solo limpia.
Hook 2 — Te frena antes de un comando destructivo
El porqué: este es el que de verdad te salva. Un rm -rf mal dado, un push directo a la rama buena… y se te va el día. Este hook mira el comando antes de ejecutarlo y, si huele a destructivo, lo para en seco.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/Users/tu-usuario/.claude/freno.sh"
}
]
}
]
}
}
Y el script freno.sh (dale permisos con chmod +x freno.sh):
#!/usr/bin/env bash
# Lee el comando que Claude quiere ejecutar (llega como JSON por stdin)
cmd=$(jq -r '.tool_input.command // empty')
# Patrones que NO quiero que se ejecuten sin que yo me entere
if echo "$cmd" | grep -Eq 'rm -rf|git push.*\bmain\b|git reset --hard|git push --force|DROP TABLE'; then
echo "BLOQUEADO por tu hook: comando destructivo -> $cmd" >&2
exit 2 # exit 2 en PreToolUse = cancela la acción
fi
exit 0 # cualquier otra cosa pasa normal
- La clave es el
exit 2: enPreToolUse, un código de salida 2 cancela la herramienta y le devuelve el mensaje a Claude. Unexit 0deja pasar. - Ajusta los patrones del
grepa lo que a ti te fría el día: borrar una migración, ungit clean -fd, lo que sea. - Requiere
jqinstalado (brew install jq). Elcommandque llega por stdin es JSON; ahí estátool_input.command.
Qué dejaría fuera (y por qué)
No es por vago, es por criterio. Estos los borré:
- Hooks que ejecutan acciones solas sin que tú revises. Un hook que hace commit, despliega o borra cosas por su cuenta corre con tus permisos y sin tu mirada. Si falla, te enteras tarde.
- Hooks que saltan en cada paso. Un
PostToolUseque se dispara en cada lectura, cada edición, cada bash… te llena la sesión de ruido y te ralentiza más de lo que automatiza. - Los “copia este repo y monta veinte”. Pegar un bloque de hooks de un repo random sin leer qué hace cada
commandes darle el volante a algo que no miras. No sabes qué corren con tus credenciales. - Notificaciones de adorno. Un sonido cada vez que Claude para está bien una semana; luego es ruido que ignoras. Si no cambia una decisión tuya, sobra.
Nota de seguridad — revisa el hook ANTES de confiarle ejecución
Un hook se ejecuta solo, con tus permisos, sin pedirte nada. Es exactamente como ejecutar tú ese comando a mano. Antes de pegar cualquiera:
- Lee el
commandentero. ¿Qué binario lanza? ¿Toca archivos, red, credenciales? Si no lo entiendes línea a línea, no lo montes. - Desconfía de
curl … | bash,evaly rutas a scripts que no escribiste tú. Eso es ejecución remota a ciegas. - Empieza en un proyecto de juguete. Monta el hook, mira qué hace en una sesión sin nada importante, y solo luego pásalo a tu config global.
- Prefiere hooks que avisan o bloquean (no que actúan). Un hook que te frena o te formatea es seguro. Uno que despliega, borra o publica solo, no — eso quieres mirarlo tú.
Regla de oro
Un hook bueno te quita una tarea aburrida o te salva de un destrozo. Si hace algo importante por su cuenta y tú no lo miras, no es automatizar: es darle el volante a algo que no controlas. Dos hooks bien puestos baten a veinte copiados a ciegas.
Sígueme para más trucos con Claude Code e IA → @pabloinpublic
Waitlist de la comunidad → pabloinpublic.com
Comunidad PabloInPublic
Todo lo que necesitas para lanzar tu proyecto en público con IA, conocer gente que está en la misma, y no rendirte por el camino.
Waitlist abierta
- Acceso completo a mis directos y tutoriales
- Plantillas de CLAUDE.md y prompts que uso a diario
- Revisiones semanales de tu código y tu contenido
- Canal privado para dudas y feedback
- Todos los recursos que voy publicando, en un solo sitio
o sígueme en Instagram → @pabloinpublic