MailOnline ESLint Typescript configuration for ESLint 9+ (flat config).
- ESLint >= 9.0.0
- TypeScript >= 5.0.0
- Node.js >= 18.18.0
- Add
eslint-config-ts-mailonline,eslint,typescript,prettier,husky, andpretty-quickas development dependencies:
yarn add --dev eslint-config-ts-mailonline eslint typescript prettier husky pretty-quick- Create a
tsconfig.eslint.jsonfile at the root of your project:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"allowJs": true,
"noEmit": true
},
"include": ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts", "**/*.js", "**/*.jsx", "**/*.mjs", "**/*.cjs"],
"exclude": ["node_modules", "dist", "coverage"]
}Why is this needed? This configuration uses
@typescript-eslint/parserwith type-aware linting, which requires TypeScript to know about all files being linted. Many projects exclude test files and config files from their maintsconfig.jsonto avoid compiling them. Thetsconfig.eslint.jsonensures all files are included for linting purposes without affecting your build configuration.
tsconfig.eslint.jsonis now required: You must create atsconfig.eslint.jsonfile in your project root. This is necessary because the configuration uses@typescript-eslint/parserwithproject: './tsconfig.eslint.json'for type-aware linting rules.
- Create an
eslint.config.mjsfile at the root of your project usingdefineConfig(defineConfigis the standard way to define ESLint configurations since ESLint 9):
import { defineConfig } from 'eslint/config';
import { baseConfig, reactConfig } from 'eslint-config-ts-mailonline';
// defineConfig accepts both a config object or an array of config objects
export default defineConfig({
// extends automatically flattens configuration arrays, so no spread operator needed
extends: [
baseConfig,
reactConfig // optional, only if using React
]
// your custom overrides here:
// rules: { 'no-console': 'warn' }
});- Create
prettier.config.mjsat the root of your project:
export { default } from 'eslint-config-ts-mailonline/prettierConfig';- Add the following script command to your
package.json:
{
"scripts": {
"lint": "tsc --noEmit && eslint ."
}
}- Add the following hooks to your husky scripts:
Pre-commit (.husky/pre-commit):
pretty-quick --staged && yarn run lintPre-push (.husky/pre-push):
yarn run testWith ESLint 9 flat config, ignores are defined in your eslint.config.mjs using globalIgnores:
import { defineConfig, globalIgnores } from 'eslint/config';
import { baseConfig } from 'eslint-config-ts-mailonline';
export default defineConfig([
// These ignores will be merged with the ones in baseConfig global ignores object
// ending up in: ['**/node_modules/**', '**/coverage/**', '**/dist/**', 'bin/**', 'legacy/**']
globalIgnores(['bin/**', 'legacy/**']),
{
extends: [
baseConfig
// other configs...
]
}
]);This package includes the following ESLint plugins and configurations as direct dependencies. You should remove these from your project's devDependencies if you have them:
@typescript-eslint/eslint-plugin@typescript-eslint/parsereslint-config-prettiereslint-import-resolver-typescripteslint-plugin-importeslint-plugin-no-only-testseslint-plugin-prefer-arroweslint-plugin-reacteslint-plugin-react-hookseslint-plugin-unicorn
Why? By bundling these dependencies, we:
- Guarantee compatibility: The config package ensures all plugins work correctly together
- Avoid version conflicts: No risk of peer dependency mismatches or duplicate packages
- Simplify adoption: Consumers don't need to manage ESLint plugin versions
- Single source of truth: Updates to plugins are handled centrally in this package
Any changes to this package that might cause code using it to not validate anymore, will be a semver-major change.
See Migration Guide for instructions on upgrading from v4.x (ESLint 8) to v5.x (ESLint 9).