---
title: "Hooks en Claude Code: automatiza y aplica reglas"
excerpt: "Los hooks ejecutan comandos en momentos clave del ciclo de vida de Claude Code. Sirven para forzar reglas que siempre deben cumplirse: formatear con Pint, correr tests o proteger archivos en tu proyecto Laravel."
date: "2026-07-14T11:00:00.000Z"
category: "Inteligencia Artificial"
tech_article: true
author:
  name: "angel cruz"
  picture: "https://angelcruzdevcdn.nyc3.cdn.digitaloceanspaces.com/images/me/angel-cruz.png"
ogImage:
  url: "/images/open-graph/og-image.png"
seo_title: "Hooks en Claude Code: guía con ejemplos (Laravel)"
seo_description: "Qué son los hooks de Claude Code, qué eventos existen y cómo configurarlos en settings.json para formatear con Pint, proteger tu .env y aplicar reglas de forma determinista."
---

**Los hooks de Claude Code son comandos de shell que se ejecutan automáticamente en puntos concretos de su ciclo de vida.** Su gran diferencia con el [CLAUDE.md](/post/claude-md-buenas-practicas) es que el hook **siempre se ejecuta**: no depende de que el modelo decida hacerlo. Por eso son la herramienta para *forzar* reglas (formatear, bloquear, validar), no solo sugerirlas.

En este artículo verás qué son, qué eventos existen y cómo configurarlos, con ejemplos aplicados a un proyecto Laravel (formatear con Pint, proteger tu `.env`).

## Por qué un hook y no una instrucción

El CLAUDE.md es guía: Claude lo lee y trata de seguirlo, pero no hay garantía. Un hook es determinista: corre como un comando del sistema en el evento que definas, decida lo que decida el modelo. Si algo **tiene** que pasar (formatear tras cada edición, no tocar ciertos archivos), va en un hook.

## Los eventos principales

Claude Code expone muchos eventos de ciclo de vida (más de treinta). Estos son los que más vas a usar:

- **`PreToolUse`**: antes de que Claude use una herramienta (puedes **bloquear** la acción).
- **`PostToolUse`**: después de usar una herramienta (ideal para formatear o lintar tras editar).
- **`UserPromptSubmit`**: cuando envías un prompt.
- **`Notification`**: cuando Claude espera tu input o permiso.
- **`SessionStart`**: al iniciar la sesión (inyectar contexto).
- **`Stop` / `SubagentStop`**: al terminar la conversación o un subagente.

## Cómo se configuran

Los hooks viven en un archivo de settings: `~/.claude/settings.json` (global), `.claude/settings.json` (del proyecto) o `.claude/settings.local.json` (local, sin commitear). La estructura es: evento → lista de entradas con un `matcher` (el patrón que decide qué herramienta dispara el hook: una cadena exacta, una lista separada por `|`, o una expresión regular) y los `hooks` a ejecutar.

Ejemplo genérico: formatear con Prettier cada vez que Claude escribe o edita un archivo. El `matcher` `Write|Edit` calza con ambas herramientas.

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          { "type": "command", "command": "npx prettier --write \"$(jq -r '.tool_input.file_path')\"" }
        ]
      }
    ]
  }
}
```

El hook recibe la información del evento como JSON por stdin: la ruta del archivo recién editado viene en **`tool_input.file_path`**, que extraes con `jq`. Por eso el comando de arriba lee esa ruta con `jq -r '.tool_input.file_path'` y se la pasa a Prettier. (No hay una variable de entorno con las rutas; en un hook de tipo `command` el dato siempre llega por stdin.)

## Hooks para un proyecto Laravel

Aquí es donde los hooks se vuelven tu control de calidad automático. Tres ejemplos concretos.

**1. Formatear con Pint tras cada edición.** En vez de recordarle a Claude que respete el estilo, lo fuerzas: cada `Write|Edit` pasa por [Pint](https://laravel.com/docs/pint).

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          { "type": "command", "command": "./vendor/bin/pint \"$(jq -r '.tool_input.file_path')\"" }
        ]
      }
    ]
  }
}
```

**2. Proteger archivos sensibles.** Un hook en `PreToolUse` puede **denegar** una edición antes de que ocurra. Aquí bloqueamos cualquier cambio a tu `.env` o a las migraciones ya versionadas. Apunta el hook a un script:

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          { "type": "command", "command": ".claude/hooks/proteger-laravel.sh" }
        ]
      }
    ]
  }
}
```

Y el script lee la ruta del archivo y decide. Para bloquear, imprime un JSON con `permissionDecision: "deny"`:

```bash
#!/usr/bin/env bash
ruta=$(jq -r '.tool_input.file_path')
if [[ "$ruta" == *".env"* || "$ruta" == *"/database/migrations/"* ]]; then
  echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Archivo protegido: edítalo tú a mano."}}'
fi
```

**3. No cerrar una tarea con los tests en rojo.** Un hook en `Stop` puede correr `php artisan test` (o PHPStan/Larastan con `./vendor/bin/phpstan`) al terminar, para que el agente no dé por hecho un trabajo que rompe la suite.

Puedes abrir `/hooks` para ver los eventos y los hooks configurados (es de solo lectura: para editarlos, tocas el JSON o le pides a Claude que lo haga). Este flujo encaja con el resto del cluster de [IA para desarrolladores Laravel](/post/ia-para-desarrolladores-laravel) y con [usar Claude Code en un proyecto Laravel real](/post/claude-code-proyecto-laravel).

## Hook, CLAUDE.md, skill o subagente

- **Hook**: enforcement determinista en un evento fijo.
- **[CLAUDE.md](/post/claude-md-buenas-practicas)**: guía persistente que el modelo intenta seguir.
- **Skill**: procedimiento que se carga bajo demanda.
- **[Subagente](/post/subagentes-claude-code)**: tarea en un contexto aislado.

Para ver cómo se combinan todos, revisa la [guía de Claude Code](/post/guia-claude-code).

## Preguntas frecuentes

### ¿Qué son los hooks en Claude Code?

Comandos de shell que Claude Code ejecuta automáticamente en eventos de su ciclo de vida (antes/después de usar una herramienta, al notificar, al iniciar sesión, etc.) para automatizar tareas y aplicar reglas de forma determinista.

### ¿Dónde se configuran los hooks?

En un archivo de settings (`~/.claude/settings.json`, `.claude/settings.json` del proyecto o `.claude/settings.local.json`), dentro de un bloque `hooks`, agrupados por evento, con un `matcher` y los comandos a ejecutar.

### ¿Un hook puede impedir una acción de Claude?

Sí. Un hook en `PreToolUse` puede denegar el uso de una herramienta antes de que ocurra: imprime un JSON con `permissionDecision: "deny"` (o termina con código de salida 2). Es la forma de proteger archivos como tu `.env`.

### ¿Cómo formateo con Pint automáticamente?

Con un hook `PostToolUse` (matcher `Write|Edit`) que corra Pint sobre el archivo recién editado. La ruta llega en el JSON del evento por stdin, así que la extraes con `jq`: `./vendor/bin/pint "$(jq -r '.tool_input.file_path')"`.

### ¿Cuándo uso un hook en vez del CLAUDE.md?

Cuando algo debe ocurrir siempre en un momento exacto. El CLAUDE.md es guía (puede no cumplirse); el hook es enforcement.

---

## Sitemap

Índice completo del sitio: [/sitemap.md](https://www.angelcruz.dev/sitemap.md)

Canónico HTML: [https://www.angelcruz.dev/post/hooks-claude-code](https://www.angelcruz.dev/post/hooks-claude-code)
