Visitar URL original
chore: Publish feathers as ESM only (v6) by fratzinger · Pull Request #3723 · feathersjs/feathers · GitHub
Skip to content

chore: Publish feathers as ESM only (v6) - #3723

Open
fratzinger wants to merge 1 commit into
feathersjs:v6from
fratzinger:chore/esm-only
Open

fratzinger wants to merge 1 commit into
feathersjs:v6from
fratzinger:chore/esm-only

Conversation

@fratzinger

Copy link
Copy Markdown
Member

Summary

feathers is now published as ESM only. The CommonJS build that #3674 added (cjs/, the require export conditions and tsconfig.cjs.json) is removed. CommonJS projects can still require('feathers') because Node.js loads ES modules synchronously with require() from Node.js 20.19 and 22.12. The library has no top-level await, which would prevent that.

 packages/feathers/package.json
   "exports": {
-    ".": { "import": "./lib/index.js", "require": "./cjs/index.js" },
+    ".": "./lib/index.js",
     ... (the same for all 7 subpaths)
   },
-  "files": [..., "lib/**", "cjs/**"],
+  "files": [..., "lib/**"],
-  "compile": "shx rm -rf lib/ cjs/ && tsc && tsc -p tsconfig.cjs.json && echo '{\"type\":\"commonjs\"}' > cjs/package.json"
+  "compile": "shx rm -rf lib/ && tsc"
-packages/feathers/tsconfig.cjs.json
 .gitignore, .eslintrc.js   cjs entries removed

Related: #3674. No dependencies on other PRs. #3720 (Node.js 24+) makes sure every supported Node.js version can require() ES modules.

Evidence

From a CommonJS consumer ("type": "commonjs"):

require() of all 7 subpaths + a service call throwing NotFound, and import():
v22.16.0  require OK | feathers:29 feathers/hooks:21 feathers/commons:7 feathers/errors:20 feathers/client:4 feathers/http:15 feathers/http/node:1 | call: NotFound
v24.16.0  require OK | (same)
v26.10.0  require OK | (same)

A TypeScript CommonJS consumer, by module / moduleResolution:

setting result
node16, node18 error TS1479 ("...the referenced file is an ECMAScript module and cannot be imported with 'require'")
nodenext OK (TypeScript 5.8+ supports require() of ESM)
commonjs + node10 OK
preserve + bundler OK
  • Before: npm pack includes the cjs/ build.
    After: npm pack has 0 files in cjs/. npm test passes on Node.js 24 and 26 with Tests 497 passed | 1 skipped, and CI is green on 20.x and 24.x.

Merge Danger

Door: two-way

Blast Radius: small

  • TypeScript CommonJS projects using module: node16 or node18 need to switch to nodenext or ESM. This belongs in the v6 migration guide.
  • On Node.js 20.0 to 20.18, require('feathers') fails. chore: Require Node.js 24 or later (v6) #3720 raises the minimum to Node.js 24.
  • Until now, ESM and CJS consumers could load two separate copies of the package (the dual package hazard). With a single build, instanceof checks such as error instanceof NotFound work across both module systems.
  • If chore: Migrate to ESLint 10 flat config with @feathers-community/eslint-config (v6) #3721 is merged first, its eslint.config.mjs still ignores **/cjs/. That leftover is harmless and can be removed when rebasing.

🤖 Generated with Claude Code

Remove the CommonJS build (`cjs/`) and the `require` export conditions.
CommonJS projects can still load `feathers` with `require()` since Node.js
supports loading ES modules synchronously (Node.js 20.19+ and 22.12+), and
the library has no top-level `await`.

TypeScript CommonJS projects using `module: node16` or `node18` now get
error TS1479 and need to switch to `module: nodenext` (TypeScript 5.8+).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@daffl

daffl commented Oct 28, 2026

Copy link
Copy Markdown
Member

I guess we should do this. I added CJS back because a few people with older projects said they still needed it. They probably won't be able to upgrade.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants