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…