iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

ESLint

ESLint catches whole classes of bugs before review. Combined with Prettier and a few opinionated rules, it stops you arguing about style and starts catching real mistakes.

Node + ESLint setup

EXAMPLE
// Install
// npm i -D eslint @eslint/js typescript-eslint prettier eslint-config-prettier

// eslint.config.js (flat config, ESLint 9+)
import js from '@eslint/js';
import ts from 'typescript-eslint';
import prettier from 'eslint-config-prettier';

export default [
  { ignores: ['dist/**', 'node_modules/**', 'coverage/**'] },
  js.configs.recommended,
  ...ts.configs.recommended,
  {
    languageOptions: {
      ecmaVersion: 2024,
      sourceType: 'module',
      parserOptions: { project: './tsconfig.json' },
    },
    rules: {
      'no-console': ['warn', { allow: ['warn', 'error'] }],
      'no-unused-vars': 'off',
      '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
      '@typescript-eslint/no-floating-promises': 'error',
      '@typescript-eslint/await-thenable': 'error',
      '@typescript-eslint/no-misused-promises': 'error',
      'eqeqeq': ['error', 'smart'],
      'no-restricted-syntax': [
        'error',
        { selector: 'TSEnumDeclaration', message: 'Use literal unions instead of enums' },
      ],
    },
  },
  prettier,
];

// package.json scripts
{
  'scripts': {
    'lint': 'eslint . --max-warnings 0',
    'lint:fix': 'eslint . --fix'
  }
}

// .prettierrc
{
  'singleQuote': true,
  'trailingComma': 'all',
  'printWidth': 100,
  'semi': true
}

// Pre-commit hook (husky + lint-staged)
// npx husky-init && npm i -D lint-staged

// package.json
{
  'lint-staged': {
    '*.{ts,tsx}': ['eslint --fix', 'prettier --write']
  }
}

Why it matters

Flat config is the future - migrate. Pair ESLint with typed rules (no-floating-promises is worth the setup alone). Disable formatting rules in ESLint, run Prettier separately, run both pre-commit.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
// .eslintrc / eslint.config.js
import tseslint from 'typescript-eslint';
export default tseslint.config(tseslint.configs.strict);
Try it Yourself »

Discussion

Loading…