Skip to content
← Back to Blog
Angular

How to Setup ESLint and Prettier in Angular 20 Projects Cómo Configurar ESLint y Prettier en Proyectos Angular 20

March 1, 2026 1 de marzo de 2026

How to Setup ESLint and Prettier in Angular 20 Projects

Angular dropped TSLint years ago and ships with ESLint support via @angular-eslint. But getting ESLint and Prettier working together — without them fighting each other — still trips people up. This is the guide I wish I had.

What You’re Setting Up

  • ESLint: catches code quality issues, enforces rules
  • Prettier: formats code (indentation, quotes, line length)
  • eslint-config-prettier: disables ESLint formatting rules that conflict with Prettier
  • Husky + lint-staged: runs both on every commit automatically

Step 1: Add Angular ESLint

For a new project:

ng new my-app --strict

For an existing project:

ng add @angular-eslint/schematics

This adds @angular-eslint/eslint-plugin, @angular-eslint/template-parser, and creates eslint.config.js (Angular 20 uses flat config by default).

Step 2: Install Prettier

npm install --save-dev prettier eslint-config-prettier

eslint-config-prettier is critical — it turns off all ESLint rules that could conflict with Prettier’s formatting decisions.

Step 3: Configure Prettier

Create .prettierrc at the project root:

{
  "semi": false,
  "singleQuote": true,
  "trailingComma": "all",
  "printWidth": 100,
  "tabWidth": 2,
  "bracketSpacing": true,
  "arrowParens": "always"
}

And .prettierignore:

dist/
.angular/
node_modules/
coverage/

Step 4: Update eslint.config.js

Angular 20 generates a flat config. Add prettier to the extends to disable conflicting rules:

// eslint.config.js
import angular from 'angular-eslint'
import tseslint from 'typescript-eslint'
import prettier from 'eslint-config-prettier'

export default tseslint.config(
  {
    files: ['**/*.ts'],
    extends: [
      ...tseslint.configs.recommended,
      ...angular.configs.tsRecommended,
      prettier, // must be last — disables conflicting rules
    ],
    processor: angular.processInlineTemplates,
    rules: {
      '@angular-eslint/directive-selector': ['error', { type: 'attribute', prefix: 'app', style: 'camelCase' }],
      '@angular-eslint/component-selector': ['error', { type: 'element', prefix: 'app', style: 'kebab-case' }],
      '@typescript-eslint/no-explicit-any': 'warn',
      '@typescript-eslint/explicit-function-return-type': 'off',
    },
  },
  {
    files: ['**/*.html'],
    extends: [
      ...angular.configs.templateRecommended,
      ...angular.configs.templateAccessibility,
    ],
    rules: {},
  },
)

Step 5: Add Scripts to package.json

{
  "scripts": {
    "lint": "ng lint",
    "lint:fix": "ng lint --fix",
    "format": "prettier --write \"src/**/*.{ts,html,scss,css,json}\"",
    "format:check": "prettier --check \"src/**/*.{ts,html,scss,css,json}\""
  }
}

Step 6: VS Code Integration

Install the ESLint and Prettier extensions, then add to .vscode/settings.json:

{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[html]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }
}

Step 7: Pre-commit Hook with Husky + lint-staged

npm install --save-dev husky lint-staged
npx husky init

Add to package.json:

{
  "lint-staged": {
    "*.ts": ["eslint --fix", "prettier --write"],
    "*.html": ["prettier --write"],
    "*.{scss,css,json}": ["prettier --write"]
  }
}

Update .husky/pre-commit:

npx lint-staged

Now every commit is automatically linted and formatted. No more “you forgot to format this” in code reviews.

Verify Everything Works

npm run lint
npm run format:check

Both should pass on a clean project. If ESLint and Prettier conflict on something, eslint-config-prettier is doing its job — Prettier wins on formatting, ESLint wins on logic.

That’s the setup. It takes 10 minutes and saves hours of style debates.

Cómo Configurar ESLint y Prettier en Proyectos Angular 20

Angular abandonó TSLint hace años y viene con soporte de ESLint via @angular-eslint. Pero hacer que ESLint y Prettier funcionen juntos — sin que se peleen — todavía le cuesta a la gente. Esta es la guía que me hubiera gustado tener.

Qué Vas a Configurar

  • ESLint: detecta problemas de calidad de código, aplica reglas
  • Prettier: formatea código (indentación, comillas, largo de línea)
  • eslint-config-prettier: desactiva las reglas de formateo de ESLint que conflictúan con Prettier
  • Husky + lint-staged: ejecuta ambos en cada commit automáticamente

Paso 1: Agregar Angular ESLint

Para un proyecto nuevo:

ng new my-app --strict

Para un proyecto existente:

ng add @angular-eslint/schematics

Esto agrega @angular-eslint/eslint-plugin, @angular-eslint/template-parser, y crea eslint.config.js (Angular 20 usa flat config por defecto).

Paso 2: Instalar Prettier

npm install --save-dev prettier eslint-config-prettier

eslint-config-prettier es crítico — desactiva todas las reglas de ESLint que podrían conflictuar con las decisiones de formateo de Prettier.

Paso 3: Configurar Prettier

Crea .prettierrc en la raíz del proyecto:

{
  "semi": false,
  "singleQuote": true,
  "trailingComma": "all",
  "printWidth": 100,
  "tabWidth": 2,
  "bracketSpacing": true,
  "arrowParens": "always"
}

Y .prettierignore:

dist/
.angular/
node_modules/
coverage/

Paso 4: Actualizar eslint.config.js

Angular 20 genera flat config. Agrega prettier al extends para desactivar las reglas conflictivas:

// eslint.config.js
import angular from 'angular-eslint'
import tseslint from 'typescript-eslint'
import prettier from 'eslint-config-prettier'

export default tseslint.config(
  {
    files: ['**/*.ts'],
    extends: [
      ...tseslint.configs.recommended,
      ...angular.configs.tsRecommended,
      prettier, // debe ir último — desactiva reglas conflictivas
    ],
    processor: angular.processInlineTemplates,
    rules: {
      '@angular-eslint/directive-selector': ['error', { type: 'attribute', prefix: 'app', style: 'camelCase' }],
      '@angular-eslint/component-selector': ['error', { type: 'element', prefix: 'app', style: 'kebab-case' }],
      '@typescript-eslint/no-explicit-any': 'warn',
      '@typescript-eslint/explicit-function-return-type': 'off',
    },
  },
  {
    files: ['**/*.html'],
    extends: [
      ...angular.configs.templateRecommended,
      ...angular.configs.templateAccessibility,
    ],
    rules: {},
  },
)

Paso 5: Agregar Scripts a package.json

{
  "scripts": {
    "lint": "ng lint",
    "lint:fix": "ng lint --fix",
    "format": "prettier --write \"src/**/*.{ts,html,scss,css,json}\"",
    "format:check": "prettier --check \"src/**/*.{ts,html,scss,css,json}\""
  }
}

Paso 6: Integración con VS Code

Instala las extensiones de ESLint y Prettier, luego agrega a .vscode/settings.json:

{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[html]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }
}

Paso 7: Pre-commit Hook con Husky + lint-staged

npm install --save-dev husky lint-staged
npx husky init

Agrega a package.json:

{
  "lint-staged": {
    "*.ts": ["eslint --fix", "prettier --write"],
    "*.html": ["prettier --write"],
    "*.{scss,css,json}": ["prettier --write"]
  }
}

Actualiza .husky/pre-commit:

npx lint-staged

Ahora cada commit se lintea y formatea automáticamente. Adiós a los “te olvidaste de formatear esto” en code reviews.

Verificar Que Todo Funciona

npm run lint
npm run format:check

Ambos deberían pasar en un proyecto limpio. Si ESLint y Prettier conflictúan en algo, eslint-config-prettier está haciendo su trabajo — Prettier gana en formateo, ESLint gana en lógica.

Eso es todo. 10 minutos de setup, horas de debates de estilo ahorradas.

← Back to Blog