Skip to content
ESLint Guide — JavaScript and TypeScript Linting Best Practices

ESLint Guide — JavaScript and TypeScript Linting Best Practices

DodaTech Updated Jun 7, 2026 7 min read

ESLint is a static code analysis tool for finding and fixing problems in JavaScript and TypeScript code — catching bugs, enforcing style rules, and maintaining consistency across your codebase without running your application.

What You’ll Learn

  • Setting up ESLint with the modern flat config format
  • Configuring rules, plugins, and extends presets
  • Fixing issues automatically with --fix
  • Setting up TypeScript-specific linting rules
  • Integrating ESLint with VS Code, WebStorm, and CI
  • Creating custom rules for project-specific needs

Why ESLint Matters

Code style is subjective, but consistency is not — inconsistent formatting, unused variables, and unreachable code create real bugs and reduce readability. ESLint automates code review for the kind of issues that humans miss or shouldn’t have to check: missing semicolons, undeclared variables, implicit type coercions, and security vulnerabilities. Durga Antivirus Pro uses ESLint with strict rules to ensure the codebase doesn’t have unsafe patterns that could introduce vulnerabilities through eval() calls or insecure regex patterns.

    flowchart LR
    A[JavaScript & TypeScript Basics] --> B[ESLint]
    B --> C[Rules]
    B --> D[Plugins]
    B --> E[Flat Config]
    B --> F[--fix]
    C --> G[Error Prevention]
    D --> H[Framework Rules]
    E --> I[Modern Configuration]
    style B fill:#4b32c3,color:#fff
  
Prerequisites: Solid JavaScript and TypeScript knowledge. Basic understanding of Node.js and npm/package managers.

Core Concepts

Installation and Flat Config

npm init @eslint/config
# Or manual setup:
npm install -D eslint
// eslint.config.js — the modern "flat config" format
import js from "@eslint/js";
import tseslint from "typescript-eslint";

export default [
  // Base recommended rules
  js.configs.recommended,

  // TypeScript-specific rules
  ...tseslint.configs.recommended,

  // Project-specific customizations
  {
    rules: {
      "no-unused-vars": "error",
      "no-console": "warn",
      "prefer-const": "error",
      "eqeqeq": ["error", "always"],
      "@typescript-eslint/explicit-function-return-type": "warn",
    },
  },

  // Ignore patterns
  {
    ignores: ["dist/", "node_modules/", "*.config.js"],
  },
];

Output: The flat config is an array of configuration objects. Each object can have rules, plugins, files, and ignores. The recommended presets provide sensible defaults — you override what matters for your project.

Rules — What ESLint Checks

// eslint.config.js — rule severity levels
// "off" (0) — don't check
// "warn" (1) — show warning, don't fail
// "error" (2) — show error, fail the build

{
  rules: {
    // Possible errors — catch real bugs
    "no-cond-assign": "error",          // if (a = b) — probably meant ===
    "no-constant-condition": "error",   // if (true) — probably unintentional
    "no-duplicate-case": "error",       // Duplicate case in switch

    // Best practices
    "curly": ["error", "all"],          // Always use curly braces
    "default-case": "error",            // Always have default in switch
    "no-eval": "error",                 // eval() is dangerous
    "no-implied-eval": "error",         // setTimeout("code") is dangerous

    // Style (auto-fixable)
    "semi": ["error", "always"],        // Require semicolons
    "quotes": ["error", "double"],      // Use double quotes
    "comma-dangle": ["error", "always-multiline"],  // Trailing commas
  },
}

Output: ESLint scans your files and reports violations with file, line number, and severity. Rules with a 🔧 symbol are auto-fixable with --fix.

Plugins — Framework-Specific Rules

npm install -D eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-import
// eslint.config.js with plugins
import react from "eslint-plugin-react";
import reactHooks from "eslint-plugin-react-hooks";
import importPlugin from "eslint-plugin-import";

export default [
  {
    plugins: {
      react,
      "react-hooks": reactHooks,
      import: importPlugin,
    },
    rules: {
      "react/jsx-no-target-blank": "error",
      "react/jsx-key": "error",
      "react-hooks/rules-of-hooks": "error",
      "react-hooks/exhaustive-deps": "warn",
      "import/no-unused-modules": "error",
      "import/order": ["error", { alphabetize: { order: "asc" } }],
    },
  },
];

Output: Plugins extend ESLint with domain-specific rules. The React plugin catches JSX issues and missing keys. The hooks plugin enforces the Rules of Hooks. The import plugin validates import ordering.

Auto-Fix with –fix

# Fix all auto-fixable issues
npx eslint src/ --fix

# Check without fixing (CI)
npx eslint src/

# Output:
# /src/app.tsx
#   3:1  error  'unusedVar' is defined but never used  no-unused-vars
#   5:5  error  Strings must use doublequote           quotes
#   8:3  error  Expected '===' and instead saw '=='    eqeqeq
#
# ✖ 3 problems (3 errors, 0 warnings)
#   2 problems auto-fixable with --fix

Output: ESLint outputs errors with file path, line, column, message, and rule name. The --fix flag automatically fixes style issues (quotes, semicolons, indentation) but not logic issues (unused vars, === vs ==).

Integration with Editors and CI

// .vscode/settings.json — VS Code auto-fix on save
{
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "eslint.validate": ["javascript", "typescript", "javascriptreact", "typescriptreact"]
}
# .github/workflows/ci.yml — CI integration
name: Lint
on: [pull_request]
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
      - run: npm ci
      - run: npx eslint src/

Common Mistakes

  1. Using the old .eslintrc format in new projects: The flat config (eslint.config.js) is the modern standard. .eslintrc files are deprecated and may not support newer ESLint features.

  2. Disabling rules globally instead of for specific lines: /* eslint-disable */ at the top of a file disables ALL rules for the entire file. Use // eslint-disable-next-line no-eval for targeted suppression.

  3. Not running ESLint in CI: Without CI enforcement, team members can merge code with eslint-disable comments and rule violations. CI lint should fail on errors, warn on warnings.

  4. Overriding @typescript-eslint rules incorrectly: TypeScript rules require type information. Without parserOptions.project, rules like @typescript-eslint/no-floating-promises won’t work.

  5. Using too many plugins with conflicting rules: Some plugins conflict (e.g., Prettier vs ESLint formatting rules). Use eslint-config-prettier to disable formatting rules that Prettier handles.

Practice Questions

  1. What’s the difference between ESLint rules and plugins? Answer: Rules are individual checks (e.g., no-eval). Plugins bundle multiple related rules for a specific framework or domain (e.g., eslint-plugin-react).

  2. How does the flat config differ from the old .eslintrc format? Answer: Flat config is a JavaScript array of objects instead of a nested JSON object. It eliminates configuration cascading and makes the final config more predictable.

  3. What does the --fix flag do? Answer: It automatically applies auto-fixable rule corrections — primarily style rules like quotes, semicolons, and indentation. It doesn’t fix logical errors.

  4. How do you suppress a rule for a single line? Answer: Add // eslint-disable-next-line rule-name on the line above the violation, or // eslint-disable-line rule-name at the end of the violating line.

Challenge

Set up ESLint for a TypeScript React monorepo: create separate configs for frontend and backend packages, add React hooks and import ordering plugins, configure no-eval as an error (for security), set up VS Code to auto-fix on save, and create a CI workflow that runs ESLint on pull requests.

FAQ

Should I use ESLint or Prettier?
: Both. ESLint catches code quality issues, Prettier handles formatting. Use eslint-config-prettier to disable ESLint rules that conflict with Prettier.
Does ESLint support TypeScript?
: Yes. Use typescript-eslint (the @typescript-eslint/parser and @typescript-eslint/eslint-plugin) for full TypeScript support.
Can ESLint find security vulnerabilities?
: ESLint can catch some security issues (no-eval, no-implied-eval). For comprehensive security scanning, pair ESLint with tools like eslint-plugin-security.
How do I migrate from .eslintrc to flat config?
: Use npx eslint --init to generate a flat config. Manually merge your existing rule overrides. The flat config is incompatible with the old format — you must choose one.
Why is my ESLint config not working?
: Common issues: flat config vs old format mismatch, missing parserOptions for TypeScript, conflicting plugins, or rules not registered in the correct config object.

Try It Yourself

mkdir eslint-demo && cd eslint-demo
npm init -y
npm install -D eslint

# Create a file with issues
cat > test.js << 'EOF'
var x = 1
var x = 2
if (x = 3) {
  console.log(eval("x"))
}
EOF

# Run ESLint
npx eslint test.js
# Watch it catch redeclared vars, assignment in condition, and eval

# Fix automatically
npx eslint test.js --fix

What’s Next

TopicDescription
VS Code
Editor integration with ESLint
Prettier
Code formatter to pair with ESLint

Related topics: JavaScript, TypeScript, Node.js, Prettier

What’s Next

Congratulations on completing this ESLint tutorial! Here’s where to go from here:

  • Practice daily — Consistency is more important than long study sessions
  • Build a project — Apply what you learned by building something real
  • Explore related topics — Check out other tutorials in the same category
  • Join the community — Discuss with other learners and share your progress

Remember: every expert was once a beginner. Keep coding!

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro