Repository navigation
module: expose CJS named-exports detection (cjs-module-lexer equivalent) #63123
Description
Activity
- addedfeature requestIssues requesting new Node.js features.Issues requesting new Node.js features.
on May 5, 2026 - addedmoduleIssues and PRs related to the module subsystem.Issues and PRs related to the module subsystem.loadersIssues and PRs related to ES module loaders.Issues and PRs related to ES module loaders.
on May 5, 2026 Node.js doesn't actually use cjs-module-lexer anymore, it switched to the native C++ merve lexer in releases 25.6.1 and 24.14.0. Just noting that in case it makes a difference in terms of API design or behaviour.
Reacted by Simen BekkhusOh, that's interesting! I missed that. In that case this ask is more relevant again and my point about getting fixes not in node is irrelevant
also the package is publish to npm so you can just use it https://www.npmjs.com/package/cjs-module-lexer
I know - that's what we do today, like mentioned in the OP
The current approach is the alternative: depending directly on
cjs-module-lexer.But if Node doesn't even use it anymore I don't think that's a good alternative anymore
I know - that's what we do today, like mentioned in the OP
The current approach is the alternative: depending directly on
cjs-module-lexer.But if Node doesn't even use it anymore I don't think that's a good alternative anymore
as my knowledge merve doesn't have node binding or wasm build. So yeah expose this api make sense
Reacted by Simen Bekkhus and ExE BossThis issue has been marked as stale due to 90 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.- addedstaleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.Issues and PRs marked stale due to inactivity and scheduled for automatic closure.
on Aug 6, 2026 This issue has been automatically closed after 30 days of inactivity following its stale status (no activity for a total of 120 days).
If this is still relevant, feel free to reopen it or leave a comment with additional details so we can continue the discussion.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsAwaiting Triage
What is the problem this feature will solve?
When loading a CJS module from ESM (
import {foo} from './bar.cjs'), the named exports have to be derived statically before the CJS body runs - ESM bindings need to exist at link time. Node already does this internally forrequire(esm)and friends, usingcjs-module-lexerto lex the CJS source.Frameworks doing the same job - Jest, and likely others wrapping CJS as ESM in custom contexts - currently take a direct dependency on the
cjs-module-lexernpm package and call it themselves. Works fine, but it's redundant: every framework re-vendors a parser that Node already runs, and parsing happens twice for the same source whenever Node and the framework both touch it.What is the feature you are proposing to solve the problem?
Some way to ask Node to do the lex for us. Two shapes that would both work:
module.cjsNamedExports(source: string | Buffer): string[]- pure helper, takes source, returns names.SyntheticModule.fromCjsExports(exports: object, options): SyntheticModule- higher-level convenience that does both the lex and the synthetic construction.Either shape lets frameworks delete the explicit
cjs-module-lexerdependency and lean on whatever Node ships. The first is more flexible (callers may want to combine the lexed names with runtimeObject.keys, which is what Jest does today to handleObject.assignpatterns the lexer can miss); the second is more ergonomic if the only use case is "wrap this CJS as ESM.". Both might make sense as well, but I understand the second one might feel out of scope 🙂What alternatives have you considered?
The current approach is the alternative: depending directly on
cjs-module-lexer. There's a real tradeoff worth flagging here, though.The npm package versions independently of Node. Bug fixes ship to users regardless of which Node version they're running. If the lexer moves into Node's surface, users get whatever lexer ships with their Node version - older Node releases would lock users to older lexer behavior, including known bugs, until they upgrade Node itself.
So I think the question isn't strictly "should Node expose this" but "is exposing it a net win given the versioning tradeoff." Possible answers:
I lean toward the second - the documented choice - but happy for that to be wrong.