How to Setup ESLint and Prettier for TypeScript Projects
Tuesday, Dec 23, 2025
Have you ever worked with a team where everyone’s code style is different? Some use single quotes, some use double quotes. Some indent with 2 spaces, some with 4. Not to mention unused variables that make code reviews drag on forever.
In this article, I’ll cover how to set up ESLint and Prettier for your TypeScript project. After this, your code will be more consistent and clean.
Why Do You Need ESLint and Prettier?
Before diving into the technical stuff, let’s understand why these two tools are important:
ESLint is a linter — a tool that checks your code for bugs, whether it follows best practices, and potential errors. Examples: unused variables, unreachable code, or using == instead of ===.
Prettier is a formatter — a tool that formats your code to be consistent. Examples: indentation, quotes, semicolons, line length, and more.
In short:
- ESLint → Find problems in code (code quality)
- Prettier → Make code tidy (code formatting)
Both are important and complement each other. ESLint focuses on what, Prettier focuses on how.
ESLint vs Prettier Differences
| Aspect | ESLint | Prettier |
|---|---|---|
| Function | Linting (find bugs & enforce rules) | Formatting (tidy up code) |
| Focus | Code quality | Code style |
| Customizable | Highly customizable | Opinionated (few options) |
| Auto-fix | Can fix some issues | Auto-fix all formatting |
Step-by-Step Installation
Okay, now let’s start the setup. Make sure you already have a TypeScript project ready.
1. Install Dependencies
First, install all required packages:
npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
npm install -D prettier eslint-config-prettier eslint-plugin-prettier
Quick explanation:
eslint— Core ESLint@typescript-eslint/parser— Parser for TypeScript@typescript-eslint/eslint-plugin— TypeScript-specific rulesprettier— Core Prettiereslint-config-prettier— Disable ESLint rules that conflict with Prettiereslint-plugin-prettier— Run Prettier as an ESLint rule
2. ESLint Configuration (.eslintrc.js)
Create file .eslintrc.js in project root:
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2021,
sourceType: 'module',
project: './tsconfig.json',
},
plugins: ['@typescript-eslint', 'prettier'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
'plugin:prettier/recommended',
],
rules: {
// TypeScript rules
'@typescript-eslint/explicit-function-return-type': 'warn',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'@typescript-eslint/no-explicit-any': 'warn',
// General rules
'no-console': 'warn',
'prefer-const': 'error',
// Prettier
'prettier/prettier': 'error',
},
ignorePatterns: ['node_modules/', 'dist/', 'build/'],
};
Tip: Use .eslintrc.js (JavaScript) instead of .eslintrc.json so you can add comments and logic if needed.
3. Prettier Configuration (.prettierrc)
Create file .prettierrc in project root:
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"useTabs": false,
"trailingComma": "es5",
"printWidth": 100,
"bracketSpacing": true,
"arrowParens": "always",
"endOfLine": "lf"
}
Option explanations:
semi: true— Use semicolonssingleQuote: true— Use single quotestabWidth: 2— Indent 2 spacestrailingComma: "es5"— Trailing comma in arrays and objectsprintWidth: 100— Max 100 characters per line
You can also create a .prettierignore file to exclude files:
node_modules/
dist/
build/
*.min.js
VS Code Integration
To make things smoother, let’s integrate with VS Code.
1. Install Extensions
Install these extensions in VS Code:
- ESLint (dbaeumer.vscode-eslint)
- Prettier - Code formatter (esbenp.prettier-vscode)
2. VS Code Settings
Create or update file .vscode/settings.json in your project:
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
],
"typescript.tsdk": "node_modules/typescript/lib"
}
With this config:
- Code will be formatted automatically on save
- ESLint auto-fix also runs on save
- Bye-bye manual formatting!
Pre-commit Hooks with Husky + lint-staged
To prevent bad code from being committed, let’s set up git hooks.
1. Install Husky and lint-staged
npm install -D husky lint-staged
npx husky init
2. Setup lint-staged
Add config in package.json:
{
"lint-staged": {
"*.{ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md}": [
"prettier --write"
]
}
}
3. Update Husky Hook
Edit file .husky/pre-commit:
npx lint-staged
Now, every time you commit, lint-staged will run ESLint and Prettier only for staged files. Efficient!
npm Scripts for Lint and Format
Add these scripts to package.json:
{
"scripts": {
"lint": "eslint . --ext .ts,.tsx",
"lint:fix": "eslint . --ext .ts,.tsx --fix",
"format": "prettier --write \"src/**/*.{ts,tsx,json,md}\"",
"format:check": "prettier --check \"src/**/*.{ts,tsx,json,md}\"",
"check": "npm run lint && npm run format:check"
}
}
How to use:
npm run lint— Check ESLint errorsnpm run lint:fix— Auto-fix ESLint errorsnpm run format— Format all filesnpm run format:check— Check formatting without modifyingnpm run check— Run all checks (good for CI/CD)
Troubleshooting: ESLint vs Prettier Conflicts
Sometimes ESLint and Prettier can conflict. Here are tips to handle it:
1. Make Sure eslint-config-prettier is Installed
This package disables all ESLint rules that conflict with Prettier. Make sure it’s installed and in extends:
extends: [
// ... other rules
'plugin:prettier/recommended', // MUST BE AT THE BOTTOM!
],
2. Check Conflicting Rules
Run this command to check conflicting rules:
npx eslint-config-prettier src/index.ts
3. “Delete ␍” Error on Windows
This is a line endings issue. Add this rule in .eslintrc.js:
rules: {
'prettier/prettier': ['error', { endOfLine: 'auto' }],
}
4. ESLint Not Running in VS Code
Try these steps:
- Restart VS Code
- Check Output panel (View → Output → ESLint)
- Make sure
node_modulesis installed - Check path in
.eslintrc.jsis correct
Bonus: Config for React + TypeScript
If your project uses React, add this:
npm install -D eslint-plugin-react eslint-plugin-react-hooks
Update .eslintrc.js:
module.exports = {
// ... previous config
plugins: ['@typescript-eslint', 'prettier', 'react', 'react-hooks'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:prettier/recommended',
],
settings: {
react: {
version: 'detect',
},
},
rules: {
'react/react-in-jsx-scope': 'off', // Not needed in React 17+
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
},
};
Conclusion
Setting up ESLint and Prettier does require effort upfront, but trust me, it’s totally worth it. Benefits you get:
- Code consistency — All developers write code with the same style
- Catch bugs early — ESLint can detect potential bugs before runtime
- Faster code review — No more debating about code style
- Better DX — Auto-format on save makes coding smoother
I recommend setting this up in every new project from the start. For existing projects, start slowly — enable rules one by one so it’s not overwhelming.
Happy coding! 🚀