or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-remix-run--eslint-config

ESLint configuration for Remix projects providing comprehensive linting rules for React, TypeScript, JSX accessibility, and import management

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@remix-run/eslint-config@2.17.x

To install, run

npx @tessl/cli install tessl/npm-remix-run--eslint-config@2.17.0

index.mddocs/

@remix-run/eslint-config

@remix-run/eslint-config provides comprehensive ESLint configurations specifically designed for Remix projects. It offers shareable ESLint configs that enforce best practices for React, TypeScript, JSX accessibility, and import/export patterns.

⚠️ Deprecation Notice: This package is deprecated and will not be included in React Router v7. Users should migrate to streamlined ESLint configurations as provided in Remix templates.

Package Information

  • Package Name: @remix-run/eslint-config
  • Package Type: npm
  • Language: JavaScript/TypeScript
  • Installation: npm install -D eslint @remix-run/eslint-config

Core Imports

This package is used via ESLint configuration files - no JavaScript imports required.

Basic Usage

Create a .eslintrc.js file in your project root:

module.exports = {
  extends: "@remix-run/eslint-config",
};

With Jest and Testing Library:

module.exports = {
  extends: [
    "@remix-run/eslint-config",
    "@remix-run/eslint-config/jest-testing-library",
  ],
};

For Node.js projects:

module.exports = {
  extends: [
    "@remix-run/eslint-config",
    "@remix-run/eslint-config/node",
  ],
};

Note: The package.json references a jest.js file in the files array, but this file does not exist in the actual package. Testing configuration is provided through jest-testing-library.js instead.

Architecture

@remix-run/eslint-config is built around several key configuration modules:

  • Main Configuration: Default shareable config with React, TypeScript, and accessibility rules
  • Testing Configuration: Optional Jest and Testing Library rules for test files
  • Node.js Configuration: Basic Node.js environment setup
  • Internal Configuration: Extended configuration for internal Remix development (not recommended for external use)
  • Rule Modules: Modular rule definitions for core JavaScript, React, TypeScript, accessibility, and testing
  • Settings Modules: Import resolution and React-specific settings for Remix components

Capabilities

Default ESLint Configuration

Main shareable ESLint configuration for Remix projects with comprehensive rules for JavaScript, React, TypeScript, and accessibility.

// Usage in .eslintrc.js
module.exports = {
  extends: "@remix-run/eslint-config",
};

// ESLint Configuration Object Structure
interface ESLintConfig {
  parser: string;
  parserOptions: {
    sourceType: "module";
    requireConfigFile: false;
    ecmaVersion: "latest";
    babelOptions: {
      presets: string[];
    };
  };
  env: {
    browser: boolean;
    commonjs: boolean;
    es6: boolean;
  };
  plugins: string[];
  settings: Record<string, any>;
  rules: Record<string, any>;
  overrides: Array<{
    files: string[];
    extends?: string[];
    parser?: string;
    parserOptions?: Record<string, any>;
    plugins?: string[];
    rules?: Record<string, any>;
  }>;
}

Features:

  • JavaScript/TypeScript Parsing: Uses @babel/eslint-parser and @typescript-eslint/parser
  • React Support: React and React Hooks rules with JSX support
  • Accessibility: JSX A11y rules for accessible React components
  • Import Management: ES6 import/export rules with TypeScript integration
  • TypeScript Overrides: Specialized rules for .ts/.tsx files
  • Route Overrides: Special handling for Remix route files (allows unnamed default exports)

Jest and Testing Library Configuration

Optional ESLint configuration for projects using Jest and Testing Library.

// Usage in .eslintrc.js
module.exports = {
  extends: [
    "@remix-run/eslint-config",
    "@remix-run/eslint-config/jest-testing-library",
  ],
};

// Configuration Structure
interface JestTestingLibraryConfig {
  plugins: ["jest", "jest-dom", "testing-library"];
  env: {
    node: boolean;
  };
  overrides: Array<{
    files: string[];
    env: {
      "jest/globals": boolean;
    };
    rules: Record<string, any>;
  }>;
}

Features:

  • Jest Rules: Test structure, expect usage, snapshot testing guidelines
  • Jest DOM Rules: DOM assertion preferences and element state checking
  • Testing Library Rules: Best practices for async queries, event handling, screen queries
  • Test File Targeting: Applies rules to **/__tests__/**/* and **/*.{spec,test}.* files

Required Peer Dependencies (if using this configuration):

{
  "dependencies": {
    "@testing-library/jest-dom": ">=5.16.0",
    "@testing-library/react": ">=12.0.0",
    "jest": ">=28.0.0"
  }
}

Node.js Configuration

Basic Node.js environment configuration for server-side projects.

// Usage in .eslintrc.js
module.exports = {
  extends: [
    "@remix-run/eslint-config",
    "@remix-run/eslint-config/node",
  ],
};

// Configuration Structure
interface NodeConfig {
  plugins: ["node"];
  env: {
    node: boolean;
  };
}

Features:

  • Node.js Environment: Enables Node.js global variables and features
  • Node.js Plugin: Provides Node.js-specific linting rules

Internal Configuration (Not Public API)

Extended ESLint configuration used internally by the Remix team. This configuration is not intended for external use and should not be considered public API regarding semver considerations.

// Usage (internal Remix projects only)
module.exports = {
  extends: "@remix-run/eslint-config/internal",
};

// Configuration Structure  
interface InternalConfig {
  root: true;
  extends: [
    "./index.js",
    "./jest-testing-library.js"
  ];
  env: {
    node: boolean;
  };
  plugins: ["node", "prefer-let"];
  rules: {
    "@typescript-eslint/consistent-type-imports": 2; // ERROR
    "import/order": [2, { 
      "newlines-between": "always";
      groups: [
        ["builtin", "external"],
        "internal", 
        ["parent", "sibling", "index"]
      ];
    }];
    "jest/no-disabled-tests": 0; // OFF
    "prefer-let/prefer-let": 1; // WARN
  };
  overrides: Array<{
    files: string[];
    rules: Record<string, any>;
  }>;
}

Features:

  • Extended Base Config: Includes both main config and jest-testing-library config
  • Import Ordering: Enforces specific import organization with newlines between groups
  • TypeScript Imports: Requires consistent type-only imports
  • Markdown Code Blocks: Special rules for code samples in documentation
  • Workspace Dependencies: Validates dependencies are listed in package.json files
  • Integration Test Handling: Special rules for integration test files

Internal-Only Rules:

  • Consistent type imports enforcement
  • Strict import ordering with grouped organization
  • Prefer-let over const for variable declarations
  • Disabled Jest rules for certain test patterns
  • Code block linting in Markdown files with relaxed rules

Rule Categories

Core JavaScript Rules

Fundamental ESLint rules for JavaScript/ES6+ code quality and error prevention.

// Core JavaScript Rules (comprehensive)
interface CoreRules {
  "array-callback-return": 1; // WARN
  "getter-return": 1; // WARN
  "new-parens": 1; // WARN
  "no-array-constructor": 1; // WARN
  "no-caller": 2; // ERROR  
  "no-cond-assign": [1, "except-parens"]; // WARN
  "no-const-assign": 2; // ERROR
  "no-control-regex": 1; // WARN
  "no-dupe-args": 1; // WARN
  "no-dupe-class-members": 1; // WARN
  "no-dupe-keys": 1; // WARN
  "no-duplicate-case": 1; // WARN
  "no-empty-character-class": 1; // WARN
  "no-empty-pattern": 1; // WARN
  "no-empty": [1, { allowEmptyCatch: true }]; // WARN
  "no-eval": 2; // ERROR
  "no-ex-assign": 1; // WARN
  "no-extend-native": 1; // WARN
  "no-extra-bind": 1; // WARN
  "no-extra-label": 1; // WARN
  "no-extra-boolean-cast": 1; // WARN
  "no-func-assign": 2; // ERROR
  "no-global-assign": 2; // ERROR
  "no-implied-eval": 1; // WARN
  "no-invalid-regexp": 1; // WARN
  "no-label-var": 1; // WARN
  "no-labels": [1, { allowLoop: true, allowSwitch: false }]; // WARN
  "no-lone-blocks": 1; // WARN
  "no-loop-func": 1; // WARN
  "no-mixed-operators": [1, {
    groups: [
      ["&", "|", "^", "~", "<<", ">>", ">>>"],
      ["==", "!=", "===", "!==", ">", ">=", "<", "<="],
      ["&&", "||"],
      ["in", "instanceof"]
    ],
    allowSamePrecedence: false
  }]; // WARN
  "no-unsafe-negation": 1; // WARN
  "no-new-func": 1; // WARN
  "no-new-object": 1; // WARN  
  "no-octal": 1; // WARN
  "no-redeclare": 2; // ERROR
  "no-script-url": 1; // WARN
  "no-self-assign": 1; // WARN
  "no-self-compare": 1; // WARN
  "no-sequences": 1; // WARN
  "no-shadow-restricted-names": 1; // WARN
  "no-sparse-arrays": 1; // WARN
  "no-template-curly-in-string": 1; // WARN
  "no-this-before-super": 1; // WARN
  "no-undef": 2; // ERROR
  "no-unreachable": 1; // WARN
  "no-unused-expressions": [1, {
    allowShortCircuit: true,
    allowTernary: true,
    allowTaggedTemplates: true
  }]; // WARN
  "no-unused-labels": 1; // WARN
  "no-unused-vars": [1, { args: "none", ignoreRestSiblings: true }]; // WARN
  "no-use-before-define": [1, { classes: false, functions: false, variables: false }]; // WARN
  "no-useless-computed-key": 1; // WARN
  "no-useless-concat": 1; // WARN
  "no-useless-constructor": 1; // WARN
  "no-useless-escape": 1; // WARN
  "no-useless-rename": [1, {
    ignoreDestructuring: false,
    ignoreImport: false,
    ignoreExport: false
  }]; // WARN
  "require-yield": 1; // WARN
  "use-isnan": 1; // WARN
  "valid-typeof": 1; // WARN
}

React and JSX Rules

React-specific rules for component development and JSX syntax.

// React and JSX Rules (comprehensive)
interface ReactRules {
  "react/display-name": 1; // WARN
  "react/forbid-foreign-prop-types": [1, { allowInPropTypes: true }]; // WARN
  "react/jsx-key": 1; // WARN
  "react/jsx-no-comment-textnodes": 1; // WARN
  "react/jsx-no-target-blank": 1; // WARN
  "react/jsx-no-undef": 2; // ERROR
  "react/jsx-pascal-case": [1, { allowAllCaps: true, ignore: [] }]; // WARN
  "react/jsx-uses-vars": 1; // WARN
  "react/jsx-uses-react": 1; // WARN
  "react/no-danger-with-children": 1; // WARN
  "react/no-direct-mutation-state": 1; // WARN
  "react/no-find-dom-node": 1; // WARN
  "react/no-is-mounted": 1; // WARN
  "react/no-render-return-value": 2; // ERROR
  "react/no-string-refs": 1; // WARN
  "react/no-typos": 1; // WARN
  "react/react-in-jsx-scope": 0; // OFF - Not needed in modern React
  "react/require-render-return": 2; // ERROR
  "react/style-prop-object": 1; // WARN
  
  // React Hooks Rules
  "react-hooks/exhaustive-deps": 1; // WARN
  "react-hooks/rules-of-hooks": 2; // ERROR
}

TypeScript Rules

TypeScript-specific rules and overrides for type safety.

// TypeScript Rules (comprehensive)
interface TypeScriptRules {
  // Disabled TypeScript rules (turned off for flexibility)
  "@typescript-eslint/ban-ts-comment": 0; // OFF
  "@typescript-eslint/ban-types": 0; // OFF
  "@typescript-eslint/no-empty-function": 0; // OFF
  "@typescript-eslint/no-empty-interface": 0; // OFF
  "@typescript-eslint/no-explicit-any": 0; // OFF
  "@typescript-eslint/no-inferrable-types": 0; // OFF
  "@typescript-eslint/no-namespace": 0; // OFF
  "@typescript-eslint/no-non-null-assertion": 0; // OFF
  "@typescript-eslint/no-var-requires": 0; // OFF
  "no-var": 0; // OFF
  "prefer-rest-params": 0; // OFF
  
  // Configured TypeScript rules
  "@typescript-eslint/no-use-before-define": [2, {
    functions: false,
    classes: false,
    variables: false,
    typedefs: false
  }]; // ERROR
  "@typescript-eslint/no-unused-expressions": [2, {
    allowShortCircuit: true,
    allowTernary: true,
    allowTaggedTemplates: true
  }]; // ERROR
  "@typescript-eslint/no-unused-vars": [2, {
    args: "none",
    ignoreRestSiblings: true
  }]; // ERROR
  
  // JavaScript rules disabled for TypeScript
  "no-dupe-class-members": 0; // OFF - Handled by TypeScript
  "no-undef": 0; // OFF - Handled by TypeScript
  "no-use-before-define": 0; // OFF - Use TypeScript version
  "prefer-const": 0; // OFF - Style preference
  
  // Stylistic TypeScript rules  
  "@typescript-eslint/consistent-type-assertions": 1; // WARN
  "@typescript-eslint/consistent-type-imports": 1; // WARN
}

JSX Accessibility Rules

Accessibility rules for JSX elements and ARIA compliance.

// JSX Accessibility Rules (comprehensive)
interface JsxA11yRules {
  "jsx-a11y/alt-text": 1; // WARN
  "jsx-a11y/anchor-has-content": [1, { components: ["Link", "NavLink"] }]; // WARN
  "jsx-a11y/anchor-is-valid": [1, { aspects: ["noHref", "invalidHref"] }]; // WARN
  "jsx-a11y/aria-activedescendant-has-tabindex": 1; // WARN
  "jsx-a11y/aria-props": 1; // WARN
  "jsx-a11y/aria-proptypes": 1; // WARN
  "jsx-a11y/aria-role": [1, { ignoreNonDOM: true }]; // WARN
  "jsx-a11y/aria-unsupported-elements": 1; // WARN
  "jsx-a11y/iframe-has-title": 1; // WARN
  "jsx-a11y/img-redundant-alt": 1; // WARN
  "jsx-a11y/lang": 1; // WARN
  "jsx-a11y/no-access-key": 1; // WARN
  "jsx-a11y/no-redundant-roles": 1; // WARN
  "jsx-a11y/role-has-required-aria-props": 1; // WARN
  "jsx-a11y/role-supports-aria-props": 1; // WARN
}

Import and Export Rules

ES6 module import/export management and organization.

// Import and Export Rules
interface ImportRules {
  "import/first": 2; // ERROR - Imports must be at top
  "import/no-amd": 2; // ERROR - No AMD require/define
  "import/no-duplicates": 2; // ERROR - No duplicate imports
  "import/no-webpack-loader-syntax": 2; // ERROR - No webpack loader syntax
}

Jest Testing Rules

Jest-specific rules for test structure and best practices when using jest-testing-library configuration.

// Jest Rules (comprehensive)
interface JestRules {
  "jest/no-conditional-expect": 1; // WARN
  "jest/no-deprecated-functions": 1; // WARN
  "jest/no-disabled-tests": 1; // WARN
  "jest/no-export": 2; // ERROR - Test files should not export
  "jest/no-focused-tests": 1; // WARN - No .only or .skip
  "jest/no-identical-title": 1; // WARN
  "jest/no-interpolation-in-snapshots": 1; // WARN
  "jest/no-jasmine-globals": 2; // ERROR - Use Jest, not Jasmine
  "jest/no-jest-import": 1; // WARN
  "jest/no-mocks-import": 1; // WARN
  "jest/valid-describe-callback": 2; // ERROR
  "jest/valid-expect": 2; // ERROR
  "jest/valid-expect-in-promise": 2; // ERROR
}

Jest DOM Rules

Jest DOM assertion preferences and element state checking.

// Jest DOM Rules
interface JestDomRules {
  "jest-dom/prefer-checked": 1; // WARN
  "jest-dom/prefer-empty": 1; // WARN
  "jest-dom/prefer-enabled-disabled": 1; // WARN
  "jest-dom/prefer-focus": 1; // WARN
  "jest-dom/prefer-in-document": 1; // WARN
  "jest-dom/prefer-required": 1; // WARN
  "jest-dom/prefer-to-have-attribute": 1; // WARN
  "jest-dom/prefer-to-have-class": 1; // WARN
  "jest-dom/prefer-to-have-style": 1; // WARN
  "jest-dom/prefer-to-have-text-content": 1; // WARN
  "jest-dom/prefer-to-have-value": 1; // WARN
}

Testing Library Rules

Testing Library best practices for async queries, event handling, and screen queries.

// Testing Library Rules
interface TestingLibraryRules {
  "testing-library/await-async-query": 2; // ERROR
  "testing-library/await-async-utils": 2; // ERROR
  "testing-library/no-await-sync-events": 2; // ERROR
  "testing-library/no-await-sync-query": 2; // ERROR
  "testing-library/no-debugging-utils": 1; // WARN
  "testing-library/no-promise-in-fire-event": 2; // ERROR
  "testing-library/no-render-in-setup": 2; // ERROR
  "testing-library/no-unnecessary-act": 2; // ERROR
  "testing-library/no-wait-for-empty-callback": 2; // ERROR
  "testing-library/no-wait-for-multiple-assertions": 2; // ERROR
  "testing-library/no-wait-for-side-effects": 2; // ERROR
  "testing-library/no-wait-for-snapshot": 2; // ERROR
  "testing-library/prefer-find-by": 1; // WARN
  "testing-library/prefer-presence-queries": 1; // WARN
  "testing-library/prefer-query-by-disappearance": 1; // WARN
  "testing-library/prefer-screen-queries": 1; // WARN
  "testing-library/prefer-user-event": 1; // WARN
  "testing-library/prefer-wait-for": 1; // WARN
  "testing-library/render-result-naming-convention": 1; // WARN
}

Configuration Settings

React Settings

React-specific ESLint settings for Remix components.

interface ReactSettings {
  react: {
    version: "detect";
    formComponents: ["Form"];
    linkComponents: Array<{
      name: "Link" | "NavLink";
      linkAttribute: "to";
    }>;
  };
}

Import Resolution Settings

Import parser and resolver configuration for JavaScript and TypeScript.

// Import Resolution Settings (detailed)
interface ImportSettings {
  "import/ignore": [
    "node_modules",
    "\\.(css|md|svg|json)$"
  ];
  "import/parsers": {
    "@typescript-eslint/parser": [".ts", ".tsx", ".d.ts"];
  };
  "import/resolver": {
    "eslint-import-resolver-node": {
      extensions: [".js", ".jsx", ".ts", ".tsx"];
    };
    "eslint-import-resolver-typescript": {
      alwaysTryTypes: true;
    };
  };
}

File Override Patterns

TypeScript File Overrides

Special configuration for .ts and .tsx files.

// Files: ["**/*.ts?(x)"]
interface TypeScriptOverride {
  extends: [
    "plugin:import/typescript",
    "plugin:@typescript-eslint/recommended",
  ];
  parser: "@typescript-eslint/parser";
  parserOptions: {
    sourceType: "module";
    ecmaVersion: 2019;
  };
  plugins: ["@typescript-eslint"];
  rules: Record<string, any>;
}

Remix Route File Overrides

Special handling for Remix route files allowing unnamed default exports.

// Files: ["**/routes/**/*.js?(x)", "**/routes/**/*.tsx", "app/root.js?(x)", "app/root.tsx"]
interface RouteOverride {
  rules: {
    "react/display-name": 0; // OFF - Routes may use default exports without a name
  };
}

Test File Overrides

Configuration applied specifically to test files when using jest-testing-library config.

// Files: ["**/__tests__/**/*", "**/*.{spec,test}.*"]
interface TestOverride {
  env: {
    "jest/globals": true;
  };
  rules: {
    // Jest, Jest DOM, and Testing Library rules applied here
  };
}

Installation Requirements

Base Requirements

interface PeerDependencies {
  eslint: "^8.0.0";
  react: "^18.0.0";
  typescript?: "^5.1.0"; // Optional
}

interface Engines {
  node: ">=18.0.0";
}

Testing Configuration Requirements

Additional dependencies needed when using jest-testing-library configuration:

{
  "dependencies": {
    "@testing-library/jest-dom": ">=5.16.0",
    "@testing-library/react": ">=12.0.0", 
    "jest": ">=28.0.0"
  }
}

Error Handling

The package includes proper error handling through:

  • ESLint Configuration Validation: Invalid configurations will be caught by ESLint
  • Peer Dependency Warnings: Missing peer dependencies will generate npm warnings
  • Rule Conflicts: Rule conflicts between configurations are resolved through ESLint's extending mechanism
  • Deprecation Warnings: Console warning displayed when using the package about upcoming deprecation

Deprecation Warning

When using this package, a deprecation warning will be displayed:

⚠️ REMIX FUTURE CHANGE: The `@remix-run/eslint-config` package is deprecated 
and will not be included in React Router v7. We recommend moving towards a 
streamlined ESLint config such as the ones included in the Remix templates. 
See https://github.com/remix-run/remix/blob/main/templates/remix/.eslintrc.cjs.

This warning is shown every time the configuration is loaded, helping users transition to alternative ESLint configurations before React Router v7.

Types

// ESLint Rule Severity Levels
type RuleSeverity = 0 | 1 | 2 | "off" | "warn" | "error";

// Rule Configuration
type RuleConfig = RuleSeverity | [RuleSeverity, ...any[]];

// ESLint Configuration Object
interface ESLintConfiguration {
  root?: boolean;
  extends?: string | string[];
  parser?: string;
  parserOptions?: Record<string, any>;
  env?: Record<string, boolean>;
  plugins?: string[];
  settings?: Record<string, any>;
  rules?: Record<string, RuleConfig>;
  overrides?: Array<{
    files: string | string[];
    excludedFiles?: string | string[];
    extends?: string | string[];
    parser?: string;
    parserOptions?: Record<string, any>;
    env?: Record<string, boolean>;
    plugins?: string[];
    rules?: Record<string, RuleConfig>;
  }>;
}