npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

eslint-config-typed

v4.0.5

Published

[![npm version](https://img.shields.io/npm/v/eslint-config-typed.svg)](https://www.npmjs.com/package/eslint-config-typed) [![npm downloads](https://img.shields.io/npm/dm/eslint-config-typed.svg)](https://www.npmjs.com/package/eslint-config-typed) [![Licen

Readme

eslint-config-typed

npm version npm downloads License codecov

A comprehensive ESLint configuration package with strongly-typed rule definitions and pre-configured setups for TypeScript, React, testing frameworks, and more.

Table of Contents

Features

  • 🎯 Type-Safe Configuration: Fully typed ESLint rules and options and configurations for better IDE support
  • 📦 Pre-configured Setups: Ready-to-use configurations for TypeScript, React, Preact, and popular testing frameworks
  • 📝 Comprehensive Type Definitions: Complete TypeScript types for all ESLint rules and options
  • 🔄 ESLint Flat Config Support: Built for the modern ESLint flat configuration system
  • 🔧 Custom Rules: Additional custom ESLint rules for enhanced code quality

Requirements

  • Node.js >= 18.0.0
  • ESLint >= 9.0.0
  • TypeScript >= 5.0.0 (for TypeScript projects)

Installation

npm add -D eslint eslint-config-typed
# or
yarn add -D eslint eslint-config-typed
# or
pnpm add -D eslint eslint-config-typed

All required ESLint plugins and dependencies are automatically installed.

Quick Start

Create an eslint.config.js or eslint.config.ts file in your project root:

import {
    defineConfig,
    defineKnownRules,
    eslintConfigForTypeScript,
    eslintConfigForVitest,
    withDefaultOption,
} from 'eslint-config-typed';

// import * as path from 'node:path';
// import * as url from 'node:url';

const thisDir = import.meta.dirname;
// or path.dirname(url.fileURLToPath(import.meta.url));

export default defineConfig([
    {
        // config with just ignores is the replacement for `.eslintignore`
        ignores: ['**/build/**', '**/dist/**', 'src/some/file/to/ignore.ts'],
    },

    // Base config for TypeScript & JavaScript code
    ...eslintConfigForTypeScript({
        tsconfigRootDir: thisDir,
        tsconfigFileName: './tsconfig.json',
        packageDirs: [thisDir],

        // If you are using a monorepo and the root package.json is located at ../../../:
        // packageDirs: [path.resolve(thisDir, '../../..'), thisDir],
    }),
    eslintConfigForVitest(),

    // You can override per-rule settings if necessary.
    {
        rules: defineKnownRules({
            '@typescript-eslint/no-explicit-any': withDefaultOption('warn'),
            '@typescript-eslint/prefer-readonly-parameter-types': 'off',
            'react-hooks/exhaustive-deps': withDefaultOption('warn'),
            'functional/no-let': [
                'error',
                {
                    allowInForLoopInit: true,
                    allowInFunctions: false,
                    ignoreIdentifierPattern: ['^mut_', '^_mut_', '^#mut_'],
                },
            ],
        }),
    },
]);

Add a lint script to your package.json:

{
    "scripts": {
        "lint": "eslint './src/**/*'",
        "lint:fix": "eslint './src/**/*' --fix"
    }
}

Run the linter:

npm run lint
# or auto-fix issues
npm run lint:fix

defineConfig helper

defineConfig wraps your flat configuration array so JavaScript config files get full IntelliSense without relying on JSDoc casts. It keeps literal types intact while returning the config unchanged at runtime.

import {
    defineConfig,
    defineKnownRules,
    eslintConfigForTypeScript,
} from 'eslint-config-typed';

const thisDir = import.meta.dirname;

export default defineConfig([
    ...eslintConfigForTypeScript({
        tsconfigRootDir: thisDir,
        tsconfigFileName: './tsconfig.json',
        packageDirs: [thisDir],
    }),
    {
        rules: defineKnownRules({
            // ...
        }),
    },
]);

This is equivalent to:

import {
    defineKnownRules,
    eslintConfigForTypeScript,
    type FlatConfig,
} from 'eslint-config-typed';

const thisDir = import.meta.dirname;

export default [
    ...eslintConfigForTypeScript({
        tsconfigRootDir: thisDir,
        tsconfigFileName: './tsconfig.json',
        packageDirs: [thisDir],
    }),
    {
        rules: defineKnownRules({
            // ...
        }),
    },
] satisfies readonly FlatConfig[];

defineKnownRules utility

defineKnownRules is a helper designed for the rules field in ESLint flat configs. It keeps the returned object untouched while giving you type-safe rule names and option inference in editors (like biome.json). When you wrap your overrides with this function you can rely on:

  • autocomplete and early feedback for rule identifiers, eliminating typo-prone string literals;
  • strongly typed options for every plugin rule that ships with eslint-config-typed, so you can discover valid properties without leaving your editor;
  • a zero-cost runtime helper—because the object is returned as-is, it blends seamlessly into any flat config block.
import {
    defineKnownRules,
    eslintConfigForTypeScript,
    type FlatConfig,
} from 'eslint-config-typed';

const thisDir = import.meta.dirname;

export default [
    ...eslintConfigForTypeScript({
        tsconfigRootDir: thisDir,
        tsconfigFileName: './tsconfig.json',
        packageDirs: [thisDir],
    }),
    {
        rules: defineKnownRules({
            // @ts-expect-error typo of rule name
            'no-restricted-globalsSSSS': 'error',
            // ~~~~~~~~~~~~~~~~~~~~~~~
        }),
    },
    {
        rules: defineKnownRules({
            'no-unsafe-optional-chaining': [
                'error',
                // @ts-expect-error typo of an option key
                { disallowArithmeticOperatorsSSSSS: true },
                // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            ],
        }),
    },
] satisfies FlatConfig[];

withDefaultOption utility

withDefaultOption is a companion helper that highlights rules which ship with option objects. It maps the familiar severity strings to the numeric values ESLint expects: withDefaultOption('error') returns 2, and withDefaultOption('warn') returns 1. Within defineKnownRules, rules that provide options require one of these helpers when you want to keep the defaults and only adjust severity. This convention visually distinguishes rules that contain options, reminding users that a rule has configurable options.

defineKnownRules also reserves 0 for deprecated rules. The resulting severity matrix looks like this:

| Rule type | Allowed severity values in defineKnownRules | | :------------------- | :-------------------------------------------- | ------ | -------- | ------- | ------------------- | | Deprecated rule | 0 | | Rule without options | "off" | "warn" | "error" | | Rule with options | "off" | 1 | 2 | ["warn" | "error", <option>] |

import {
    defineKnownRules,
    eslintConfigForTypeScript,
    withDefaultOption,
    type FlatConfig,
} from 'eslint-config-typed';

const thisDir = import.meta.dirname;

export default [
    ...eslintConfigForTypeScript({
        tsconfigRootDir: thisDir,
        tsconfigFileName: './tsconfig.json',
        packageDirs: [thisDir],
    }),
    {
        rules: defineKnownRules({
            // @ts-expect-error Simply passing the string "error" to a rule with options is not allowed
            'no-restricted-globals': 'error',
            // ~~~~~~~~~~~~~~~~~~~~
            // ^ Type Error! (Because "no-restricted-globals" has options)
            // NOTE: In addition, some rules, such as "no-restricted-syntax" "and no-restricted-globals", have no effect unless you set the option.

            // OK
            'object-shorthand': withDefaultOption('error'),

            // OK (options are set explicitly)
            'no-unsafe-optional-chaining': [
                'error',
                { disallowArithmeticOperators: true },
            ],
        }),
    },
] satisfies FlatConfig[];

TypeScript Configuration Files

You can also write your eslint config in .ts or .mts format, all you need to do is run npm add -D jiti.

import {
    eslintConfigForTypeScript,
    eslintConfigForVitest,
    type FlatConfig,
} from 'eslint-config-typed';

const thisDir = import.meta.dirname;

export default [
    ...eslintConfigForTypeScript({
        tsconfigRootDir: thisDir,
        tsconfigFileName: './tsconfig.json',
        packageDirs: [thisDir],
    }),
    eslintConfigForVitest(),
] satisfies FlatConfig[];

For details, see https://eslint.org/docs/latest/use/configure/configuration-files#typescript-configuration-files.

Configuration Examples

TypeScript + React Project

import {
    defineKnownRules,
    eslintConfigForNodeJs,
    eslintConfigForReact,
    eslintConfigForTypeScript,
    type FlatConfig,
} from 'eslint-config-typed';

const thisDir = import.meta.dirname;

export default [
    { ignores: ['**/dist/**', '**/build/**', '**/.next/**', 'public/**'] },
    ...eslintConfigForTypeScript({
        tsconfigRootDir: thisDir,
        tsconfigFileName: './tsconfig.json',
        packageDirs: [thisDir],
    }),
    ...eslintConfigForReact(['src/**']),
    eslintConfigForNodeJs(['scripts/**', 'configs/**']),
    {
        files: ['scripts/**', 'configs/**'],
        rules: defineKnownRules({
            '@typescript-eslint/explicit-function-return-type': 'off',
            'no-await-in-loop': 'off',
            'import-x/no-unassigned-import': 'off',
            'import-x/no-internal-modules': 'off',
            'import-x/no-default-export': 'off',
            'import-x/no-extraneous-dependencies': 'off',
        }),
    },
] satisfies FlatConfig[];

Node.js TypeScript Project

import {
    defineKnownRules,
    eslintConfigForNodeJs,
    eslintConfigForTypeScript,
    type FlatConfig,
} from 'eslint-config-typed';

export default [
    { ignores: ['**/dist/**', '**/node_modules/**'] },
    ...eslintConfigForTypeScript({
        tsconfigRootDir: import.meta.dirname,
        tsconfigFileName: './tsconfig.json',
        packageDirs: [import.meta.dirname],
    }),
    eslintConfigForNodeJs(),
    {
        rules: defineKnownRules({
            // Allow console in Node.js
            'no-console': 'off',
        }),
    },
] satisfies FlatConfig[];

React + Testing Libraries

import {
    eslintConfigForReact,
    eslintConfigForTestingLibrary,
    eslintConfigForTypeScript,
    eslintConfigForVitest,
    type FlatConfig,
} from 'eslint-config-typed';

export default [
    { ignores: ['**/dist/**', '**/coverage/**'] },
    ...eslintConfigForTypeScript({
        tsconfigRootDir: import.meta.dirname,
        tsconfigFileName: './tsconfig.json',
        packageDirs: [import.meta.dirname],
    }),
    ...eslintConfigForReact(),
    eslintConfigForVitest(),
    eslintConfigForTestingLibrary(),
] satisfies FlatConfig[];

VS Code Integration

Add the following to .vscode/settings.json for proper ESLint integration:

{
    "eslint.workingDirectories": [
        {
            "mode": "auto"
        }
    ],
    "eslint.experimental.useFlatConfig": true
    // "editor.codeActionsOnSave": {
    //   "source.fixAll.eslint": "explicit"
    // }
}

Included plugins

  • @typescript-eslint/eslint-plugin
  • @stylistic/eslint-plugin
  • eslint-plugin-unicorn
  • eslint-plugin-functional
  • eslint-plugin-total-functions (Reimplemented in this repository to support flat config)
  • eslint-plugin-array-func
  • eslint-plugin-prefer-arrow-functions
  • eslint-plugin-sort-destructure-keys
  • eslint-plugin-security
  • eslint-plugin-promise
  • eslint-plugin-import-x
  • eslint-plugin-math
  • eslint-plugin-strict-dependencies
  • eslint-plugin-tree-shakable (Reimplemented in this repository to support flat config)
  • eslint-plugin-n
  • eslint-plugin-react
  • eslint-plugin-react-hooks
  • eslint-plugin-react-perf
  • eslint-plugin-react-refresh
  • eslint-plugin-jsx-a11y
  • eslint-plugin-vitest
  • eslint-plugin-jest
  • eslint-plugin-playwright
  • eslint-plugin-cypress
  • eslint-plugin-testing-library
  • eslint-plugin-eslint-plugin

API Reference

Configuration Functions

These functions return (arrays of) ESLint flat configuration(s):

Base Configurations

  • eslintConfigForTypeScript(options) - TypeScript configuration with strict type checking rules
    • options.tsconfigRootDir: Root directory containing tsconfig.json
    • options.tsconfigFileName: Path to tsconfig.json file
    • options.packageDirs: Array of package directories for import resolution
  • eslintConfigForBrowser - Browser configuration (Turn off Node.js-specific rules)
  • eslintConfigForNodeJs - Node.js configuration (Turn off browser-specific rules)

Framework Configurations

  • eslintConfigForReact(options?) - React configuration with hooks and JSX rules
    • eslintConfigForBrowser is included in this configuration
  • eslintConfigForPreact(options?) - Preact (lighter React alternative) configuration
    • eslintConfigForBrowser is included in this configuration
  • eslintConfigForVitest(options?) - Vitest testing framework configuration
  • eslintConfigForJest(options?) - Jest testing framework configuration
  • eslintConfigForTestingLibrary(options?) - Testing Library configuration
  • eslintConfigForPlaywright(options?) - Playwright E2E testing configuration
  • eslintConfigForCypress(options?) - Cypress E2E testing configuration

Utility Configurations

  • eslintConfigForTypeScriptWithoutRules(options) - TypeScript parser & plugins setup without any rules

Rule Collections

Pre-configured rule sets that can be imported and customized:

| Rule set | Plugin name | Description | | :----------------------------------------- | :------------------------------------- | :----------------------------------------------------- | | eslintRules | (eslint) | Core ESLint rules | | typescriptEslintRules | @typescript-eslint/eslint-plugin | TypeScript-specific ESLint rules | | eslintFunctionalRules | eslint-plugin-functional | Functional programming style rules | | eslintTotalFunctionsRules | eslint-plugin-total-functions | Functional programming style rules | | eslintUnicornRules | eslint-plugin-unicorn | Unicorn plugin rules for better code | | eslintArrayFuncRules | eslint-plugin-array-func | Array function preference rules | | eslintMathRules | eslint-plugin-math | Math object and Number rules | | eslintPreferArrowFunctionRules | eslint-plugin-prefer-arrow-functions | Arrow function preference rules | | eslintPluginSortDestructureKeysRules | eslint-plugin-sort-destructure-keys | Object destructuring rules | | eslintPromiseRules | eslint-plugin-promise | Promise handling rules | | eslintImportsRules | eslint-plugin-import-x | Import/export rules | | eslintSecurityRules | eslint-plugin-security | Security best practices | | eslintTreeShakableRules | eslint-plugin-tree-shakable | Tree-shaking optimization rules | | eslintStylisticRules | @stylistic/eslint-plugin | Stylistic formatting rules disabled to mirror Prettier | | eslintTsRestrictionsRules | eslint-plugin-ts-restrictions | Restrict some syntax in TypeScript | | eslintNRules | eslint-plugin-n | Node.js-specific rules | | eslintReactRules | eslint-plugin-react | React-specific rules | | eslintReactHooksRules | eslint-plugin-react-hooks | React Hooks rules | | eslintReactPerfRules | eslint-plugin-react-perf | React performance optimization rules | | eslintReactRefreshRules | eslint-plugin-react-refresh | React Refresh (HMR) rules | | eslintReactCodingStyleRules | eslint-plugin-react-coding-style | Opinionated React component style rules | | eslintJsxA11yRules | eslint-plugin-jsx-a11y | Accessibility rules for JSX | | eslintVitestRules | eslint-plugin-vitest | Vitest-specific rules | | eslintJestRules | eslint-plugin-jest | Jest-specific rules | | eslintTestingLibraryRules | eslint-plugin-testing-library | Testing Library rules | | eslintPlaywrightRules | eslint-plugin-playwright | Playwright-specific rules | | eslintCypressRules | eslint-plugin-cypress | Cypress-specific rules | | eslintVitestCodingStyleRules | eslint-plugin-vitest-coding-style | Vitest best practices | | eslintPluginRules | eslint-plugin-eslint-plugin | eslint-plugin development rules |

Exported Pre-configured Rule Options

| Pre-configured rule option | Rule | Description | | :-------------------------------- | :---------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------ | | restrictedGlobals | no-restricted-globals | Array of restricted global variables | | restrictedGlobalsForBrowser | no-restricted-globals | Browser-environment-specific restricted globals | | restrictedSyntax | no-restricted-syntax | Disallows the in operator, Object.prototype.hasOwnProperty.call (suggests using Object.hasOwn), and new Array(*) syntax (suggests using Array.from) |

You can find other pre-configured rule options by traversing the pre-defined rules object like this:

  • typescriptEslintRules['@typescript-eslint/no-unused-vars'][1].varsIgnorePattern
  • eslintRules['logical-assignment-operators'].slice(1)

The shape of the rule option varies depending on the rule, so please check the contents by tracing the predefined rules each time and extract it.

Custom Plugins

Forked plugins

  • eslintPluginTotalFunctions
    • Flat Config version of eslint-plugin-total-functions
  • eslintPluginTreeShakable
    • Flat Config version of eslint-plugin-tree-shakable
  • eslintPluginStrictDependencies
    • Flat Config version of eslint-plugin-strict-dependencies

ts-restrictions

eslintPluginTsRestrictions - Custom ESLint plugin with additional rules for TypeScript

  • Currently, this plugin only provides the ts-restrictions/no-restricted-syntax rule (which duplicates ESLint's no-restricted-syntax rule).
  • Can be used to set the error level to error or warn as needed.

Example:

import {
    defineKnownRules,
    eslintRules,
    type FlatConfig,
} from 'eslint-config-typed';

export default [
    // ...
    {
        rules: defineKnownRules({
            'no-restricted-syntax': [
                'warn',
                ...eslintRules['no-restricted-syntax'].slice(1),
            ],
            'ts-restrictions/no-restricted-syntax': [
                'error',
                {
                    // Restrict import style of React
                    selector:
                        "ImportDeclaration[source.value='react'][specifiers.0.type!='ImportNamespaceSpecifier']",
                    message:
                        "React should be imported as `import * as React from 'react'.",
                },
            ],
        }),
    },
] satisfies FlatConfig[];

vitest-coding-style

eslintPluginVitestCodingStyle - Opinionated rules that constrain how Vitest assert/expect APIs are used. Rules that rely on type information (for example prefer-assert-is-true-over-expect-true / prefer-assert-is-false-over-expect-false) assume the plugin types are loaded via tsconfig; add this plugin type definition to compilerOptions.types as shown below.

{
    "compilerOptions": {
        "types": [
            // "vitest/globals", // Remove this line
            "eslint-config-typed/vitest-globals", // Add this line
            "vitest/importMeta",
        ],
    },
}

This type definition provides overridden Chai.Assert type:

  • Change the type definition of isTrue/isFalse
    • Change the arg type from unknown to boolean
    • Change the return type of isTrue from asserts value is true to asserts value so that it can be used as an assertion function like assert.ok.
    • Removed optional message arg
    • Before
      • isTrue: (value: unknown, message?: string) => asserts value is true
      • isFalse: (value: unknown, message?: string) => asserts value is false
    • After
      • isTrue: (value: boolean) => asserts value;
      • isFalse: (value: boolean) => asserts value is false
  • Removed the call signature (assert(x))
  • Removed deepEqual, equal, notEqual, ok, notOk, isOk, isNotOk,
    • deepEqual : Removed in favor of assert.deepStrictEqual
    • equal : Removed in favor of assert.strictEqual
    • notEqual : Removed in favor of assert.notStrictEqual
    • ok : Removed in favor of assert.isTrue
    • notOk : Removed in favor of assert.isFalse
    • isOk : Removed in favor of assert.isTrue
    • isNotOk : Removed in favor of assert.isFalse
  • Removed optional message arg from all assert.* methods
  • Convert arg types to be readonly
  • Replace Object with object

| Included rules | Description | | :--------------------------------------------------- | :-------------------------------------------------------------------------------------------- | | no-expect-to-strict-equal | Forbid expect(x).toStrictEqual(y); prefer assert.deepStrictEqual(x, y) | | prefer-assert-deep-strict-equal-over-deep-equal | Replace assert.deepEqual(x) with assert.deepStrictEqual(x) | | prefer-assert-is-true-over-assert | Canonicalize assert(x) / assert.isOk(x) / assert.ok(x) to assert.isTrue(x) | | prefer-assert-is-false-over-assert-not-ok | Canonicalize assert.isNotOk(x) / assert.notOk(x) to assert.isFalse(x) | | prefer-assert-is-false-over-negated-assert-is-true | Rewrite assert.isTrue(!x) to assert.isFalse(x) | | prefer-assert-is-true-over-negated-assert-is-false | Rewrite assert.isFalse(!x) to assert.isTrue(x) | | prefer-assert-is-true-over-expect-true | Rewrite expect(x).toBe(true) to assert.isTrue(x) (only when x is boolean; type-aware) | | prefer-assert-is-false-over-expect-false | Rewrite expect(x).toBe(false) to assert.isFalse(x) (only when x is boolean; type-aware) |

react-coding-style

eslintPluginReactCodingStyle - Custom ESLint plugin that codifies this repository's React memo component conventions (namespace imports, React.memo<Props>, arrow props naming, etc.).

  • See src/plugins/react-coding-style/README.md for the rationale and examples.
  • Provides rules such as react-coding-style/import-style, react-coding-style/component-var-type-annotation, react-coding-style/react-memo-type-parameter, react-coding-style/react-memo-props-argument-name, react-coding-style/props-type-annotation-style, and react-coding-style/react-hooks-definition-style.

| Included rules | Description | | :------------------------------- | :-------------------------------------------------------------------------------------------------------------------- | | component-name | Enforce concise React.memo component variable names (default max length 42; optional pattern) | | component-var-type-annotation | Forbid React.FC / React.FunctionComponent type annotations; prefer React.memo<Props>((props) => ...) | | import-style | Enforce React import style (import * as React by default; configurable to named imports) | | props-type-annotation-style | Forbid annotating props in the React.memo arrow function; use React.memo<Props>((props) => ...) | | react-memo-props-argument-name | Require the React.memo arrow function to take a single identifier named props | | react-memo-type-parameter | Require React.memo<Props> when props exist; forbid type parameter when there are no props | | use-memo-hook-style | Forbid type assertions/annotations inside and around React.useMemo; annotate via type parameter or variable instead | | ban-use-imperative-handle-hook | Forbid React.useImperativeHandle; move logic to the parent component | | display-name | Require explicit displayName on React.memo components |

Type Definitions

All rules and configurations come with complete TypeScript type definitions:

Core Types

  • FlatConfig - ESLint flat configuration type
    • = DeepReadonly<import('@typescript-eslint/utils/ts-eslint').FlatConfig>
  • ESLintPlugin - ESLint plugin type
    • = DeepReadonly<import('@typescript-eslint/utils/ts-eslint').FlatConfig.Plugin>
  • Rule - ESLint rule definition type
    • = DeepReadonly<import('@eslint/core').RuleDefinition>
  • Rules - Collection of rules type
    • = Readonly<Record<string, Rule>>

Rule Types

Each plugin provides typed rule definitions:

  • General rules
    • EslintRules & EslintRulesOption
    • TypeScriptEslintRules & TypeScriptEslintRulesOption
    • EslintFunctionalRules & EslintFunctionalRulesOption
    • EslintTotalFunctionsRules (no options)
    • EslintUnicornRules & EslintUnicornRulesOption
    • EslintArrayFuncRules (no options)
    • EslintMathRules & EslintMathRulesOption
    • EslintPreferArrowFunctionRules & EslintPreferArrowFunctionRulesOption
    • EslintStylisticRules & EslintStylisticRulesOption
    • EslintPluginSortDestructureKeysRules & EslintPluginSortDestructureKeysRulesOption
    • EslintPromiseRules & EslintPromiseRulesOption
    • EslintImportsRules & EslintImportsRulesOption
    • EslintStrictDependenciesRules & EslintStrictDependenciesRulesOption
    • EslintSecurityRules (no options)
    • EslintTreeShakableRules (no options)
    • EslintStylisticRules & EslintStylisticRulesOption
    • EslintTsRestrictionsRules & EslintTsRestrictionsRulesOption
    • EslintNRules & EslintNRulesOption
  • React & JSX
    • EslintReactRules & EslintReactRulesOption
    • EslintReactHooksRules & EslintReactHooksRulesOption
    • EslintReactPerfRules & EslintReactPerfRulesOption
    • EslintReactRefreshRules & EslintReactRefreshRulesOption
    • EslintJsxA11yRules & EslintJsxA11yRulesOption
    • EslintReactCodingStyleRules & EslintReactCodingStyleRulesOption
  • Testing
    • EslintVitestRules & EslintVitestRulesOption
    • EslintJestRules & EslintJestRulesOption
    • EslintPlaywrightRules & EslintPlaywrightRulesOption
    • EslintCypressRules & EslintCypressRulesOption
    • EslintTestingLibraryRules & EslintTestingLibraryRulesOption
    • EslintVitestCodingStyleRules (no options)
  • Others
    • EslintPluginRules & EslintPluginRulesOption

Customization

The pre-configured rules of eslint-config-typed are opinionated settings that prioritize strictness and enable as many non-conflicting rules as possible. Therefore, it is intended to be used by downgrading the severity of unnecessary rules in the config file from "error" to "warn" or "off", or by overriding option settings.

Override Specific Rules

You can override any rule by adding a configuration object after the preset configurations:

import {
    defineKnownRules,
    eslintConfigForTypeScript,
    type FlatConfig,
    typescriptEslintRules,
    withDefaultOption,
} from 'eslint-config-typed';

const thisDir = import.meta.dirname;

export default [
    ...eslintConfigForTypeScript({
        tsconfigRootDir: thisDir,
        tsconfigFileName: './tsconfig.json',
        packageDirs: [thisDir],
    }),
    {
        rules: defineKnownRules({
            // Downgrade to warning (Option settings are inherited)
            '@typescript-eslint/no-explicit-any': withDefaultOption('warn'),
            // Disable a rule
            '@typescript-eslint/prefer-readonly-parameter-types': 'off',
            // Configure with options
            'functional/no-let': [
                'error',
                {
                    allowInForLoopInit: true,
                    allowInFunctions: false,
                },
            ],

            // Update rule options
            '@typescript-eslint/no-restricted-types': [
                'error',
                {
                    types: {
                        ...typescriptEslintRules[
                            '@typescript-eslint/no-restricted-types'
                        ][1].types,
                        Function: "Don't use Function type",
                    },
                },
            ],
        }),
    },
] satisfies FlatConfig[];

Use RulesOptions Types

Leverage TypeScript for type-safe rule configuration:

// configs/restricted-syntax-defs.mjs

import { eslintRules, type EslintRulesOption } from 'eslint-config-typed';

export const restrictedSyntax = [
    ...eslintRules['no-restricted-syntax'].slice(1),
    {
        // Restrict type annotation style for React.useMemo
        selector:
            "TSTypeAnnotation[parent.parent.type='CallExpression'][parent.parent.callee.object.name='React'][parent.parent.callee.property.name='useMemo']",
        message:
            'The variable type T should be annotated as `React.useMemo<T>` or `const v: T = React.useMemo(...)`.',
    },
] satisfies EslintRulesOption['no-restricted-syntax'];
// eslint.config.mts

import {
    defineKnownRules,
    eslintConfigForTypeScript,
    type FlatConfig,
} from 'eslint-config-typed';
import { restrictedSyntax } from './restricted-syntax-defs.mjs';

const thisDir = import.meta.dirname;

export default [
    ...eslintConfigForTypeScript({
        tsconfigRootDir: thisDir,
        tsconfigFileName: './tsconfig.json',
        packageDirs: [thisDir],
    }),
    {
        rules: defineKnownRules({
            'no-restricted-syntax': ['error', ...restrictedSyntax],
        }),
    },
] satisfies readonly FlatConfig[];

Target Specific Files

Apply different rules to different file patterns:

import {
    defineKnownRules,
    eslintConfigForTypeScript,
    type FlatConfig,
} from 'eslint-config-typed';

const thisDir = import.meta.dirname;

export default [
    ...eslintConfigForTypeScript({
        tsconfigRootDir: thisDir,
        tsconfigFileName: './tsconfig.json',
        packageDirs: [thisDir],
    }),
    {
        files: ['**/*.test.ts', '**/*.spec.ts'],
        rules: defineKnownRules({
            // Allow any in tests
            '@typescript-eslint/no-explicit-any': 'off',
            // Allow console in tests
            'no-console': 'off',
        }),
    },
    {
        files: ['scripts/**/*.ts'],
        rules: defineKnownRules({
            // Allow console in scripts
            'no-await-in-loop': 'off',
            'import-x/no-unassigned-import': 'off',
        }),
    },
] satisfies FlatConfig[];

Troubleshooting

Common Issues

1. ESLint can't find tsconfig.json

Ensure the paths are correct:

import {
    eslintConfigForTypeScript,
    type FlatConfig,
} from 'eslint-config-typed';

const thisDir = import.meta.dirname;

export default eslintConfigForTypeScript({
    tsconfigRootDir: thisDir, // Must be absolute path
    tsconfigFileName: './tsconfig.json', // Relative to tsconfigRootDir
    packageDirs: [thisDir],
}) satisfies readonly FlatConfig[];

2. Import resolution errors

The packageDirs option helps ESLint resolve imports correctly in monorepos:

import {
    eslintConfigForTypeScript,
    type FlatConfig,
} from 'eslint-config-typed';

const thisDir = import.meta.dirname;

export default eslintConfigForTypeScript({
    tsconfigRootDir: thisDir,
    tsconfigFileName: './tsconfig.json',
    packageDirs: [
        path.resolve(thisDir, '../../..'), // Monorepo root
        thisDir, // Current package
    ],
}) satisfies readonly FlatConfig[];

3. Performance issues

For large projects, consider:

  • Using TIMING=1 eslint to identify heavy rules
  • Using NODE_OPTIONS='--max-old-space-size=<memory-size-MB>' eslint to increase the maximum memory available
  • Separate heavy rules into a separate config and prepare a dedicated command
  • Using .eslintignore or ignores patterns to skip generated files
  • Running ESLint with --cache flag
  • Limiting the scope of type-aware rules

4. How to Use import-x/no-unused-modules

import-x/no-unused-modules reports exported values that are never imported anywhere else. The rule still relies on ESLint’s classic configuration loader to discover ignore patterns, so a flat-config-only setup is not enough. For this to work, you need to place a .eslintrc.cjs file along with eslint.config.mts.

// .eslintrc.cjs
module.exports = {
    ignorePatterns: ['**/node_modules/**', 'dist', '.eslintrc.cjs'],
};

The flat config then enables the rule for our source tree and marks the public federation module as an allowed unused export:

// eslint.config.mts (excerpt)
{
  files: ['src/**'],
  rules: defineKnownRules({
    'import-x/no-unused-modules': [
      'error',
      { unusedExports: true, ignoreExports: ['src/entry-point.mts'] },
    ],
  }),
},

With this configuration, you can run eslint and receive actionable diagnostic information when exports are no longer referenced. If you implement a library, add the file paths that define the variables, types, etc. that your library exports to the ignoreExports array so that the rule does not flag intentionally re-exported surfaces.

Known Limitations

  • Some type-aware rules may have performance impacts on very large codebases
  • Flat config requires ESLint 9.0+ and may not be compatible with older tools

Contributing

Contributions are welcome! Please check our GitHub repository for:

  • Issue reporting
  • Feature requests
  • Pull requests

License

This project is licensed under the Apache License 2.0.