Integración de ESLint + Prettier
Haz que ESLint y Prettier funcionen juntos sin conflictos separando conceptos: ESLint para calidad de código, Prettier para formateo.
Busca en todas las páginas de la documentación
Haz que ESLint y Prettier funcionen juntos sin conflictos separando conceptos: ESLint para calidad de código, Prettier para formateo.
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Tarjeta de receta de referencia rápida - lista para copiar y pegar.
# Instala el paquete de compatibilidad
npm install --save-dev eslint-config-prettier
# Eso es todo - no se necesita eslint-plugin-prettier// package.json scripts (ejecútalos por separado)
{
"scripts": {
"lint": "next lint",
"lint:fix": "next lint --fix",
"format": "prettier --write .",
"format:check": "prettier --check .",
"check-all": "npm run format:check && npm run lint"
}
}Cuándo usarlo: En cualquier proyecto que use ESLint y Prettier (que es la mayoría de proyectos React/Next.js).
// eslint.config.mjs
import { FlatCompat } from "@eslint/eslintrc";
import { dirname } from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const compat = new FlatCompat({ baseDirectory: __dirname });
const eslintConfig = [
...compat.extends(
"next/core-web-vitals",
"next/typescript",
"prettier", // Debe ser LAST - desactiva las reglas de formateo de ESLint
),
{
rules: {
// Reglas de calidad de código (no formateo) - estos no entrarán en conflicto
"@typescript-eslint/no-unused-vars": [
"error",
{ argsIgnorePattern: "^_" },
],
"react-hooks/exhaustive-deps": "warn",
"import/order": [
"warn",
{
groups: ["builtin", "external", "internal"],
"newlines-between": "always",
},
],
},
},
];
export default eslintConfig;// .prettierrc
{
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "all",
"printWidth": 80,
"plugins": ["prettier-plugin-tailwindcss"]
}Lo que esto demuestra:
eslint-config-prettier (la extensión "prettier") desactiva todas las reglas de ESLint que entran en conflicto con Prettierindent, semi, quotes) y reglas de calidad de código (por ejemplo, no-unused-vars, react-hooks/exhaustive-deps)eslint-config-prettier desactiva cada regla de ESLint que Prettier maneja, eliminando conflictosextends para anular todas las configuraciones anterioresPor qué NO usar eslint-plugin-prettier:
// ❌ Este enfoque ejecuta Prettier dentro de ESLint
// eslint-plugin-prettier - NO recomendado
{
plugins: ["prettier"],
rules: {
"prettier/prettier": "error",
},
}Problemas con este enfoque:
Enfoque recomendado: ejecútalas por separado:
{
"scripts": {
"lint": "next lint",
"lint:fix": "next lint --fix",
"format": "prettier --write .",
"format:check": "prettier --check .",
"fix-all": "npm run lint:fix && npm run format"
}
}Enfoque con hooks de pre-commit (lo mejor de ambos mundos):
// package.json
{
"lint-staged": {
"*.{ts,tsx}": ["eslint --fix", "prettier --write"],
"*.{css,json,md}": ["prettier --write"]
}
}// Ambas herramientas funcionan sin problemas en archivos .ts y .tsx.
// ESLint detecta problemas conscientes del tipo:
const unused = "hello"; // @typescript-eslint/no-unused-vars ❌
// Prettier maneja el formateo:
const obj = { a: 1, b: 2, c: 3 }; // Prettier controla espaciado, comas finales, etc.
// Sin superposición - cada herramienta hace su trabajo.Cosas que te causarán problemas. Cada trampa incluye qué sale mal, por qué sucede y la solución.
El orden de la configuración importa - Si "prettier" no es el último elemento en extends, las reglas de formateo de ESLint de configuraciones posteriores se volverán a habilitar y entrarán en conflicto. Solución: Siempre pon "prettier" al final en tu array de extends.
Verificar conflictos - No estás seguro si una regla entra en conflicto. Solución: Ejecuta npx eslint-config-prettier 'src/**/*.tsx' para listar las reglas que entran en conflicto con Prettier. La herramienta CLI reporta exactamente qué reglas desactivar.
Formateo diferente en CI vs local - Si los desarrolladores no tienen habilitado el formateo al guardar, CI detecta errores de formateo que nunca vieron. Solución: Usa Husky + lint-staged para formatear automáticamente antes de cada commit.
El orden de imports no es formateo - import/order es una regla de calidad de código que Prettier no maneja (Prettier no reordena imports). Solución: Mantén import/order en ESLint; no entra en conflicto con Prettier. Alternativamente, usa prettier-plugin-organize-imports.
Otras formas de resolver el mismo problema - y cuándo cada una es la mejor opción.
| Alternativa | Usalo Cuando | No lo Uses Cuando |
|---|---|---|
| Biome | Quieres linting + formateo en una herramienta sin conflictos | Necesitas el ecosistema de plugins de ESLint |
| Solo Prettier (sin ESLint) | Proyecto muy pequeño sin preocupaciones de calidad de código | Quieres detectar bugs, variables no utilizadas o violaciones de hooks |
| Solo ESLint (con reglas de formateo) | Te niegas a agregar otra herramienta | Quieres formateo consistente y opinionado |
extends para anular todas las configuraciones anteriores."prettier" se volverán a habilitar."prettier" al final en tu array de extends.npx eslint-config-prettier 'src/**/*.tsx'Esta herramienta CLI reporta exactamente qué reglas activas entran en conflicto con Prettier.
import/order es una regla de calidad de código, no una regla de formateo.{
"scripts": {
"lint": "next lint",
"lint:fix": "next lint --fix",
"format": "prettier --write .",
"format:check": "prettier --check .",
"fix-all": "npm run lint:fix && npm run format"
}
}Ejecútalas como comandos separados, no como una herramienta combinada.
{
"lint-staged": {
"*.{ts,tsx}": ["eslint --fix", "prettier --write"],
"*.{css,json,md}": ["prettier --write"]
}
}ESLint corrige problemas de calidad de código primero, luego Prettier formatea.
@typescript-eslint/no-unused-vars no se ven afectadas.eslint-config-prettier asegura que no haya superposición entre los dos.npm run format:check && npm run lintformat:check verifica que los archivos estén formateados sin modificarlos.lint ejecuta ESLint para la calidad de código.Revisado por Chris St. John·Última actualización: 19 jul 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥