Skip to content

@elastic/eslint-plugin-eui: missing runtime dependencies cause ESLint to fail on load #9780

Description

@cleydyr

Describe the bug

@elastic/eslint-plugin-eui fails to load in consumer projects because it requires cssstyle at runtime, but cssstyle is only listed in devDependencies.

When ESLint loads the plugin (e.g. via plugin:@elastic/eui/recommended or flat config), it crashes immediately:

Error: Cannot find module 'cssstyle'
Require stack:
- .../node_modules/@elastic/eslint-plugin-eui/lib/esm/rules/no_css_color.js
- .../node_modules/@elastic/eslint-plugin-eui/lib/esm/index.js

The plugin entry point imports no_css_color at the top level, so the failure happens before any EUI rule runs — including rules unrelated to @elastic/eui/no-css-color.

There is a similar packaging gap with micromatch, which is required at runtime by no-restricted-eui-imports.js but is also only listed in devDependencies. It may work when hoisted by other dependencies, but that is not reliable.

Impact and severity

  • Impact: Any consumer enabling @elastic/eslint-plugin-eui cannot run ESLint at all unless they manually install missing packages.
  • Severity: High for consumers of the plugin — ESLint fails completely, so no linting runs (including unrelated rules).
  • Workaround: Manually install the missing dependency:
    yarn add -D cssstyle
    (micromatch may also need to be installed manually in some setups.)

Environment and versions

  • EUI version: @elastic/eui@116.3.1
  • ESLint plugin: @elastic/eslint-plugin-eui@2.14.0 (declared as ^2.3.0 in package.json)
  • React version: 18.3.1
  • ESLint: 10.4.1
  • Node: 22.22.0
  • Kibana version (if applicable): N/A
  • Browser: N/A (CLI / IDE tooling)
  • Operating System: macOS (Darwin)
  • Package manager: yarn

Minimum reproducible sandbox

This is an ESLint plugin packaging issue, not a React/UI runtime bug, so a CodeSandbox on eui.elastic.co is not applicable.

Minimal reproduction is a fresh Node project with ESLint and the plugin installed.

To Reproduce

  1. Create a fresh project and install ESLint + the EUI plugin (without cssstyle):

    mkdir eui-eslint-repro && cd eui-eslint-repro
    yarn init -y
    yarn add -D eslint @elastic/eslint-plugin-eui typescript-eslint
    # add "type": "module" to package.json
    # create eslint.config.js and example.tsx (as below)
  2. Create eslint.config.js:

    import elasticEuiPlugin from '@elastic/eslint-plugin-eui'
    
     export default [
       {
         files: ['**/*.{js,jsx,ts,tsx}'],
         plugins: {
           '@elastic/eui': elasticEuiPlugin,
         },
         rules: {
           ...elasticEuiPlugin.configs.recommended.rules,
         },
       },
     ]
  3. Create any file to lint, e.g. example.tsx:

    export const Example = () => null
  4. Run ESLint:

    yarn eslint example.tsx
  5. See error: Cannot find module 'cssstyle'

Expected behavior

Following the plugin README (Extend plugin:@elastic/eui/recommended) should allow ESLint to load and run without requiring consumers to install undeclared runtime dependencies.

Screenshots (Optional)

N/A — CLI error output:

Error: Cannot find module 'cssstyle'
Require stack:
- .../node_modules/@elastic/eslint-plugin-eui/lib/esm/rules/no_css_color.js
- .../node_modules/@elastic/eslint-plugin-eui/lib/esm/index.js

Additional context (Optional)

Root cause

In packages/eslint-plugin/package.json, cssstyle is listed under devDependencies:

"devDependencies": {
  "cssstyle": "^4.2.1",
  ...
}

But it is imported at runtime in no_css_color:

const cssstyle_1 = require("cssstyle");

Because lib/esm/index.js imports ./rules/no_css_color at the top level, the module load fails for all consumers.

Suggested fix

Move runtime dependencies from devDependencies to dependencies in packages/eslint-plugin/package.json:

{
  "dependencies": {
    "cssstyle": "^4.2.1",
    "micromatch": "^4.0.8"
  }
}

Related note

The plugin’s peerDependencies currently declare eslint: "^8.57.0 || ^9.0.0". We are using ESLint 10 with flat config and it appears to work once cssstyle is installed, but the peer range may need updating separately.

typescript-eslint is needed in the repro because every EUI rule depends on @typescript-eslint/utils, which is also undeclared. Without it, you hit that error before cssstyle. For a TypeScript + EUI consumer that’s the realistic path — and it matches Biblivre, where typescript-eslint was already installed.

Metadata

Metadata

Labels

No labels
No labels

Type

Fields

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions