or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

ESLint Plugin Compat

ESLint Plugin Compat is a TypeScript ESLint plugin that provides browser compatibility linting for web APIs and ES APIs. It helps developers identify when their code uses features that may not be supported in their target browsers by integrating with browserslist for flexible browser targeting configuration and leveraging compatibility data from MDN Browser Compat Data and Can I Use.

Package Information

  • Package Name: eslint-plugin-compat
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install eslint-plugin-compat

Core Imports

import compat from "eslint-plugin-compat";

For CommonJS:

const compat = require("eslint-plugin-compat");

Basic Usage

New Config (eslint.config.mjs)

import compat from "eslint-plugin-compat";

export default [compat.configs["flat/recommended"]];

Legacy Config (.eslintrc.json)

{
  "plugins": ["compat"],
  "extends": ["plugin:compat/recommended"],
  "env": {
    "browser": true
  }
}

Configure Target Browsers (package.json)

{
  "browserslist": ["defaults"]
}

Adding Polyfills

{
  "settings": {
    "polyfills": [
      "Promise",
      "WebAssembly.compile",
      "fetch",
      "Array.prototype.push"
    ]
  }
}

Architecture

ESLint Plugin Compat is built around several key components:

  • ESLint Plugin Interface: Standard ESLint plugin structure with metadata, rules, and configurations
  • Compatibility Rule Engine: Core compat rule that checks API usage against browser support data
  • Data Providers: Integration with Can I Use and MDN Browser Compat Data for compatibility information
  • Target Resolution: Browserslist integration to determine target browsers from configuration
  • Configuration Presets: Pre-configured rule sets for flat and legacy ESLint config formats

Capabilities

Plugin Configuration

Main plugin object that provides ESLint integration with browser compatibility checking functionality.

/**
 * Main ESLint plugin export containing rules, configs, and metadata
 */
interface ESLintCompatPlugin {
  /** Plugin metadata including name and version */
  meta: {
    name: string;
    version: string;
  };
  /** Available rules provided by the plugin */
  rules: {
    compat: Rule.RuleModule;
  };
  /** Configuration presets for different ESLint config formats */
  configs: {
    "flat/recommended": Linter.FlatConfig;
    recommended: Linter.Config;
  };
  /** @deprecated Use configs instead - will be removed in next major release */
  config: {
    "flat/recommended": Linter.FlatConfig;
    recommended: Linter.Config;
  };
}

Compatibility Rule

The core compat rule that performs browser compatibility checking of API usage.

/**
 * ESLint rule that checks browser compatibility of API usage
 */
interface CompatRule extends Rule.RuleModule {
  /** Rule metadata and configuration schema */
  meta: {
    docs: {
      description: "Ensure cross-browser API compatibility";
      category: "Compatibility";
      url: string;
      recommended: true;
    };
    type: "problem";
    schema: [{ type: "string" }];
  };
  /** Rule factory function that creates the rule implementation */
  create(context: Context): ESLintVisitorObject;
}

/**
 * ESLint visitor object with AST node handlers for compatibility checking
 */
interface ESLintVisitorObject {
  /** Handler for function call expressions */
  CallExpression: (node: ESLintNode) => void;
  /** Handler for constructor expressions */
  NewExpression: (node: ESLintNode) => void;
  /** Handler for member access expressions */
  MemberExpression: (node: ESLintNode) => void;
  /** Handler for expression statements */
  ExpressionStatement: (node: ESLintNode) => void;
  /** Handler for identifier nodes to track variable definitions */
  Identifier: (node: ESLintNode) => void;
  /** Handler executed when AST traversal completes */
  "Program:exit": () => void;
}

Configuration Contexts

Rule context interface that extends ESLint's base context with plugin-specific settings.

/**
 * Extended ESLint rule context with compat-specific settings
 */
interface Context extends Rule.RuleContext {
  /** Plugin-specific configuration settings */
  settings: {
    /** Target browser strings (deprecated, use browserslist) */
    targets?: string[];
    /** Browser configuration (deprecated, use browserslist) */
    browsers?: Array<string>;
    /** Array of polyfilled API names to suppress warnings */
    polyfills?: Array<string>;
    /** Enable linting of ES APIs in addition to Web APIs */
    lintAllEsApis?: boolean;
    /** Browserslist configuration options */
    browserslistOpts?: BrowsersListOpts;
  };
}

/**
 * Browserslist configuration options
 */
interface BrowsersListOpts {
  /** Environment to use from browserslist config (production/development) */
  env?: string;
  /** Additional browserslist options */
  [key: string]: any;
}

Browser Target Configuration

Types for configuring browser targets and compatibility checking.

/**
 * Browserslist configuration format
 */
type BrowserListConfig =
  | string
  | Array<string>
  | {
      production?: Array<string>;
      development?: Array<string>;
    }
  | null;

/**
 * Browser target specification
 */
interface Target {
  /** Browser target identifier */
  target: keyof TargetNameMappings;
  /** Parsed version number for comparison */
  parsedVersion: number;
  /** Version string, number, or "all" for all versions */
  version: number | string | "all";
}

/**
 * Mappings from browser target IDs to display names
 */
interface TargetNameMappings {
  chrome: "Chrome";
  firefox: "Firefox";
  safari: "Safari";
  ios_saf: "iOS Safari";
  ie: "IE";
  ie_mob: "IE Mobile";
  edge: "Edge";
  baidu: "Baidu";
  electron: "Electron";
  blackberry_browser: "Blackberry Browser";
  edge_mobile: "Edge Mobile";
  and_uc: "Android UC Browser";
  and_chrome: "Android Chrome";
  and_firefox: "Android Firefox";
  and_webview: "Android Webview";
  and_samsung: "Samsung Browser";
  and_opera: "Opera Android";
  opera: "Opera";
  opera_mini: "Opera Mini";
  opera_mobile: "Opera Mobile";
  node: "Node.js";
  kaios: "KaiOS";
}

AST Node Types

Types for ESLint AST nodes that the plugin processes during compatibility checking.

/**
 * ESLint AST node representation
 */
interface ESLintNode {
  /** Node name/identifier */
  name: string;
  /** AST node type */
  type: string;
  /** Node value if applicable */
  value?: unknown;
  /** Object reference for member expressions */
  object?: ESLintNode;
  /** Parent node reference */
  parent?: ESLintNode;
  /** Expression node reference */
  expression?: ESLintNode;
  /** Property node for member expressions */
  property?: ESLintNode;
  /** Callee node for call expressions */
  callee?: ESLintNode & {
    name: string;
    type?: string;
  };
}

/**
 * Supported AST node types for compatibility checking
 */
enum AstNodeTypes {
  MemberExpression = "MemberExpression",
  CallExpression = "CallExpression",
  NewExpression = "NewExpression"
}

API Compatibility Metadata

Types for compatibility data used by the plugin's data providers.

/**
 * API compatibility metadata with target resolution
 */
interface AstMetadataApiWithTargetsResolver {
  /** Unique API identifier */
  id: string;
  /** Can I Use database identifier */
  caniuseId?: string;
  /** API kind (web/es) */
  kind?: "web" | "es";
  /** API type (function/property/constructor) */
  type?: string;
  /** API name */
  name?: string;
  /** Object that contains this API */
  object: string;
  /** AST node type this API appears in */
  astNodeType: "MemberExpression" | "CallExpression" | "NewExpression";
  /** Property name for member expressions */
  property?: string;
  /** Prototype chain identifier */
  protoChainId: string;
  /** Full prototype chain */
  protoChain: Array<string>;
  /** Function to determine which targets don't support this API */
  getUnsupportedTargets: (
    node: AstMetadataApiWithTargetsResolver,
    targets: Target[]
  ) => Array<string>;
}

/**
 * Callback function for handling compatibility rule failures
 */
type HandleFailingRule = (
  node: AstMetadataApiWithTargetsResolver,
  eslintNode: ESLintNode
) => void;

Configuration Examples

Basic Setup with Default Browsers

// eslint.config.mjs
import compat from "eslint-plugin-compat";

export default [compat.configs["flat/recommended"]];
// package.json
{
  "browserslist": ["defaults"]
}

Custom Browser Targets

{
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

Environment-Specific Configuration

{
  "browserslist": {
    "production": [
      "> 1%",
      "not dead"
    ],
    "modern": [
      "last 1 chrome version",
      "last 1 firefox version"
    ]
  }
}
{
  "settings": {
    "browserslistOpts": {
      "env": "modern"
    }
  }
}

Advanced Settings

{
  "settings": {
    "polyfills": [
      "Promise",
      "WebAssembly.compile",
      "fetch",
      "Array.prototype.push"
    ],
    "lintAllEsApis": true,
    "browserslistOpts": {
      "env": "production"
    }
  }
}

Legacy ESLint Configuration

{
  "plugins": ["compat"],
  "extends": ["plugin:compat/recommended"],
  "env": {
    "browser": true
  },
  "settings": {
    "polyfills": ["fetch", "Promise"]
  }
}