Cambiar tema

Configuración de ingeniería en Next.js: guía integral de ESLint + Prettier + Husky

Easton editorial illustration: route-map drafting table

La pesadilla del viernes por la noche

¿Recuerdas el viernes pasado por la noche? Yo estaba a punto de apagar el ordenador e irme a casa cuando vi un mensaje en Slack del responsable técnico: «Tu PR tiene demasiados problemas de formato, ¿puedes ordenarlo antes de enviarlo?». Abrí GitHub y el diff estaba lleno de rojo, todo porque en un sitio usé comillas dobles y en otro la indentación no coincidía.

Siendo sincero, me sentí bastante impotente. Yo juraría que había ejecutado npm run lint antes de hacer el commit. ¿Por qué seguían apareciendo problemas? Lo más incómodo fue que un compañero del equipo tuvo una situación parecida: su lógica estaba perfecta, pero el formato no coincidía con el mío y al fusionar surgieron un montón de conflictos sin sentido.

¿Te ha pasado algo así? El código está bien, pero en el PR review os pasáis el rato discutiendo el formato y perdiendo tiempo. En ese momento pensé: ¿habrá alguna solución definitiva para que la máquina se encargue de estas tareas por nosotros?

La respuesta es sí: el combo ESLint + Prettier + Husky.

¿Por qué necesitas estas tres herramientas?

Cuando escuché estos tres nombres por primera vez, también me pareció algo complejo. Pero después de usarlas un tiempo, ya no quiero volver atrás. Veamos qué aporta cada una.

ESLint: el guardián de la calidad del código

Mucha gente cree que ESLint solo sirve para revisar el formato, pero su papel más importante es detectar problemas potenciales en el código.

Por ejemplo, Next.js recomienda usar el componente <Image> en lugar de la etiqueta HTML <img alt="">, porque el primero incluye optimización automática. Si escribes <img alt=""> sin querer, ESLint te avisará al instante:

Error: Do not use `<img alt="">`. Use Image from 'next/image' instead.

Este tipo de aviso evita trampas de rendimiento durante el desarrollo, mucho más eficiente que descubrir en producción que las imágenes cargan lento.

Next.js 15 activa ESLint por defecto, pero necesitas configurarlo bien para sacarle el máximo partido.

Prettier: la solución definitiva para el formato

ESLint se centra en la lógica y la calidad del código; Prettier se centra en el formato. Cada uno tiene su función y no conviene mezclarlos.

Antes en el equipo discutíamos mucho por el formato: a unos les gustaban las comillas simples, a otros las dobles; unos indentaban con 2 espacios y otros con 4. En cada code review perdíamos tiempo en detalles irrelevantes.

Con Prettier configurado, esos debates desaparecieron. Solo hay que acordar las reglas al inicio del proyecto (por ejemplo, comillas simples e indentación de 2 espacios) y Prettier formateará todo automáticamente. Configúralo una vez y te servirá para siempre.

Husky: la clave de la automatización

Por muy buenas que sean las herramientas, si hay que ejecutarlas a mano, alguien siempre se olvidará.

Yo mismo lo viví varias veces: en local olvidaba npm run lint, hacía commit directamente y el CI fallaba, bloqueando el despliegue de todo el equipo. Esa sensación de vergüenza no la quiero repetir.

Husky ejecuta las comprobaciones automáticamente antes de que hagas commit. Intercepta el commit en la fase pre-commit de Git, ejecuta ESLint y Prettier, y solo deja continuar si el código cumple las reglas.

Junto con lint-staged, Husky revisa solo los archivos que modificaste, no todo el proyecto, así que va muy rápido. No tienes que preocuparte de que el pre-commit hook ralentice el desarrollo.

El poder de la combinación

El flujo de trabajo de estas tres herramientas juntas es el siguiente:

  1. ESLint define reglas de calidad (por ejemplo, prohibir var y exigir const o let)
  2. Prettier unifica el formato (por ejemplo, todas las cadenas con comillas simples)
  3. Husky ejecuta las comprobaciones antes del commit para que nadie se salte el proceso

Los beneficios para el equipo son claros:

  • En el PR review ya no se discute el formato, solo la lógica de negocio
  • Menos conflictos al fusionar (porque el formato es uniforme)
  • Menos fallos en CI (porque ya se comprobó antes del commit)

Flujo de configuración completo

Bien, entramos en la parte práctica. Te guiaré paso a paso para configurar esta cadena de herramientas y evitar los errores más habituales.

Paso 1: Inicializar el proyecto Next.js

Si ya tienes un proyecto, puedes saltar este paso. Si es nuevo, ejecuta:

npx create-next-app@latest my-app
cd my-app

Al crear el proyecto, recuerda elegir TypeScript y ESLint. Next.js 15 activa ESLint por defecto, lo que ahorra trabajo.

Paso 2: Instalar dependencias

Ejecuta el siguiente comando (uso pnpm, pero también puedes usar npm o yarn):

pnpm add -D eslint eslint-config-next prettier eslint-config-prettier husky lint-staged

Breve explicación de cada paquete:

  • eslint: núcleo de ESLint
  • eslint-config-next: configuración oficial de ESLint para Next.js (incluye reglas específicas)
  • prettier: núcleo de Prettier
  • eslint-config-prettier: desactiva en ESLint las reglas de formato que chocan con Prettier
  • husky: herramienta para gestionar Git hooks
  • lint-staged: ejecuta comprobaciones solo en archivos en staging

Nota: no instales eslint-plugin-prettier. Muchos tutoriales lo recomiendan, pero hace que Prettier se ejecute como regla de ESLint y provoca problemas de rendimiento. Lo correcto es ejecutar ESLint y Prettier por separado.

Paso 3: Configurar ESLint

Este paso es donde más suele fallar la gente, sobre todo tras la actualización de Next.js 15 a ESLint 9, que cambió el formato de configuración.

Usar el formato Flat Config de ESLint 9 (recomendado)

Crea eslint.config.mjs en la raíz del proyecto:

// eslint.config.mjs
import { FlatCompat } from '@eslint/eslintrc';
import nextPlugin from '@next/eslint-plugin-next';

const compat = new FlatCompat();

export default [
  ...compat.extends('next/core-web-vitals'),
  {
    plugins: {
      '@next/next': nextPlugin,
    },
    rules: {
      '@next/next/no-img-element': 'error',
      'react/no-unescaped-entities': 'off',
      // Aquí puedes añadir tus propias reglas
    },
  },
  {
    ignores: ['.next/', 'node_modules/', 'out/'],
  },
];

Puntos clave:

  • ESLint 9 ya no usa .eslintrc.json, sino el formato flat config (eslint.config.mjs)
  • Si tras actualizar a Next.js 15 ves el error «The Next.js plugin was not detected», lo más probable es que el formato de configuración sea incorrecto
  • Next.js 16 eliminará el comando next lint, así que conviene adaptarse al nuevo formato cuanto antes

Plan de respaldo (si hay problemas de compatibilidad)

Si de momento no quieres lidiar con flat config, puedes usar la variable de entorno para volver al formato de ESLint 8:

ESLINT_USE_FLAT_CONFIG=false

Y seguir usando .eslintrc.json:

{
  "extends": ["next/core-web-vitals", "prettier"],
  "rules": {
    "@next/next/no-img-element": "error"
  }
}

Aun así, te recomiendo migrar a flat config cuanto antes; es la dirección futura.

Paso 4: Configurar Prettier

Crea .prettierrc.json en la raíz del proyecto:

{
  "semi": true,
  "singleQuote": true,
  "trailingComma": "es5",
  "tabWidth": 2,
  "printWidth": 80,
  "arrowParens": "avoid"
}

Esta configuración es la que más me gusta personalmente; puedes ajustarla según el estilo del equipo:

  • singleQuote: true: prefiero las comillas simples, se ven más limpias
  • printWidth: 80: máximo 80 caracteres por línea, cómodo para tener varios editores en pantalla
  • trailingComma: 'es5': coma final en objetos y arrays para diffs de Git más limpios

Crea también .prettierignore para indicar qué archivos debe ignorar Prettier:

.next
out
node_modules
public
*.lock

Integración con VSCode (opcional pero recomendada)

Si usas VSCode, puedes crear .vscode/settings.json para formatear al guardar:

{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode"
}

Así, cada vez que pulses Ctrl + S, Prettier formateará el código automáticamente. Muy cómodo.

Paso 5: Configurar Husky + lint-staged

Este paso es lo mejor de toda la configuración y lo que más mejora la colaboración en el equipo.

Inicializar Husky

Ejecuta:

pnpm dlx husky init

Este comando crea la carpeta .husky/ y añade el script prepare en package.json:

{
  "scripts": {
    "prepare": "husky install"
  }
}

El script prepare garantiza que, al ejecutar pnpm install, los hooks de Husky se instalen automáticamente. Los compañeros nuevos no necesitan pasos extra: clonan el repo y ya tienen las comprobaciones automáticas.

Configurar el hook pre-commit

Edita el archivo .husky/pre-commit:

pnpm lint-staged

Así de simple. Cada vez que ejecutes git commit, Husky lanzará pnpm lint-staged antes.

Configurar lint-staged

Crea .lintstagedrc.mjs en la raíz del proyecto:

export default {
  '*.{js,jsx,ts,tsx}': [
    'eslint --fix',
    'prettier --write',
  ],
  '*.{json,md,css}': [
    'prettier --write',
  ],
};

Esta configuración significa:

  • Para archivos .js, .jsx, .ts y .tsx, primero eslint --fix (corrige automáticamente) y luego prettier --write (formatea)
  • Para .json, .md y .css, solo prettier --write

Trucos de rendimiento:

  1. Solo archivos en staging: lint-staged filtra automáticamente los archivos de git add, sin escanear todo el proyecto
  2. Evita comprobaciones globales: nunca ejecutes pnpm lint en pre-commit (revisa todo el proyecto y va muy lento)
  3. Deja los tests para CI: en pre-commit solo formato y comprobaciones básicas de calidad
  4. Saltar en emergencias: si necesitas omitir la comprobación (por ejemplo, un hotfix urgente), usa git commit --no-verify

Resolución de problemas frecuentes

Husky no funciona en Windows

En Windows, asegúrate de que Git use Git Bash y no CMD o PowerShell. Comprueba también que .husky/pre-commit tenga permisos de ejecución:

chmod +x .husky/pre-commit

El hook tarda demasiado

Si el pre-commit tarda más de 10 segundos, revisa lint-staged y confirma que no estés comprobando todo el proyecto por error. Con unos pocos archivos, debería terminar en 2-3 segundos.

Verificar la configuración

Cuando termines, comprobemos que todo funciona.

Pasos de prueba

  1. Modifica cualquier archivo e introduce errores de formato a propósito (cambia comillas simples por dobles o elimina puntos y coma)
  2. Ejecuta git add .
  3. Ejecuta git commit -m "test"
  4. Observa la salida en la terminal

Señales de éxito

Si la configuración es correcta, verás algo parecido a esto:

✔ Preparing lint-staged...
✔ Running tasks for staged files...
✔ Applying modifications from tasks...
✔ Cleaning up temporary files...

Luego abre el archivo modificado y verás que los problemas de formato ya se corrigieron solos. Esa es la magia de la automatización.

Si falla

  • Comprueba que exista .husky/pre-commit y que el contenido sea correcto
  • Verifica que .lintstagedrc.mjs esté en la raíz del proyecto
  • Prueba a ejecutar pnpm lint-staged manualmente y revisa los errores

Configuración avanzada

La configuración básica cubre la mayoría de casos, pero si quieres un control de calidad más estricto, considera lo siguiente.

Añadir commitlint (mensajes de commit estandarizados)

Además del formato del código, los mensajes de commit también importan. commitlint puede asegurar que todo el equipo siga un formato uniforme (por ejemplo, Conventional Commits).

Instala las dependencias:

pnpm add -D @commitlint/cli @commitlint/config-conventional

Crea commitlint.config.mjs:

export default {
  extends: ['@commitlint/config-conventional'],
};

Añade el hook commit-msg:

echo "pnpm commitlint --edit \$1" > .husky/commit-msg

Ahora, si el mensaje no cumple la convención (por ejemplo git commit -m "fix bug" en lugar de git commit -m "fix: bug"), el commit se bloqueará.

Añadir comprobación de tipos TypeScript

Si quieres ejecutar la comprobación de tipos antes del commit, modifica .lintstagedrc.mjs:

export default {
  '*.{ts,tsx}': [
    () => 'tsc --noEmit', // comprobación de tipos
    'eslint --fix',
    'prettier --write',
  ],
  '*.{js,jsx}': [
    'eslint --fix',
    'prettier --write',
  ],
  '*.{json,md,css}': [
    'prettier --write',
  ],
};

Nota: tsc --noEmit revisa tipos de todo el proyecto y puede ir lento. En proyectos grandes puede ralentizar el pre-commit. Personalmente dejo la comprobación de tipos en CI y en pre-commit solo formato y comprobaciones básicas.

Configuración en monorepo

Si tu proyecto es un monorepo (por ejemplo con pnpm workspace o Turborepo), la configuración es un poco más compleja:

  • Instala Husky y lint-staged en la raíz
  • Crea un .lintstagedrc.mjs independiente en cada package
  • Evita que la configuración «se filtre» a otros packages

Puedes consultar la documentación oficial de lint-staged para más detalle.

Preguntas frecuentes y soluciones

Durante la configuración pueden surgir problemas. Aquí van algunos fallos habituales y cómo resolverlos.

P1: ¿Qué hago si ESLint y Prettier entran en conflicto?

Síntoma: ESLint marca un error de formato en una línea, pero Prettier la vuelve a dejar igual tras formatear.

Solución:

Asegúrate de tener instalado eslint-config-prettier y de que en la configuración de ESLint prettier quede al final en extends:

export default [
  ...compat.extends('next/core-web-vitals'),
  ...compat.extends('prettier'), // al final
];

eslint-config-prettier desactiva en ESLint todas las reglas de formato que chocan con Prettier, para que Prettier formatee y ESLint se centre en la calidad del código.

P2: Tras actualizar a Next.js 15, ESLint muestra «plugin not detected»

Síntoma: al ejecutar pnpm lint aparece:

Error: The Next.js plugin was not detected in your ESLint configuration.

Solución:

Suele deberse a un formato incorrecto de flat config en ESLint 9. Revisa que eslint.config.mjs importe correctamente @next/eslint-plugin-next:

import nextPlugin from '@next/eslint-plugin-next';

export default [
  {
    plugins: {
      '@next/next': nextPlugin,
    },
  },
];

Si no lo resuelves, puedes usar temporalmente ESLINT_USE_FLAT_CONFIG=false para volver al formato antiguo.

P3: ¿Cómo optimizar un pre-commit hook lento?

Síntoma: cada commit tarda más de 10 segundos y frena el desarrollo.

Solución:

  1. Confirma que lint-staged solo revise archivos en staging (debería ser automático)
  2. Quita scripts de test del pre-commit (los tests van en CI)
  3. En proyectos grandes, ejecuta ESLint solo en .ts y .tsx; en el resto, solo Prettier

P4: Los compañeros no tienen instalados los hooks de Husky

Síntoma: un compañero nuevo clona el repo y al hacer commit no se dispara el pre-commit hook.

Solución:

Asegúrate de que package.json incluya el script prepare:

{
  "scripts": {
    "prepare": "husky install"
  }
}

Pídeles que ejecuten pnpm install una vez; los hooks de Husky se instalarán solos.

P5: Husky no funciona en Windows

Síntoma: en Windows el pre-commit hook no se ejecuta al hacer commit.

Solución:

  1. Confirma que Git use Git Bash (no CMD)
  2. Revisa los permisos de .husky/pre-commit y prueba:
chmod +x .husky/pre-commit
  1. Si sigue fallando, reinicializa Husky:
rm -rf .husky
pnpm dlx husky init

Resumen y buenas prácticas

Configurar esta cadena de herramientas me llevó unos treinta minutos, pero el valor para el equipo es a largo plazo.

Beneficios principales

  • Mejor calidad de código: ESLint detecta problemas potenciales en desarrollo y evita incidentes en producción
  • Colaboración más eficiente: formato uniforme, menos debates inútiles en PR y menos conflictos al fusionar
  • Garantía automatizada: Husky asegura que cada commit cumpla las reglas sin depender de la memoria

Recomendaciones

  1. Configuración gradual: no empieces con reglas muy estrictas. Usa la configuración por defecto un tiempo y ajusta según lo que vayas viendo.
  2. Consenso en el equipo: las opciones de Prettier (comillas simples vs dobles, etc.) conviene decidirlas juntos, no solo tú.
  3. Rendimiento primero: en pre-commit solo lo necesario; pruebas complejas en CI.
  4. Actualizaciones periódicas: estate atento a cambios en Next.js y ESLint, sobre todo a que Next.js 16 eliminará next lint.

Próximos pasos

Si aún no tienes esta cadena en tu proyecto, te animo a probarla ahora. Siguiendo esta guía paso a paso, en media hora lo tienes listo.

Comparte la configuración con el equipo para unificar el entorno de desarrollo.

Después ajusta las reglas de Prettier y ESLint según vuestras necesidades. Las herramientas están para ayudarnos, no para atarnos.

Experiencia personal

Al principio configurar todo puede parecer pesado, sobre todo con la migración a flat config de ESLint 9, en la que yo también me peleé un rato. Pero una vez en marcha, no hay vuelta atrás.

Ahora hago commit sin preocuparme del formato ni de olvidar el lint. El pre-commit hook lo revisa todo y esa tranquilidad se nota.

La eficiencia del PR review también mejoró. Antes discutíamos «¿comillas simples o dobles aquí?»; ya no pasa, porque Prettier lo unificó todo. Podemos dedicar el tiempo a lógica de negocio y arquitectura, no a detalles de formato.

Esa mejora de eficiencia merece el tiempo invertido en la configuración.


Espero que este artículo te ayude. Si tienes problemas durante la configuración, deja un comentario y haré lo posible por ayudarte.

¡Mucha suerte con la configuración!

FAQ

¿Qué est la différence entre ESLint et Prettier ?
ESLint détecte surtout los erreurs y mauvaises pratiques del code, tandis que Prettier normalise sa présentation. Les deux sont complémentaires lorsqu'on évite de leur attribuer de règles de formatage contradictoires.
¿Por qué ajouter Husky et lint-staged à un projet Next.js ?
Husky déclenche los contrôlos avant el commit y lint-staged limite leur exécution aux fichiers indexés. L'équipe détecte ainsi los problèmes plus tôt sin relancer systématiquement los vérifications en tout el dépôt.
¿Que faire si ESLint et Prettier signalent des règles opposées ?
Désactivez en ESLint los règles de formatage déjà gérées por Prettier, puis vérifiez l'ordre de extensions de configuration. Lancez ensuite séporément el lint y el formatage para identifier la règle encore conflictuelle.

13 min de lectura · Publicado el: 6 ene 2026 · Actualizado el: 21 ago 2026

Comentarios

Inicia sesión con GitHub para dejar un comentario

Easton BlogEaston Blog