Claude Code Hooks: automatiza tu workflow de desarrollo
Aprende a configurar Claude Code Hooks para ejecutar comandos automáticamente en respuesta a acciones del agente. Linting, tests, notificaciones y más.
Claude Code Hooks: automatiza tu workflow de desarrollo
Los hooks de Claude Code son comandos de shell que se ejecutan automáticamente en respuesta a eventos del agente. Cuando Claude Code termina de editar un archivo, un hook puede lanzar el formatter. Cuando completa una sesión, otro hook puede correr los tests afectados. Y todo sin que tú lo pidas.
Esta guía cubre todo lo que necesitas saber para implementar hooks en tu proyecto: tipos disponibles, configuración, casos de uso reales y patrones avanzados.
Qué son los Claude Code Hooks
Los hooks son comandos que se ejecutan en puntos específicos del ciclo de vida de Claude Code. Funcionan de forma similar a los git hooks: defines qué comando ejecutar y en qué momento, y el sistema los invoca automáticamente.
Son útiles para:
- Formatear código automáticamente después de cada edición
- Validar que los cambios pasan linting antes de seguir
- Correr tests de los archivos modificados al terminar
- Enviar notificaciones cuando Claude Code completa una tarea larga
- Actualizar un archivo de log de cambios
Configuración básica: settings.json
Los hooks se configuran en .claude/settings.json dentro del repositorio:
{
"hooks": {
"EventName": [
{
"matcher": "PatrónOpcional",
"hooks": [
{
"type": "command",
"command": "tu-comando-aquí"
}
]
}
]
}
}
El matcher es opcional: si lo incluyes, el hook solo se dispara cuando la herramienta que lo generó coincide con el patrón. Si lo omites, el hook se dispara en cualquier acción del tipo de evento.
Tipos de eventos disponibles
PreToolUse
Se ejecuta antes de que Claude Code use una herramienta. Puedes usarlo para validaciones o para bloquear ciertas acciones.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "echo 'Claude va a ejecutar un comando'"
}]
}
]
}
}
PostToolUse
Se ejecuta después de que Claude Code usa una herramienta. El más común — ideal para formateo y linting.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [{
"type": "command",
"command": "npx prettier --write $CLAUDE_TOOL_INPUT_FILE_PATH"
}]
}
]
}
}
La variable de entorno $CLAUDE_TOOL_INPUT_FILE_PATH contiene la ruta del archivo que acaba de modificarse.
Stop
Se ejecuta cuando Claude Code termina una sesión o tarea. Perfecto para correr tests o enviar notificaciones.
{
"hooks": {
"Stop": [
{
"hooks": [{
"type": "command",
"command": "npm run test:changed"
}]
}
]
}
}
Notification
Se dispara cuando Claude Code genera una notificación interna (por ejemplo, cuando necesita confirmación). Útil para integrar con sistemas de alertas externos.
Variables de entorno disponibles en hooks
| Variable | Contenido |
|---|---|
$CLAUDE_TOOL_NAME | Nombre de la herramienta que disparó el evento (Edit, Bash, etc.) |
$CLAUDE_TOOL_INPUT_FILE_PATH | Ruta del archivo afectado (en eventos de edición) |
$CLAUDE_TOOL_OUTPUT | Output de la herramienta (en PostToolUse) |
$CLAUDE_SESSION_ID | ID de la sesión actual |
Casos de uso reales
1. Auto-format con Prettier después de cada edición
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [{
"type": "command",
"command": "npx prettier --write --ignore-unknown \"$CLAUDE_TOOL_INPUT_FILE_PATH\""
}]
}
]
}
}
2. Linting con Ruff (Python) en cada edición
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [{
"type": "command",
"command": "ruff check --fix \"$CLAUDE_TOOL_INPUT_FILE_PATH\" 2>/dev/null || true"
}]
}
]
}
}
El || true evita que un fallo de linting interrumpa el flujo de Claude Code.
3. Tests automáticos al terminar una sesión
{
"hooks": {
"Stop": [
{
"hooks": [{
"type": "command",
"command": "pytest tests/ -x -q 2>&1 | tail -20"
}]
}
]
}
}
4. Notificación de escritorio al completar tarea larga
{
"hooks": {
"Stop": [
{
"hooks": [{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code terminó\" with title \"DevAI\"' 2>/dev/null || notify-send 'Claude Code terminó'"
}]
}
]
}
}
Funciona en macOS (osascript) y Linux (notify-send).
5. Actualizar changelog automáticamente
{
"hooks": {
"Stop": [
{
"hooks": [{
"type": "command",
"command": "git diff --stat HEAD | head -20 >> CLAUDE_CHANGES.log"
}]
}
]
}
}
Hooks combinados: un settings.json completo
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "npx prettier --write --ignore-unknown \"$CLAUDE_TOOL_INPUT_FILE_PATH\" 2>/dev/null || true"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "npm run test:changed 2>&1 | tail -30"
},
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code terminó\" with title \"DevAI\"' 2>/dev/null || true"
}
]
}
]
}
}
Hooks vs permisos: la diferencia clave
Es importante no confundir hooks con permisos:
- Permisos (
permissions.allow): controlan qué puede hacer Claude Code sin pedir confirmación. - Hooks: comandos adicionales que tú defines y que se ejecutan como respuesta a las acciones del agente.
Los hooks corren con tus privilegios de usuario, no con los del agente. Si un hook falla, Claude Code recibe el error y puede reaccionar, pero el hook no puede bloquear una acción que ya tiene permisos para realizar.
Debugging de hooks
Si un hook no funciona como esperas:
- Prueba el comando manualmente en el terminal con las variables de entorno simuladas:
CLAUDE_TOOL_INPUT_FILE_PATH="src/main.py" bash -c 'ruff check "$CLAUDE_TOOL_INPUT_FILE_PATH"' - Añade logging: redirige el output del hook a un archivo:
"command": "tu-comando >> /tmp/claude-hooks.log 2>&1" - Usa
/doctoren Claude Code para verificar que elsettings.jsones válido.
→ Guía completa de Claude Code
→ Cómo hacer que Claude Code acepte todo automáticamente
DevAI — newsletter semanal para desarrolladores sobre Claude Code, Cursor y herramientas de IA. Suscríbete gratis.