Table of Contents
- Introduction
- Why Linting and Formatting Are Critical
- What is ESLint?
- What is Prettier?
- How ESLint and Prettier Work Together
- Setting Up ESLint in a TypeScript Project
- Installing Dependencies
- Configuring ESLint
- Common ESLint Rules for TypeScript
- Setting Up Prettier
- Installing Prettier
- Configuring Prettier
- Integrating ESLint with Prettier
- Adding Scripts to
package.json
- Best Practices for Linting and Formatting
- Conclusion
Introduction
Maintaining clean, consistent, and error-free code is crucial in any project — especially TypeScript, where large teams often collaborate on a growing codebase.
Linting catches mistakes early, and formatting ensures that code style is consistent.
Together, ESLint and Prettier create a robust development workflow that reduces bugs and increases readability.
In this guide, we’ll do a deep dive into setting up ESLint and Prettier in a TypeScript project.
Why Linting and Formatting Are Critical
- Error Prevention: Catch potential bugs, bad practices, and typos early.
- Code Consistency: Make your codebase readable for anyone at any time.
- Team Collaboration: Remove style disputes; formatting is automatic.
- Faster Reviews: Clean code means reviewers can focus on logic, not syntax.
- Increased Productivity: Save time on manual formatting and nitpicking.
What is ESLint?
ESLint is a linter for JavaScript and TypeScript.
It analyzes your code to:
- Find syntax errors
- Highlight code smells
- Enforce coding standards
- Offer auto-fixes for common issues
TypeScript + ESLint is a powerful combo that catches both type-related and general code issues.
What is Prettier?
Prettier is an opinionated code formatter.
It reformats your code automatically according to a set of rules (line width, indentation, quotes, semicolons, etc.).
Unlike ESLint, Prettier doesn’t care about “correctness” — it cares about consistent style.
How ESLint and Prettier Work Together
- ESLint → Focuses on code quality (errors, bad practices).
- Prettier → Focuses on code style (formatting).
They overlap a little, but when properly integrated:
- ESLint catches errors.
- Prettier formats code automatically.
- They don’t fight each other.
Setting Up ESLint in a TypeScript Project
1. Installing Dependencies
npm install --save-dev eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin
eslint
: Main ESLint package@typescript-eslint/parser
: Parses TypeScript for ESLint@typescript-eslint/eslint-plugin
: Official TypeScript plugin for ESLint rules
2. Configuring ESLint
Create a .eslintrc.js
file:
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
},
plugins: ['@typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
],
rules: {
// Your custom rules
'@typescript-eslint/no-unused-vars': ['error'],
'@typescript-eslint/explicit-function-return-type': 'off',
},
ignorePatterns: ['dist/', 'node_modules/'],
};
- parser: Tells ESLint to understand TypeScript.
- extends: Includes recommended ESLint and TypeScript rules.
- rules: Customize or override specific linting behaviors.
3. Common ESLint Rules for TypeScript
@typescript-eslint/no-explicit-any
: Warns about use ofany
.@typescript-eslint/explicit-module-boundary-types
: Enforces explicit return types on module boundaries.@typescript-eslint/consistent-type-definitions
: Enforces consistent use ofinterface
ortype
.@typescript-eslint/no-non-null-assertion
: Warns when using!
after variables (can cause runtime errors).
You can fine-tune these rules according to your project needs.
Setting Up Prettier
1. Installing Prettier
npm install --save-dev prettier
Optional: Install ESLint-Prettier integration plugins:
npm install --save-dev eslint-config-prettier eslint-plugin-prettier
eslint-config-prettier
: Turns off ESLint rules that conflict with Prettier.eslint-plugin-prettier
: Runs Prettier as an ESLint rule.
2. Configuring Prettier
Create a .prettierrc
file:
{
"semi": true,
"singleQuote": true,
"printWidth": 80,
"tabWidth": 2,
"trailingComma": "all",
"arrowParens": "always"
}
You can also add a .prettierignore
file:
node_modules
dist
build
coverage
Integrating ESLint with Prettier
Update your .eslintrc.js
:
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
},
plugins: ['@typescript-eslint', 'prettier'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended', // Important: Add Prettier last
],
rules: {
'prettier/prettier': 'error', // Prettier errors are shown as ESLint errors
},
ignorePatterns: ['dist/', 'node_modules/'],
};
This ensures:
- Prettier formats your code.
- Prettier mistakes are surfaced during linting.
Adding Scripts to package.json
To make your life easier, add these scripts:
{
"scripts": {
"lint": "eslint 'src/**/*.{ts,tsx}'",
"lint:fix": "eslint 'src/**/*.{ts,tsx}' --fix",
"format": "prettier --write 'src/**/*.{ts,tsx,json,md}'"
}
}
Now you can:
npm run lint
: Run ESLint.npm run lint:fix
: Auto-fix lint issues.npm run format
: Format all files using Prettier.
Best Practices for Linting and Formatting
- Always lint before pushing: Make it a habit or automate it in CI/CD.
- Use Prettier auto-format on save: Set it up in your code editor (VSCode recommended).
- Keep config files version-controlled:
.eslintrc
,.prettierrc
, etc. - Don’t fight Prettier: Adjust settings slightly if needed but embrace its philosophy.
- Group ESLint and Prettier together: Always integrate them so you get best of both.
Conclusion
Linting and formatting are non-negotiable practices in professional TypeScript development.
When set up correctly, ESLint + Prettier create a smooth, error-free, and highly productive environment that keeps your project scalable and maintainable.
With this setup, you’ll spend less time arguing over code style and more time building amazing things.