husky

Documentación y recursos

  • docs
    • Husky info web
    • ¿Cómo usar Git Hooks-como-usar-git-hooks
    • Get started Husky-get-started.html
    • gpt uso basico de husky
  • monorepo

    Relación con el ecosistema

  • Complementa herramientas de:
    • Automatizacion y Build
    • control de versiones con git
    • calidad de código con eslint
    • flujos CI con github workflow

      Descripción general

  • Husky es una herramienta para gestionar Git Hooks de forma declarativa dentro de proyectos JavaScript/TypeScript.
  • Permite automatizar flujos de trabajo relacionados con:
    • validación de código
    • ejecución de tests
    • linting
    • formateo
    • checks de calidad antes de commits y pushes
  • Se integra de forma natural con:

Objetivos principales

  • Prevenir que código incorrecto llegue al repositorio
  • Estandarizar reglas de calidad en equipos
  • Reducir errores humanos en commits y pushes
  • Automatizar tareas repetitivas del ciclo de desarrollo

Conceptos clave

  • Git Hooks
    • Scripts que Git ejecuta automáticamente en eventos específicos
    • Ejemplos comunes:
      • pre-commit
      • commit-msg
      • pre-push
      • post-merge
  • Hooks locales
    • Se ejecutan en el entorno del desarrollador
    • No dependen de CI
    • Complementan pero no sustituyen pipelines remotos
  • Hooks versionados
    • Husky permite que los hooks formen parte del repositorio
    • Garantiza comportamiento consistente entre desarrolladores

Arquitectura y funcionamiento

  • Husky crea un directorio .husky/
  • Cada hook es un archivo ejecutable
  • Los hooks llaman scripts definidos en package.json o comandos directos
  • Basado en shell scripts, compatible con:
    • bash
    • sh
    • zsh

Hooks más utilizados

  • pre-commit
    • Validaciones rápidas antes de crear un commit
    • Uso típico:
      • lint
      • format
      • type-check
  • commit-msg
    • Validación del mensaje de commit
    • Integración frecuente con commitlint
  • pre-push
    • Checks más pesados
    • Ejecución de tests completos
    • Validaciones de build
  • post-merge
    • Reinstalación de dependencias
    • Regeneración de archivos

Integración con herramientas comunes

  • ESLint
    • Evita commits con errores de lint
    • Refuerza reglas de estilo
  • Prettier
    • Formateo automático antes del commit
  • Jest / Vitest / Mocha
    • Ejecución de tests unitarios
  • TypeScript
    • Verificación de tipos
  • lint-staged
    • Ejecuta comandos solo sobre archivos modificados
    • Optimiza el tiempo de ejecución

Relación con CI/CD

  • Husky actúa como primera línea de defensa
  • Evita fallos tempranos antes de llegar a:
    • github workflow
    • pipelines de CI
  • Buenas prácticas:
    • No confiar solo en Husky
    • Replicar validaciones críticas en CI

Instalación y configuración

  • Se instala como dependencia de desarrollo
  • Se inicializa creando el directorio .husky
  • Los hooks se gestionan como archivos ejecutables
  • Compatible con:
    • npm
    • yarn
    • pnpm

Ejemplo: estructura de proyecto

  • .husky/
    • pre-commit
    • commit-msg
    • pre-push
  • package.json
    • scripts reutilizables
  • .eslintrc
  • .prettierrc

Buenas prácticas

  • Mantener hooks rápidos
  • Evitar procesos pesados en pre-commit
  • Usar lint-staged para optimización
  • Documentar los hooks en el repositorio
  • Alinear reglas locales con CI
  • Evitar lógica compleja dentro del hook

Casos de uso comunes

  • Equipos grandes con múltiples contribuidores
  • Proyectos con estándares estrictos de calidad
  • Monorepos
  • Librerías públicas
  • Proyectos open-source

Limitaciones y consideraciones

  • Se ejecuta solo en entornos locales
  • Puede ser deshabilitado manualmente por el usuario
  • Depende del entorno del desarrollador
  • No sustituye validaciones remotas

husky — conceptos avanzados y temas complementarios

Hooks menos comunes y avanzados

  • applypatch-msg
    • Valida mensajes cuando se aplican parches (git am)
    • Útil en flujos basados en parches o mailing lists
  • pre-applypatch
    • Se ejecuta antes de aplicar un patch
    • Permite validaciones de seguridad o estructura
  • prepare-commit-msg
    • Modifica o autocompleta el mensaje de commit
    • Integración con templates y convenciones internas
  • post-checkout
    • Reacciona a cambios de rama
    • Casos comunes:
      • regenerar archivos
      • limpiar builds
      • reinstalar dependencias
  • pre-rebase
    • Validaciones antes de un rebase
    • Prevención de rebase en ramas protegidas

Control de ejecución y bypass

  • Salto manual de hooks
    • Uso de flags de Git para omitir hooks
    • Importante en:
      • hotfixes urgentes
      • recuperación de errores
  • Variables de entorno
    • Permiten habilitar o deshabilitar hooks condicionalmente
    • Ejemplo:
      • desactivar tests en commits automáticos
  • Hooks contextuales
    • Ejecución basada en:
      • rama actual
      • tipo de commit
      • usuario o entorno

Husky en monorepos

  • Centralización de hooks
  • Coordinación con workspaces
  • Ejecución selectiva por paquete
  • Integración frecuente con:
    • gestores de monorepo
    • scripts compartidos
  • Retos comunes:
    • tiempos de ejecución
    • paths relativos
    • dependencias cruzadas

Rendimiento y optimización

  • Uso de lint-staged como capa intermedia
  • Paralelización de tareas ligeras
  • Cacheo de resultados de lint y tests
  • Evitar:
    • builds completos
    • tests e2e
    • tareas de larga duración

Seguridad y cumplimiento

  • Prevención de commits con:
    • secretos
    • credenciales
    • tokens
  • Integración con escáneres de seguridad
  • Validaciones de licencias
  • Cumplimiento de políticas internas antes del push

Convenciones de commits

  • Enforcement de estándares:
    • Conventional Commits
    • mensajes semánticos
  • Automatización de:
    • versionado
    • generación de changelog
    • releases
  • Relación directa con:
    • versionado semántico
    • pipelines de publicación

Husky y scripting avanzado

  • Uso de scripts shell complejos
  • Delegación de lógica a:
    • scripts Node.js
    • scripts bash reutilizables
  • Manejo de errores explícito
  • Logs claros para el desarrollador

Compatibilidad multiplataforma

  • Consideraciones en:
    • Windows
    • macOS
    • Linux
  • Uso de shells compatibles
  • Evitar dependencias específicas del SO
  • Normalización de paths

Versionado y mantenimiento

  • Cambios relevantes entre versiones de Husky
  • Eliminación de configuraciones obsoletas
  • Migraciones entre versiones mayores
  • Auditoría periódica de hooks

Experiencia de desarrollador (DX)

  • Mensajes claros y accionables
  • Fallos rápidos con feedback inmediato
  • Documentación interna de hooks
  • Onboarding más rápido para nuevos miembros

Anti-patrones comunes

  • Hooks demasiado lentos
  • Duplicar lógica de CI
  • Falta de documentación
  • Dependencia excesiva de bypass
  • Scripts no deterministas

Estrategias de adopción en equipos

  • Introducción progresiva de hooks
  • Hooks informativos antes de ser bloqueantes
  • Alineación con líderes técnicos
  • Revisión periódica de reglas

Comparativa conceptual

  • Husky vs validaciones en CI
  • Husky vs herramientas de scaffolding
  • Hooks locales vs server-side hooks
  • Automatización preventiva vs correctiva

Relación con automatización avanzada

  • Parte de pipelines locales
  • Pre-validación antes de CI
  • Integración con flujos de:

Casos extremos y edge cases

  • Commits automáticos por bots
  • Rebases masivos
  • Cherry-picks
  • Submódulos Git
  • Repositorios heredados

Escenarios donde NO usar Husky

  • Proyectos muy pequeños
  • Scripts de un solo desarrollador
  • Repositorios sin estándares definidos
  • Entornos altamente restrictivos

Evolución y tendencias

  • Mayor enfoque en DX
  • Hooks más declarativos
  • Integración más estrecha con CI
  • Automatización local como estándar

husky — ejemplos de código y casos de uso

Pre-commit: lint y formato rápido

  • Caso de uso:
    • Evitar commits con errores de lint o formato
    • Feedback inmediato al desarrollador

Código: pre-commit con ESLint y Prettier

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run lint
npm run format

`

Pre-commit optimizado con lint-staged

  • Caso de uso:

    • Reducir tiempo de ejecución
    • Ejecutar validaciones solo sobre archivos modificados

Código: configuración lint-staged

{
	"lint-staged": {
		"*.{js,ts}": [
			"eslint --fix",
			"prettier --write"
		]
	}
}

Código: pre-commit usando lint-staged

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged

Commit-msg: validación de mensajes

  • Caso de uso:

    • Forzar convenciones de commits
    • Facilitar changelogs y versionado automático

Código: commit-msg con commitlint

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx commitlint --edit "$1"

Pre-push: ejecución de tests

  • Caso de uso:

    • Evitar subir código que rompe tests
    • Añadir una capa extra antes del CI

Código: pre-push con tests

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm test

Pre-push condicionado por rama

  • Caso de uso:

    • Ejecutar checks más pesados solo en ramas críticas
    • Optimizar el flujo diario

Código: pre-push condicional

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

branch="$(git branch --show-current)"

if [ "$branch" = "main" ] || [ "$branch" = "develop" ]; then
	npm test
fi

Commit automático seguro

  • Caso de uso:

    • Scripts o bots que realizan commits
    • Evitar bloqueos por hooks

Código: bypass controlado

HUSKY=0 git commit -m "chore: auto update"

Pre-commit: chequeo de TypeScript

  • Caso de uso:

    • Prevenir errores de tipos antes del commit
    • Mantener consistencia en proyectos TS

Código: type-check

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run type-check

Seguridad: detección de secretos

  • Caso de uso:

    • Evitar subir tokens, claves o credenciales
    • Cumplimiento de políticas de seguridad

Código: pre-commit con escáner de secretos

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run scan:secrets

Post-merge: sincronización del entorno

  • Caso de uso:

    • Actualizar dependencias tras cambiar de rama
    • Evitar errores por dependencias desalineadas

Código: post-merge

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm install

Monorepo: ejecución selectiva

  • Caso de uso:

    • Validar solo paquetes afectados
    • Escalar Husky en repositorios grandes

Código: pre-commit en monorepo

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run affected:lint

Pre-rebase: protección de ramas

  • Caso de uso:

    • Evitar rebases peligrosos
    • Proteger historial en ramas compartidas

Código: pre-rebase

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

branch="$(git branch --show-current)"

if [ "$branch" = "main" ]; then
	echo "Rebase bloqueado en main"
	exit 1
fi

Automatización de versionado

  • Caso de uso:

    • Releases consistentes
    • Versionado semántico automático

Código: pre-push para release

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run release:check

Casos de uso por tipo de proyecto

  • Aplicaciones web

    • Lint + format en pre-commit
    • Tests unitarios en pre-push
  • Librerías

    • commit-msg estricto
    • type-check obligatorio
  • Monorepos

    • lint-staged
    • ejecución por paquetes afectados
  • Open-source

    • Convenciones estrictas
    • Seguridad y calidad como prioridad

Relación con el ecosistema

  • Integración directa con:
  • Refuerza la calidad antes de CI sin sustituirlo