Configure Prettier and ESLint with Angular 🎨
Everyone wants to write code in a fast bug-free way without thinking about its style most of the time. That’s why in this post I will talk about configuring ESLint and Prettier in an Angular project.
How does ESLint help?
By statically analyzing our code, ESLint can find problems and also suggest us fixes for them. And it can do better than that, it can fix our code automatically (who doesn’t want that?).
Install and configure ESLint
In this section, I will explain how to install ESLint in an Angular project and also configure it to better align with the Angular style guide and community standards.
Open the terminal and install ESLint schematics using this command:
ng add @angular-eslint/schematics
That was it. Now we have ESLint installed and also configured thanks to ng add
command provided by the Angular-ESLint team.
Example error and how ESLint helps to fix it:
ESLint error about Angular input binding alias
ESLint quick fix for Angular Input aliasing
We can also run this command in terminal:
ng lint --fix
to fix all the fixable bugs in the project.
Install and configure Prettier
Even if we have ESLint watching our code for bugs, we also need a tool to better style and format it. That’s where Prettier comes into play.
Prettier is an opinionated code formatter that helps us beautify code in a standardized way every time we save the code.
Open terminal and type:
npm install prettier --save-dev
or if you’re using yarn :
yarn add prettier -D
Then we need to add .prettierrc.json and .prettierignore files in our root project directory.
Inside .prettierignore it’s better to add whatever we have inside .gitignore file.
Then we can run this command inside our project to format it.
npx prettier --write .
Inside .prettierrc.json we can change the default settings by overriding them.
The settings I use most of the time are this:
{
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"semi": true,
"bracketSpacing": true,
"arrowParens": "avoid",
"trailingComma": "es5",
"bracketSameLine": true,
"printWidth": 80
}
That’s it about Prettier. But we are not finished.
There are times where ESLint and Prettier have different opinions about code formatting and style. That’s why we need to tweak this part. More info here.
Configure Prettier to be used as an ESLint plugin
For ESLint and Prettier to play well together, we need to run Prettier as an ESLint plugin. This way we can just call ng lint — fix and ESLint will fix bugs but also format the code.
Open terminal and type:
npm install prettier-eslint eslint-config-prettier eslint-plugin-prettier --save-dev
or
yarn add prettier-eslint eslint-config-prettier eslint-plugin-prettier -D
Now we need to edit the .eslintrc.json file to include the prettier plugin.
{
"root": true,
"overrides": [
{
"files": ["*.ts"],
"extends": [
...
"plugin:prettier/recommended"
],
},
// NOTE: WE ARE NOT APPLYING PRETTIER IN THIS OVERRIDE, ONLY @ANGULAR-ESLINT/TEMPLATE
{
"files": ["*.html"],
"extends": ["plugin:@angular-eslint/template/recommended"],
"rules": {}
},
// NOTE: WE ARE NOT APPLYING @ANGULAR-ESLINT/TEMPLATE IN THIS OVERRIDE, ONLY PRETTIER
{
"files": ["*.html"],
"excludedFiles": ["*inline-template-*.component.html"],
"extends": ["plugin:prettier/recommended"],
"rules": {
// NOTE: WE ARE OVERRIDING THE DEFAULT CONFIG TO ALWAYS SET THE PARSER TO ANGULAR (SEE BELOW)
"prettier/prettier": ["error", { "parser": "angular" }]
}
}
]
}
Extra features
Remove unused imports
We can automatically remove unused imports by using the eslint-plugin-unused-imports plugin.
npm install eslint-plugin-unused-imports --save-dev
NOTE: If version 4.x doesn't work, try version 3.x
Then we can add it to the plugins
array in the ESLint configuration.
{
"root": true,
// ... root level configuration
"plugins": ["unused-imports"],
"overrides": [
{
"files": ["*.ts"],
// ..
"rules": {
"unused-imports/no-unused-imports": "error"
}
}
]
}
---
### Sort imports
We can sort imports by using the [eslint-plugin-simple-import-sort](https://www.npmjs.com/package/eslint-plugin-simple-import-sort) plugin.
```bash
npm install eslint-plugin-simple-import-sort --save-dev
Then we can add it to the plugins
array in the ESLint configuration.
{
"root": true,
// ... root level configuration
"plugins": ["simple-import-sort"],
"overrides": [
{
"files": ["*.ts"],
// ..
"rules": {
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
}
}
]
}
Angular new control flow and @let syntax support
Prettier v3 supports the new control flow. Support for the @let
syntax was added in v3.3.3.
If it still doesn't work, try upgrading to the latest version of prettier
and eslint-plugin-prettier
packages.
Flat config configurations
I won't go much into details here, but if you're using the flat configuration (eslint.config.js
) than this is how you can configure prettier and eslint for Angular.
// @ts-check
const eslint = require('@eslint/js');
const tseslint = require('typescript-eslint');
const angular = require('angular-eslint');
const unusedImports = require('eslint-plugin-unused-imports');
const eslintPluginPrettierRecommended = require('eslint-plugin-prettier/recommended');
module.exports = tseslint.config(
{
files: ['**/*.ts'],
plugins: {
// @ts-ignore
'unused-imports': unusedImports,
},
extends: [
eslint.configs.recommended,
...tseslint.configs.recommended,
...tseslint.configs.stylistic,
...angular.configs.tsRecommended,
eslintPluginPrettierRecommended,
],
processor: angular.processInlineTemplates,
rules: {
'no-unused-vars': 'off',
'unused-imports/no-unused-imports': 'error',
'unused-imports/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_',
},
],
},
},
{
files: ['**/*.html'],
extends: [
...angular.configs.templateRecommended,
...angular.configs.templateAccessibility,
],
rules: {},
}
);
{
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"semi": true,
"bracketSpacing": true,
"arrowParens": "avoid",
"trailingComma": "es5",
"bracketSameLine": true,
"printWidth": 80,
"overrides": [
{
"files": "*.html",
"options": {
"parser": "angular"
}
}
]
}
These two should just work fine same as before with the other configuration.
VSCode and Webstorm shortcuts
That was it. We’re done with the configuration part.
After we edit a file, we want to format it and then save. That’s what we will configure now for both VS Code and Webstorm.
First make sure you have ESLint and Prettier plugin installed. WebStorm has support out-of-the-box for both.
For VS Code we need to add this lines to settings.json:
{
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.formatOnSave": false
},
"[typescript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.formatOnSave": false
},
}
For Webstorm: We need to check: Run eslint — fix on Actions On Save settings page:
Webstorm Fix File on save
Here you can find the steps summed up: Angular ESLint & Prettier Configuration
How to automate all these configurations?
As you saw, there are a lot of packages that you should install and configure. And I can tell you confidently that there is a way to manage all these automatically. Nx is the answer.
What is NX?
NX is the next generation build system with first-class monorepo support and powerful integrations.
If we migrate our Angular app to an Nx monorepo (there is a straightforward migration path) we get all those configurations for free out-of-the-box.
But what makes NX special are some crazy features like computation caching, smart rebuilds, distributed task execution, remote build caching, powerful code generators, editor plugins , etc.
Thanks for reading!
If this article was interesting and useful to you, and you want to learn more about Angular, support me by buying me a coffee ☕️ or follow me on X (formerly Twitter) @Enea_Jahollari where I tweet and blog a lot about Angular
latest news, signals, videos, podcasts, updates, RFCs, pull requests and so much more. 💎