NPM and NodeJS should do more to make ES Modules easy to use

State of Adoption and Fragmentation

  • Many commenters say CommonJS (CJS) is still dominant in npm, especially among “high‑impact” packages; ESM-only versions of popular libs often see fewer installs.
  • There’s concern that enforcing ESM would split the ecosystem, similar to Python 2/3, and keep many projects stuck on old Node versions.

Migration Pain and Backward Compatibility

  • Large CJS codebases face major refactors to adopt ESM; some report it was easier to rewrite features than migrate whole apps.
  • Mixed CJS/ESM projects are described as brittle: config (package.json type, file extensions), bundlers, and test frameworks all need careful tuning.
  • Lack of simple, synchronous interop is a recurring complaint. People want to require ESM from CJS (or an importSync) without rewriting async flows.

Arguments in Favor of ESM

  • ESM is the JavaScript standard, works natively in browsers, and unifies server and client syntax.
  • Static, analyzable imports help with tree‑shaking, memory optimization, dependency analysis, and future features like type annotations without transpilation.
  • Some report successful full‑ESM migrations with simpler setups and no desire to return to CJS.

Arguments Against / Skepticism

  • Many developers say ESM brings little or no concrete benefit to backend apps already using TypeScript and bundlers.
  • ESM is blamed for extra complexity (dual package formats, import maps, mocking in tests, polyfills ordering) and “theoretical” gains.
  • Some argue the ecosystem should have stayed with CJS or that ES modules are a “dead” delivery model since most real apps bundle.

Proposed Fixes and Alternatives

  • Suggestions:
    • Make type: "module" the default but keep CJS opt‑in.
    • Allow require() of ESM synchronously (now partially available behind flags in newer Node).
    • Deprecate CJS on a long timeline vs. never removing it at all.
  • Some recommend runtimes and registries that hide complexity (Bun, Deno, JSR) or bundlers like Vite/Parcel to smooth over module differences.