Linting and Formatting: ESLint + Prettier for TypeScript

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 of any.
  • @typescript-eslint/explicit-module-boundary-types: Enforces explicit return types on module boundaries.
  • @typescript-eslint/consistent-type-definitions: Enforces consistent use of interface or type.
  • @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.