Summary
@osls/compose declares support for Node 24 (engines: "^20.19.0 || ^22.13.0 || >=24") but require()s ESM-only dependencies:
src/utils/aws/config.js:3 → const { HttpsProxyAgent } = require('https-proxy-agent'); (https-proxy-agent@^9.0.0, ESM-only)
src/cli/Progresses.js:9 → const cliCursor = require('cli-cursor').default; (cli-cursor@^5.0.0, ESM-only)
These only load because Node ≥22.12 / 24 enables require(esm) by default — an experimental feature. As a result the CLI:
- emits
ExperimentalWarning: Support for loading ES Module in require() is an experimental feature on every run, and
- crashes with
ERR_REQUIRE_ESM whenever require(esm) is turned off — e.g. --no-experimental-require-module, a legitimate/supported setting (and the default before Node flipped it), commonly applied via NODE_OPTIONS or an .npmrc node-options= entry.
Reproduction
# Node 24.x
node --no-experimental-require-module \
-e "require('@osls/compose/src/cli/Progresses.js')"
or, in any project whose .npmrc/env disables the flag:
Actual:
Error [ERR_REQUIRE_ESM]: require() of ES Module .../cli-cursor/index.js
from .../@osls/compose/src/cli/Progresses.js not supported.
Instead change the require of index.js to a dynamic import() ...
Once one such dependency is worked around, the next (https-proxy-agent) throws — i.e. there are multiple affected require() sites.
Expected: the CLI runs on Node 24 regardless of the require(esm) flag state, without relying on an experimental feature.
Why CI doesn't catch it
.github/workflows/tests.yml runs unit tests only on Node 20 and 22; the Node 24 job runs only formatting/lint + pack-smoke.js. No test exercises the require()-of-ESM code path on the version being advertised as supported.
Suggested fixes
- Load these ESM-only deps via dynamic
import(), or pin CJS-compatible versions (https-proxy-agent@7, cli-cursor@3), so loading never depends on require(esm).
- Add a Node 24 unit-test job (ideally one also run with
--no-experimental-require-module) to prevent regressions.
Environment
@osls/compose 1.9.1 (npm) / osls 4.0.0
- Node 24.18.0, npm 11.x, Linux (GitHub Actions
ubuntu-latest); also reproduced on macOS.
Summary
@osls/composedeclares support for Node 24 (engines: "^20.19.0 || ^22.13.0 || >=24") butrequire()s ESM-only dependencies:src/utils/aws/config.js:3→const { HttpsProxyAgent } = require('https-proxy-agent');(https-proxy-agent@^9.0.0, ESM-only)src/cli/Progresses.js:9→const cliCursor = require('cli-cursor').default;(cli-cursor@^5.0.0, ESM-only)These only load because Node ≥22.12 / 24 enables
require(esm)by default — an experimental feature. As a result the CLI:ExperimentalWarning: Support for loading ES Module in require() is an experimental featureon every run, andERR_REQUIRE_ESMwheneverrequire(esm)is turned off — e.g.--no-experimental-require-module, a legitimate/supported setting (and the default before Node flipped it), commonly applied viaNODE_OPTIONSor an.npmrcnode-options=entry.Reproduction
or, in any project whose
.npmrc/env disables the flag:Actual:
Once one such dependency is worked around, the next (
https-proxy-agent) throws — i.e. there are multiple affectedrequire()sites.Expected: the CLI runs on Node 24 regardless of the
require(esm)flag state, without relying on an experimental feature.Why CI doesn't catch it
.github/workflows/tests.ymlruns unit tests only on Node 20 and 22; the Node 24 job runs only formatting/lint +pack-smoke.js. No test exercises therequire()-of-ESM code path on the version being advertised as supported.Suggested fixes
import(), or pin CJS-compatible versions (https-proxy-agent@7,cli-cursor@3), so loading never depends onrequire(esm).--no-experimental-require-module) to prevent regressions.Environment
@osls/compose1.9.1 (npm) /osls4.0.0ubuntu-latest); also reproduced on macOS.