
Linting and Formatting with ESLint in VS Code
ESLint is a static code analysis tool that catches bugs, enforces coding standards, and improves JavaScript/TypeScript code quality before it hits production. When integrated with VS Code, it transforms your editor into a powerful development environment that provides real-time feedback, automatic fixes, and consistent code formatting across your entire team. This guide covers everything from basic setup to advanced configurations, troubleshooting common issues, and implementing ESLint in various project scenarios.
How ESLint Works in VS Code
ESLint operates as a linter that parses your JavaScript code into an Abstract Syntax Tree (AST), then runs configurable rules against this tree to identify potential problems. The VS Code ESLint extension acts as a bridge between the editor and the ESLint engine, providing real-time analysis as you type.
The workflow looks like this:
- ESLint reads configuration files (.eslintrc.js, .eslintrc.json, or package.json)
- The extension watches for file changes in supported languages
- Code gets parsed and analyzed against active rules
- Issues appear as squiggly underlines with hover details
- Quick fixes and auto-formatting become available through command palette
ESLint supports over 200 built-in rules covering potential errors, best practices, stylistic issues, and ES6+ features. Popular rule sets like Airbnb, Standard, and Google provide pre-configured rule collections that teams can adopt wholesale or customize.
Step-by-Step Setup Guide
Getting ESLint running in VS Code requires installing both the npm package and the VS Code extension. Here’s the complete setup process:
Install ESLint Extension
Open VS Code and install the official ESLint extension by Microsoft (ms-vscode.vscode-eslint). This extension has over 20 million downloads and provides the core integration between VS Code and ESLint.
Initialize ESLint in Your Project
npm install eslint --save-dev
npx eslint --init
The initialization wizard asks several questions:
- How would you like to use ESLint? (check syntax, find problems, enforce style)
- What type of modules does your project use? (JavaScript modules, CommonJS, none)
- Which framework does your project use? (React, Vue.js, none)
- Does your project use TypeScript? (Yes/No)
- Where does your code run? (Browser, Node)
- What format do you want your config file to be in? (JavaScript, YAML, JSON)
Basic Configuration Example
Here’s a typical .eslintrc.js configuration for a React TypeScript project:
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
extends: [
'eslint:recommended',
'@typescript-eslint/recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 12,
sourceType: 'module',
},
plugins: [
'react',
'@typescript-eslint',
'react-hooks',
],
rules: {
'no-unused-vars': 'warn',
'no-console': 'warn',
'react/prop-types': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'warn',
},
settings: {
react: {
version: 'detect',
},
},
};
VS Code Settings Configuration
Add these settings to your VS Code settings.json for optimal ESLint integration:
{
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
],
"eslint.format.enable": true,
"eslint.codeAction.showDocumentation": {
"enable": true
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.formatOnSave": true,
"[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"[typescript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
}
}
Real-World Examples and Use Cases
Enterprise React Application
Large React applications benefit from strict ESLint configurations that catch common bugs and enforce consistent patterns. Here’s a production-ready setup:
module.exports = {
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:jsx-a11y/recommended',
'plugin:import/errors',
'plugin:import/warnings',
'plugin:import/typescript',
],
rules: {
'import/order': ['error', {
'groups': ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
'newlines-between': 'always',
'alphabetize': { 'order': 'asc' }
}],
'react/jsx-sort-props': 'error',
'prefer-const': 'error',
'no-var': 'error',
'@typescript-eslint/no-unused-vars': ['error', { 'argsIgnorePattern': '^_' }],
}
};
Node.js API Server
Backend applications need different rule sets focusing on security and performance:
module.exports = {
env: {
node: true,
es2021: true,
},
extends: [
'eslint:recommended',
'plugin:security/recommended',
'plugin:node/recommended',
],
plugins: ['security', 'node'],
rules: {
'no-console': 'off',
'security/detect-object-injection': 'error',
'security/detect-non-literal-regexp': 'error',
'node/no-unpublished-require': 'off',
'node/exports-style': ['error', 'module.exports'],
}
};
Monorepo Configuration
Large codebases with multiple packages need hierarchical ESLint configurations:
// Root .eslintrc.js
module.exports = {
root: true,
extends: ['eslint:recommended'],
env: {
node: true,
},
overrides: [
{
files: ['packages/frontend/**/*.{js,ts,tsx}'],
env: { browser: true },
extends: ['plugin:react/recommended'],
},
{
files: ['packages/backend/**/*.{js,ts}'],
env: { node: true },
extends: ['plugin:node/recommended'],
},
],
};
Comparison with Alternative Tools
Tool | Primary Focus | Configuration Complexity | Performance | VS Code Integration | Ecosystem |
---|---|---|---|---|---|
ESLint | Linting + Formatting | Medium | Fast | Excellent | Largest |
Prettier | Code Formatting | Low | Very Fast | Excellent | Good |
TSLint (Deprecated) | TypeScript Linting | Medium | Moderate | Good | Legacy |
JSHint | JavaScript Linting | Low | Fast | Basic | Small |
StandardJS | Opinionated Linting | None | Fast | Good | Medium |
ESLint vs Prettier Integration
Many teams use ESLint and Prettier together, with ESLint handling code quality rules and Prettier managing formatting. This requires careful configuration to avoid conflicts:
npm install --save-dev eslint-config-prettier eslint-plugin-prettier
// .eslintrc.js
module.exports = {
extends: [
'eslint:recommended',
'prettier', // Disables ESLint formatting rules
],
plugins: ['prettier'],
rules: {
'prettier/prettier': 'error', // Shows prettier issues as ESLint errors
},
};
Performance Optimization and Troubleshooting
Common Performance Issues
Large codebases can experience slow ESLint performance. Here are optimization strategies:
- Use .eslintignore to exclude node_modules, build directories, and generated files
- Configure VS Code to lint only open files in large projects
- Disable expensive rules in development, enable them in CI
- Use ESLint cache for faster subsequent runs
// .eslintignore
node_modules/
dist/
build/
coverage/
*.min.js
public/
// package.json script with caching
{
"scripts": {
"lint": "eslint . --cache --cache-location .eslintcache"
}
}
VS Code Settings for Large Projects
{
"eslint.workingDirectories": ["src"],
"eslint.options": {
"cache": true,
"cacheLocation": ".eslintcache"
},
"eslint.run": "onType",
"eslint.validate": [
"javascript",
"typescript"
]
}
Troubleshooting Common Issues
ESLint not working in VS Code:
- Check ESLint extension is installed and enabled
- Verify ESLint is installed in project (npm list eslint)
- Look for configuration file in project root
- Check VS Code Output panel for ESLint errors
- Restart ESLint server: Ctrl+Shift+P β “ESLint: Restart ESLint Server”
Rules not applying correctly:
- Check rule inheritance order in extends array
- Verify parser options match your code (ECMAScript version, modules)
- Use ESLint CLI to test rules outside VS Code
- Check for conflicting configurations in parent directories
Performance problems:
- Add more entries to .eslintignore
- Disable rules that require type information if not needed
- Use overrides to apply different rule sets to different file patterns
- Consider using eslint-nibble to identify slow rules
Advanced Configuration and Best Practices
Custom Rule Development
Teams can create custom ESLint rules for organization-specific patterns:
// eslint-local-rules.js
module.exports = {
'no-relative-imports': {
meta: {
type: 'suggestion',
docs: {
description: 'Disallow relative imports beyond parent directory',
},
},
create(context) {
return {
ImportDeclaration(node) {
const importPath = node.source.value;
if (importPath.startsWith('../../')) {
context.report({
node,
message: 'Avoid deep relative imports, use absolute imports instead',
});
}
},
};
},
},
};
CI/CD Integration
ESLint works excellently in continuous integration pipelines:
# GitHub Actions example
name: ESLint Check
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16'
- run: npm ci
- run: npm run lint -- --format=junit --output-file=eslint-report.xml
- uses: actions/upload-artifact@v2
with:
name: eslint-report
path: eslint-report.xml
Team Configuration Management
Successful ESLint adoption requires team-wide configuration standards:
- Use shared configurations published as npm packages
- Document rule decisions and exceptions
- Implement gradual rule adoption with warning levels
- Set up pre-commit hooks to catch issues early
- Provide VS Code workspace settings in version control
// .vscode/settings.json (committed to repository)
{
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"typescript.preferences.includePackageJsonAutoImports": "off"
}
Security and Dependency Management
When deploying ESLint in production environments, especially on managed services like VPS or dedicated servers, consider these security practices:
- Regularly update ESLint and plugins to patch security vulnerabilities
- Use npm audit to check for known vulnerabilities in ESLint dependencies
- Implement the security plugin for Node.js applications
- Configure ESLint to run in CI environments with restricted permissions
For additional information about ESLint configuration and advanced usage, refer to the official ESLint documentation and the VS Code ESLint extension documentation.

This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.
This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.