Baseline Logoeslint-plugin-baseline-js

Best Practices

Run JavaScript, TypeScript, CSS, and HTML checks under one Baseline policy.

Goal

Use one Baseline threshold across your app: JavaScript, TypeScript, CSS, and HTML. Choose widely, newly, or a year, then share that value across the rules below.

Set up your project

This recipe combines the JavaScript presets with separate CSS and HTML plugins. It includes type information for TypeScript files and browser globals for JavaScript and TypeScript.

Install the plugins

npm i -D eslint eslint-plugin-baseline-js typescript @typescript-eslint/parser @eslint/css @html-eslint/eslint-plugin globals

See Quick Start for supported Node.js and ESLint versions. The HTML example uses the language configuration available in current HTML ESLint releases.

Include your TypeScript files

Use your existing tsconfig.json, or start with this browser project setup. The parser uses its library declarations to identify API types.

tsconfig.json
{
  "compilerOptions": {
    "target": "ESNext",
    "lib": ["DOM", "ESNext"],
    "jsx": "preserve",
    "strict": true,
    "noEmit": true
  },
  "include": ["src/**/*.ts", "src/**/*.tsx"]
}

Type information

Keep every TypeScript file you lint in this project. The declarations describe APIs; they do not add browser support or polyfills.

Share one threshold across the rules

Save this as eslint.config.mjs. The highlighted lines connect each language to the shared policy.

eslint.config.mjs
import baselineJs, { BASELINE } from "eslint-plugin-baseline-js";
import tsParser from "@typescript-eslint/parser";
import css from "@eslint/css";
import html from "@html-eslint/eslint-plugin";
import globals from "globals";

const available = BASELINE.WIDELY; 

export default [
  // JavaScript: .js, .cjs, .mjs, and .jsx
  {
    ...baselineJs.configs.recommended({ available }), 
    plugins: { "baseline-js": baselineJs },
    languageOptions: {
      globals: globals.browser,
      parserOptions: { ecmaFeatures: { jsx: true } },
    },
  },
  // TypeScript: .ts and .tsx, with type information
  {
    ...baselineJs.configs["recommended-ts"]({ available }), 
    plugins: { "baseline-js": baselineJs },
    languageOptions: {
      globals: globals.browser,
      parser: tsParser,
      parserOptions: {
        project: "./tsconfig.json",
        tsconfigRootDir: import.meta.dirname,
      },
    },
  },
  // CSS
  {
    files: ["**/*.css"],
    plugins: { css },
    language: "css/css",
    rules: {
      "css/use-baseline": ["error", { available }], 
    },
  },
  // HTML
  {
    files: ["**/*.html"],
    plugins: { "@html-eslint": html },
    language: "@html-eslint/html",
    rules: {
      "@html-eslint/use-baseline": ["error", { available }], 
    },
  },
];

Each block has its own file scope. JavaScript globals and parser settings stay within the JavaScript and TypeScript blocks. Override files if your project uses other extensions.

Run the checks

pnpm exec eslint src

Review reports, then choose a different threshold or a narrow exception where your project needs one.

Variations: pick what fits

Allow features marked widely available in each plugin's data:

const available = BASELINE.WIDELY; 

One policy, separate data

The shared value keeps your policy consistent. Each plugin has its own data version and detection coverage.

JavaScript-only or TypeScript-only projects

Remove the TypeScript block and parser import if your project has no TypeScript files. Remove the JavaScript block if you only lint TypeScript. Keep the CSS and HTML blocks for the files you use.

The JavaScript block runs without type information. Add a parser project for JavaScript if you need supported instance-member checks there too.

Choose environment globals

Use globals.browser, globals.worker, or globals.node in the JavaScript or TypeScript block that needs those names. For example, replace the browser globals in a worker's block:

Inside the worker config block
languageOptions: {
  globals: globals.worker, 
}

This can prevent no-undef reports when that rule is enabled. Global names do not change Baseline targets: the rule still uses browser data for Node.js and worker code.

Operational tips

  • Review Scope & Terms when choosing detection options.
  • Use ignoreFeatures or ignoreNodeTypes for documented exceptions and phased rollout.
  • Review Coverage when you update the plugin.
  • Test your polyfills, fallbacks, and runtime feature checks in your target environments.

For more language-specific options, see ESLint CSS and HTML ESLint.

Last updated on

On this page