Transform ID:Documentation Index
Fetch the complete documentation index at: https://docs.refactron.dev/llms.txt
Use this file to discover all available pages before exploring further.
commonjs_to_esm
Language: TypeScript
What it does
Rewrites the CommonJS module surface into ES modules:const x = require('m')→import x from 'm'(withnode:prefix for Node builtins).const { a, b } = require('m')→import { a, b } from 'm'.module.exports = X(identifier) →export default X.module.exports = { a, b }(object literal) → namedexport { a, b }.
Detector pattern
The detector atsrc/analyze/detectors/typescript/commonjs.ts finds ts-morph CallExpression nodes with the callee require and BinaryExpression nodes with module.exports on the left.
Preconditions
- The file does not use
__dirnameor__filename— these are CommonJS-only globals; ESM requiresimport.meta.urltranslation which is out of scope. - No dynamic require (
require(name)wherenameis not a string literal) — ESM imports must be static. - The file is not a
.cjsextension (explicitly opted into CommonJS by the user). - No
require.resolve(...),require.cache, or other Node CJS-specific APIs.
Before / after
Edge cases handled
- Node builtins (
path,fs,os,crypto, etc.) get the modernnode:specifier prefix. - Package specifiers (
lodash,express) are kept unprefixed. - Relative specifiers (
'./utils') are kept unprefixed. - Destructured require (
const { join } = require('path')) becomes named import. module.exports = identifierbecomesexport default identifier.module.exports = { a, b }becomesexport { a, b }.
Edge cases NOT handled (skip via precondition)
- File uses
__dirname/__filename(preconditionnode-globals). - Dynamic
require(name)wherenameis not a literal (preconditiondynamic-require). .cjsfiles (preconditioncjs-extension).module.exports.x = ...style (top-level mutation of the exports object — defer to a manual migration).
The actual reordering of declarations between input and output may differ —
module.exports = { join } references a join defined inline; the rewrite hoists the join const ahead of the named export. Run refactron run --dry-run for the exact diff in your code.