Bug
Importing @beeper/chat-adapter-matrix in a Node.js ESM project crashes at startup:
Error [ERR_MODULE_NOT_FOUND]: Cannot find module
'/path/node_modules/matrix-js-sdk/lib/http-api/errors'
imported from /path/node_modules/@beeper/chat-adapter-matrix/dist/index.js
Did you mean to import "matrix-js-sdk/lib/http-api/errors.js"?
Environment
- Node.js 22.16.0
@beeper/chat-adapter-matrix 0.2.0
matrix-js-sdk 41.3.0 (type: "module")
- No bundler — direct Node.js ESM execution
Root cause
tsup.config.ts marks matrix-js-sdk as external, so tsup copies the import specifiers verbatim from the TypeScript source into dist/index.js. TypeScript resolves these without .js extensions via its own module algorithm, but Node.js ESM requires explicit .js for subpath imports into other ESM packages that don't have a matching exports map entry.
Five imports in dist/index.js are affected:
import { MatrixError } from "matrix-js-sdk/lib/http-api/errors"; // needs errors.js
import { decodeRecoveryKey } from "matrix-js-sdk/lib/crypto-api/recovery-key"; // needs recovery-key.js
import { logger as matrixSDKLogger } from "matrix-js-sdk/lib/logger"; // needs logger.js
import { SyncAccumulator } from "matrix-js-sdk/lib/sync-accumulator"; // needs sync-accumulator.js
import { MemoryStore } from "matrix-js-sdk/lib/store/memory"; // needs memory.js
matrix-js-sdk has been type: "module" since at least v39.0.0 and does not define exports entries for these deep paths, so Node falls back to direct file resolution which requires the .js extension.
Suggested fix
A few options:
-
Source-level: write imports with .js in the TypeScript source and set moduleResolution: "node16" or "nodenext" in tsconfig.json — TypeScript will resolve them correctly and they'll pass through to the output as-is.
-
Build-level: remove matrix-js-sdk from external in tsup.config.ts so tsup bundles it into the output — avoids the subpath import entirely.
-
Post-build: add an esbuild plugin or postbuild script to append .js to extensionless external imports targeting matrix-js-sdk/lib/.
Option 1 is the cleanest long-term.
Bug
Importing
@beeper/chat-adapter-matrixin a Node.js ESM project crashes at startup:Environment
@beeper/chat-adapter-matrix0.2.0matrix-js-sdk41.3.0 (type: "module")Root cause
tsup.config.tsmarksmatrix-js-sdkasexternal, so tsup copies the import specifiers verbatim from the TypeScript source intodist/index.js. TypeScript resolves these without.jsextensions via its own module algorithm, but Node.js ESM requires explicit.jsfor subpath imports into other ESM packages that don't have a matchingexportsmap entry.Five imports in
dist/index.jsare affected:matrix-js-sdkhas beentype: "module"since at least v39.0.0 and does not defineexportsentries for these deep paths, so Node falls back to direct file resolution which requires the.jsextension.Suggested fix
A few options:
Source-level: write imports with
.jsin the TypeScript source and setmoduleResolution: "node16"or"nodenext"intsconfig.json— TypeScript will resolve them correctly and they'll pass through to the output as-is.Build-level: remove
matrix-js-sdkfromexternalintsup.config.tsso tsup bundles it into the output — avoids the subpath import entirely.Post-build: add an esbuild plugin or postbuild script to append
.jsto extensionless external imports targetingmatrix-js-sdk/lib/.Option 1 is the cleanest long-term.