- Los system hooks son puntos de extensión que permiten interceptar o ampliar el comportamiento de sistemas, frameworks y aplicaciones sin modificar su núcleo.
- A nivel bajo, el hooking se basa en redirigir llamadas de función o eventos del sistema, ya sea modificando binarios, tablas de importación o usando APIs oficiales del sistema operativo.
- En frameworks como React y plataformas como WordPress, los hooks se exponen como APIs de alto nivel (estado, efectos, filtros, acciones) que simplifican la reutilización y la personalización.
- Herramientas como Git también incorporan hooks para automatizar tareas y aplicar políticas, demostrando que el patrón de ganchos es transversal a múltiples tecnologías.

Los system hooks, ganchos del sistema o simplemente hooks, son uno de esos conceptos que aparecen por todas partes: en React, en WordPress, en sistemas operativos como Windows o Linux e incluso en herramientas como Git. Aunque el nombre es el mismo, el contexto cambia bastante, y eso suele provocar bastante confusión cuando empiezas a ver hooks en todos los lados.
Para aclararlo, en este artículo vamos a unir piezas: qué son los system hooks a nivel general, cómo funcionan técnicamente y cómo se aplican en distintos entornos reales (React, WordPress, Git, APIs del sistema operativo, etc.). Irás viendo que la idea base es la misma: puntos donde puedes “enganchar” tu código para modificar o extender el comportamiento de algo sin tocar su núcleo.
Qué es un system hook: idea general
En términos generales, un system hook es un mecanismo que expone puntos de extensión dentro de un programa, framework o sistema operativo, permitiendo que terceros inserten lógica propia en determinados momentos o eventos. En vez de modificar el código original, te conectas a esos puntos de enganche y el sistema llama a tu función cuando corresponde.
Desde un punto de vista más técnico, un hook puede ser:
- Una función de callback registrada en una API oficial (como en WordPress o React), que se ejecuta cuando el sistema lanza un evento.
- Un parche en memoria o en un binario que redirige una llamada de función hacia código personalizado, típico del hooking de APIs del sistema operativo.
- Un script disparado por un evento interno de una herramienta, por ejemplo, los hooks que utiliza Git en acciones como commit, push o receive.
En todos los casos, la idea es la misma: interceptar o complementar el comportamiento normal sin tener que reescribir el sistema original.
System hooks a bajo nivel: hooking de funciones y del sistema operativo
Cuando se habla de system hooks en el mundo de sistemas operativos y seguridad, el concepto se vuelve bastante más “hardcore”. Aquí hablamos de interceptar llamadas de función, modificar binarios o alterar tablas internas para redirigir la ejecución a nuestro propio código.
En este contexto, el hooking se puede aplicar en diferentes momentos:
- Antes de ejecutar la aplicación, modificando físicamente un ejecutable o una biblioteca (mediante ingeniería inversa) para que, cuando se cargue, acabe llamando a nuestro código.
- En tiempo de ejecución, inyectando código o cambiando estructuras de datos internas del proceso una vez que ya está en marcha.
Algunos mecanismos habituales de system hooks a bajo nivel son:
Modificación del ejecutable o de la tabla de importación
Un enfoque clásico de hooking consiste en editar el binario (el ejecutable o una DLL) para cambiar cómo se resuelven las llamadas a funciones:
- Localizar, con un desensamblador, el punto de entrada de una función en un módulo.
- Modificar ese código para que cargue dinámicamente otra biblioteca y ejecute funciones de esa biblioteca en su lugar, o antes/después del código original.
- Alterar la tabla de importación (IAT) o tablas similares del ejecutable para que, cuando el sistema resuelva una función importada, apunte a nuestra implementación en lugar de a la original.
Este tipo de hooking es muy usado para monitorizar, registrar o sustituir llamadas a funciones de librerías, muchas veces con fines de depuración, análisis o, en el lado oscuro, para evadir medidas de seguridad.
Hooking mediante bibliotecas de envoltura (wrappers)
Otra técnica elegante consiste en crear una biblioteca de envoltura que hace de sustituto de la biblioteca real:
- Se compila una DLL “falsa” con las mismas funciones públicas que la original.
- Cuando la aplicación la carga, en realidad está cargando la biblioteca de envoltura.
- Dentro de esa biblioteca se puede llamar a la biblioteca real, registrar parámetros, modificar resultados o incluso reemplazar completamente la lógica.
La ventaja es que resulta menos sospechoso y más fácil de mantener, y se puede aplicar en procesos propios o, con inyección de DLL, en procesos de terceros.
Hooks proporcionados por el propio sistema operativo
Muchos sistemas operativos proporcionan APIs oficiales para insertar hooks de eventos sin tener que recurrir a ingeniería inversa dura:
- Windows permite instalar hooks de teclado, ratón, mensajes de ventana, menús, barras de desplazamiento, cuadros de diálogo, etc. Un proceso con permisos suficientes puede registrar callbacks que reciben o modifican esos eventos antes de que lleguen a la aplicación destino.
- Linux, a nivel de red, expone puntos de enganche como Netfilter, que permiten interceptar, modificar o descartar paquetes en el kernel.
En estos casos, los system hooks son parte del diseño oficial del sistema, aunque también son una puerta de entrada para herramientas de monitorización avanzadas o malware si se usan de forma maliciosa.
Hooks sobre tablas de funciones virtuales (VMT/VTable)
En lenguajes orientados a objetos compilados, cuando una clase define métodos virtuales, la mayoría de compiladores añaden un puntero oculto a una tabla de métodos virtuales (VMT o VTable), que es una lista de punteros a las funciones reales que se ejecutarán en tiempo de ejecución.
Un método de hooking consiste en modificar esa VTable en memoria para que un método virtual deje de apuntar a la implementación original y pase a apuntar a una función nuestra. A partir de ese momento, cualquier llamada al método virtual ejecutará nuestro código, con la posibilidad de delegar después en el original.
Hooking de APIs con saltos (JMP) y DLL injection
Una táctica muy directa de system hook es sobrescribir los primeros bytes de una función con una instrucción de salto (JMP) hacia otra función controlada por nosotros:
- Se compila el código hook en una DLL.
- Se inyecta la DLL en el proceso objetivo (usando varias técnicas de DLL injection).
- Una vez dentro, se guardan los bytes originales del inicio de la función.
- Se sobrescriben esos bytes con un JMP a nuestra función. Si queremos preservar el comportamiento normal, podemos, en algún momento, restaurar los bytes originales y saltar de vuelta.
Esto permite interceptar funciones importadas de otros módulos, incluso en procesos remotos. Un beneficio adicional es que puede ser menos detectable por antivirus si se hace con cuidado, al no depender de patrones de código malicioso típico.
Hooks en frameworks de interfaz: el caso de React y sus system hooks

En el ecosistema de desarrollo frontend, el término hook se ha popularizado sobre todo gracias a React. Aquí el enfoque es muy distinto: los hooks son una API oficial de alto nivel para manejar estado, efectos secundarios y otros comportamientos en componentes funcionales.
Hasta React 16.7, para disponer de estado y ciclo de vida en React era necesario usar componentes de clase. En octubre de 2018, en la React Conf, el equipo de Facebook presentó los hooks, que se incorporaron de forma estable en React 16.8 (y en React Native a partir de la 0.59). La idea era poder tener estado, efectos y contexto dentro de componentes funcionales, simplificando el modelo mental y mejorando la reutilización.
Problemas que venían a resolver los hooks de React
El equipo de React identificó tres grandes dolores que sufrían las aplicaciones grandes:
- Dificultad para reutilizar lógica con estado. Hasta entonces se usaban patrones como High-Order Components (HOC) y render props; funcionaban, pero en casos complejos derivaban en árboles absurdamente anidados, el famoso “wrapper hell”.
- Componentes de clase muy largos y difíciles de mantener. La lógica de una misma funcionalidad se repartía entre métodos de ciclo de vida como componentDidMount, componentDidUpdate y componentWillUnmount, lo que hacía complicado seguir el flujo de datos y efectos.
- Complejidad inherente de las clases de JavaScript, tanto para personas (problemas con
this, binding, herencia) como para las máquinas (dificultades para hot reloading fiable y optimizaciones a nivel de compilación y rendimiento).
En lugar de parchear cada problema por separado, el equipo llegó a la conclusión de que el síntoma común era la ausencia de un modelo sencillo de componente con estado y ciclo de vida sin recurrir a clases. De ahí nacieron los hooks.
Qué es un hook en React
En React, un hook es una función especial que empieza por use y que te permite “enganchar” (hook) un componente funcional a capacidades internas de React: estado, ciclo de vida, contexto, memoización, transiciones, etc.
Algunos hooks vienen incorporados en la librería, como useState, useEffect, useContext, useReducer, useRef, useMemo, useCallback, useLayoutEffect o useTransition. Además, puedes crear tus propios hooks personalizados (custom hooks) que encapsulen y reutilicen lógica con estado entre varios componentes.
useState: estado local en componentes funcionales
El hook useState te permite añadir un estado local mutable a un componente funcional. Devuelve un par: el valor actual de estado y una función para actualizarlo.
Es la alternativa directa a this.state y this.setState() en componentes de clase, pero con una sintaxis más compacta y sin la necesidad de gestionar this. El estado inicial se pasa como argumento a useState y solo se usa en el primer renderizado.
Un patrón común es desestructurar el array devuelto:
- La primera variable representa el valor actual (por ejemplo,
counter). - La segunda es la función de actualización (por ejemplo,
setCounter), que suele seguir el patrón de nombrar conset+ nombre del estado.
Se pueden declarar varios useState en un mismo componente, y React los diferenciará según el orden en el que se llamen, de ahí que las reglas de hooks insistan tanto en no usarlos en condicionales o bucles.
useEffect: efectos secundarios y ciclo de vida
El hook useEffect es el equivalente funcional a combinar componentDidMount, componentDidUpdate y componentWillUnmount en componentes de clase. Sirve para ejecutar efectos secundarios después de que React haya actualizado el DOM: peticiones a APIs, suscripciones, timers, manipulaciones del DOM, logging, etc.
useEffect recibe una función de efecto, que React ejecutará después de cada render por defecto. Además, puede recibir un segundo argumento: un array de dependencias. Esa lista indica a React cuándo debe volver a ejecutar el efecto:
- Si no se pasa array, el efecto se ejecuta tras cada renderizado.
- Si se pasa un array con variables, el efecto solo se ejecuta cuando alguna de ellas cambie.
- Si se pasa un array vacío
[], el efecto se ejecuta solo una vez después del primer render (patrón típico para inicializaciones como una petición HTTP).
La función del efecto puede devolver otra función, que React utilizará para limpiar recursos (unsubscribe, eliminar listeners, limpiar intervalos, etc.) antes de desmontar el componente o antes de volver a ejecutar el efecto.
Un error clásico con useEffect cuando haces peticiones es olvidar el array de dependencias, provocando que cada actualización dispare una nueva llamada, lo que a su vez cambia el estado y causa un bucle infinito de renderizados.
useContext: acceso sencillo a contexto global
React incluye una API de contexto (Context API) que permite compartir datos globales como el usuario autenticado, el tema visual o configuración general, sin necesidad de pasar props a través de todos los niveles del árbol.
El contexto se crea con createContext y ofrece dos elementos principales:
- Provider: componente que expone un valor a todo su subárbol mediante la prop
value. - Consumer: componente que, tradicionalmente, se usaba para leer el valor del contexto.
El hook useContext sustituye de forma mucho más cómoda al Consumer. Llamas useContext con el objeto de contexto y obtienes directamente el valor actual, suscribiéndote a sus cambios sin necesidad de funciones de render prop ni anidamiento excesivo.
Otros hooks importantes de React
Además de useState, useEffect y useContext, React ofrece otros hooks pensados para casos más avanzados o de rendimiento:
- useReducer: una alternativa a useState cuando el estado es complejo y tiene múltiples transiciones. Sigue el patrón de reducer al estilo Redux, recibiendo el estado actual y una acción, y devolviendo el nuevo estado.
- useMemo y useCallback: pensados para optimizar rendimiento. useMemo memoriza el resultado de un cálculo caro; useCallback memoriza una función para evitar recrearla en cada render y provocar renders innecesarios en componentes hijos.
- useRef: crea una referencia mutable que persiste entre renders, útil tanto para almacenar valores que no disparan un rerender como para acceder directamente a nodos DOM.
- useLayoutEffect: similar a useEffect, pero se ejecuta después de actualizar el DOM y antes de que el usuario vea los cambios. Es útil cuando necesitas medir o recalcular layout antes del pintado.
Reglas de los hooks en React
Para que React pueda asociar internamente cada llamada a hook con su estado correspondiente, impone dos reglas estrictas:
- Solo llama hooks en el nivel superior del componente. Nada de usarlos dentro de bucles, condicionales o funciones anidadas.
- Solo llama hooks desde componentes funcionales de React o desde otros hooks personalizados, nunca desde funciones normales.
Si rompes estas reglas, React deja de poder asociar correctamente el orden de los hooks con su estado, lo que provoca comportamientos erráticos. Existe incluso un plugin de ESLint oficial para detectar estos errores en tiempo de desarrollo.
Custom hooks: encapsular y reutilizar lógica
Un custom hook no es más que una función de JavaScript cuyo nombre empieza por use y que internamente llama a otros hooks. Sirven para agrupar lógica relacionada con estado y efectos y reutilizarla en varios componentes sin repetir código ni añadir más niveles de componentes (como pasaba con HOC o render props).
Por ejemplo, puedes encapsular toda la lógica de suscripción al estado online de un amigo en un hook useFriendStatus(friendId) y usarlo en diferentes componentes. Cada llamada a ese hook tendrá su propio estado aislado, de forma que reutilizas la lógica, no el estado.
Hooks en WordPress: filtros, acciones y ganchos del core
En el mundo de WordPress, los hooks (ganchos) son la base de su sistema de extensiones. Permiten modificar el comportamiento de WordPress, temas y plugins sin tocar el código original, lo que hace posible actualizar el core sin perder personalizaciones.
Los hooks llevan presentes desde WordPress 1.2, y existen cientos de ellos repartidos por el core. Cualquier desarrollador de temas o plugins que se tome en serio WordPress debe entender bien cómo funcionan.
Dos tipos de hooks en WordPress: acciones y filtros
WordPress diferencia entre dos grandes familias de hooks:
- Action hooks (acciones): sirven para ejecutar código en momentos concretos del flujo de WordPress. No devuelven valores; simplemente “hacen cosas” (registrar tipos de post, enviar emails, imprimir HTML, etc.).
- Filter hooks (filtros): se utilizan para modificar datos justo antes de que se muestren en pantalla o se guarden en la base de datos. Reciben un valor, lo transforman y devuelven el resultado modificado.
Internamente, el core dispara estos hooks con do_action() (para acciones) y apply_filters() (para filtros). Los desarrolladores se enganchan a ellos con add_action() y add_filter().
Ejemplo conceptual: añadir texto al final de los posts
Imagina que quieres añadir el texto “Gracias por leer este post” al final de todos tus artículos. Las soluciones ingenuas serían editar cada entrada o modificar la plantilla del tema, con todos los problemas de mantenimiento que eso implica.
Con hooks, basta con usar el filtro the_content y enganchar una función que añada ese texto al contenido. WordPress pasará el contenido al filtro, tu función le añadirá el párrafo y devolverá el nuevo contenido. No has tocado el core ni la plantilla, pero has modificado el resultado final.
Cómo se integran los hooks con el core de WordPress
El núcleo de WordPress define montones de puntos donde lanza eventos internos:
- Con
do_action('hook_name'), el core dispara una acción en un momento dado (por ejemplo,init,wp_head,save_post). - Con
apply_filters('hook_name', $valor), permite que cualquier plugin o tema pueda modificar un determinado valor (the_content,the_title,body_class, etc.).
WordPress mantiene internamente una gran estructura (la global $wp_filter) donde almacena qué funciones están enganchadas a cada hook y con qué prioridad. Cuando se dispara un hook, WordPress recorre esa lista y ejecuta las funciones registradas en orden.
Orden de ejecución y prioridades
Cuando varias funciones están enganchadas al mismo hook, el orden en el que se ejecutan viene determinado por la prioridad que se indica en add_action() o add_filter():
- Las prioridades son números enteros; cuanto más bajo sea el número, antes se ejecuta la función.
- Si no se especifica, la prioridad por defecto es 10.
Esto es fundamental cuando una función depende de que otra ya haya hecho su trabajo. Por ejemplo, si primero registras un Custom Post Type en un hook init con prioridad 5 y después, con prioridad 15, asignas capacidades a ese post type, te aseguras de que el registro exista antes de intentar modificarlo.
Hooks globales: el hook especial all
WordPress dispone de un hook especial llamado all, que se dispara cada vez que se ejecuta cualquier hook en el sistema. Enganchándote a all puedes auditar qué hooks se van disparando y en qué orden, o registrar información de depuración.
Eso sí, hay que usarlo con cuidado porque se ejecutará constantemente y puede afectar al rendimiento si haces operaciones pesadas en él.
Crear y eliminar tus propios hooks en WordPress
Además de engancharte a hooks del core, puedes definir tus propios puntos de extensión dentro de un plugin o un tema, para que terceros puedan añadir lógica sobre tu código:
- do_action(‘mi_hook_personalizado’): define un punto donde otros pueden enganchar funciones con
add_action(). - apply_filters(‘mi_filtro_personalizado’, $valor): permite que otros modifiquen un valor concreto con
add_filter()antes de usarlo o mostrarlo.
Del mismo modo, se pueden usar remove_action() y remove_filter() para desenganchar callbacks registrados previamente, siempre que coincidan nombre del hook, función y prioridad, y que la eliminación se haga después de su registro.
Buenas prácticas con hooks en WordPress
Para evitar conflictos y mantener el código limpio, hay varias prácticas muy recomendables:
- Prefijar nombres de funciones, clases y hooks con un identificador único del plugin o tema, para evitar colisiones.
- Comprobar si existen funciones o clases antes de declararlas usando
function_exists()o similares, especialmente al cargar librerías comunes. - Documentar los hooks propios con PHPDoc, indicando su propósito, versión desde la que existen, parámetros y funciones enganchadas típicas.
- Gestionar bien las prioridades cuando hay dependencias entre callbacks.
Herramientas como Debug Bar o Query Monitor ayudan a inspeccionar qué hooks se ejecutan, qué consultas generan o qué errores se están produciendo, algo muy útil cuando el número de ganchos se dispara.
Hooks en herramientas de control de versiones: el caso de Git
Fuera del desarrollo web, los hooks también son fundamentales en herramientas como Git. En este contexto, un hook es simplemente un script que se ejecuta automáticamente cuando ocurre un evento en el repositorio, como un commit, un push o una recepción de cambios en el servidor.
Git distingue principalmente entre hooks locales (en el repositorio del desarrollador) y hooks de servidor (en el repositorio remoto, por ejemplo en un servidor centralizado o en una integración on-premise).
Hooks locales en Git
En el repositorio local, Git soporta diferentes tipos de hooks que se ejecutan en momentos clave del flujo de trabajo:
- pre-commit: se ejecuta justo antes de crear el commit; suele usarse para lanzar linters, tests rápidos o formateadores y bloquear el commit si algo falla.
- prepare-commit-msg: permite preparar o modificar el mensaje de commit antes de que el usuario lo edite (por ejemplo, para insertar una plantilla).
- commit-msg: se ejecuta tras escribir el mensaje; ideal para validar su formato, por ejemplo, comprobar que incluya un identificador de ticket.
- post-commit: se dispara después de crear el commit; se usa para acciones informativas o sincronizaciones que no deban bloquear el commit.
- post-checkout: se ejecuta después de cambiar de rama o restaurar archivos; útil para re-configurar el entorno de trabajo según la rama activa.
- pre-rebase: se lanza antes de un rebase, lo que permite bloquear ciertos rebases o realizar comprobaciones previas.
Estos scripts residen normalmente en la carpeta .git/hooks y se ejecutan si son ejecutables. Permiten automatizar calidad, convenciones y tareas repetitivas de forma muy potente.
Hooks de servidor en Git
En el lado del servidor, Git también dispone de hooks que se ejecutan cuando un cliente intenta empujar cambios:
- pre-receive: se ejecuta antes de aceptar los cambios; sirve para validar políticas (ramas protegidas, mensajes de commit, firmas, etc.).
- update: similar a pre-receive pero para cada referencia (branch/tag) individual, lo que permite reglas más finas.
- post-receive: se ejecuta después de aceptar los cambios; muy usado para desencadenar integraciones continuas, despliegues o notificaciones.
En conjunto, estos system hooks de Git permiten personalizar el flujo de trabajo a nivel de equipo u organización sin modificar la lógica interna de Git, respetando totalmente su modelo distribuido.
Los system hooks, ya sea en forma de ganchos a nivel de sistema operativo, APIs de frameworks como React, extensiones de WordPress o scripts en Git, responden a la misma idea: exponer puntos de enganche donde el sistema cede el control momentáneamente a tu código. Entender bien cómo funcionan, sus reglas y sus límites es clave para construir software extensible, mantenible y, sobre todo, preparado para crecer sin romper el núcleo en el que se apoya.
