{"id":25071,"library":"cjs-module-lexer","title":"cjs-module-lexer","description":"A fast CommonJS module syntax lexer that detects named exports and reexports from CJS modules, used in Node.js core for ESM interop. Current stable version: 2.2.0. Maintained by Node.js team; release cadence is irregular but active for parser bugs and performance improvements. Key differentiators: extremely fast (~90ms/MB cold, ~15ms/MB warm), frozen detection patterns to ensure backwards compatibility across Node.js versions, and support for transpiler variations (e.g., TypeScript, Babel). Provides both Node.js (CJS) and Wasm (ESM) builds, with TypeScript declarations included.","status":"active","version":"2.2.0","language":"javascript","source_language":"en","source_url":"https://github.com/nodejs/cjs-module-lexer","tags":["javascript","typescript"],"install":[{"cmd":"npm install cjs-module-lexer","lang":"bash","label":"npm"},{"cmd":"yarn add cjs-module-lexer","lang":"bash","label":"yarn"},{"cmd":"pnpm add cjs-module-lexer","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"For ESM, init() must be awaited before first parse() call. For CJS, init is automatically handled.","wrong":"const parse = require('cjs-module-lexer').parse","symbol":"parse","correct":"import { parse, init } from 'cjs-module-lexer'"},{"note":"init() is only needed for Wasm build (ESM). In CJS, it's a no-op promise.","wrong":"const { init } = require('cjs-module-lexer')","symbol":"init","correct":"import { init } from 'cjs-module-lexer'"},{"note":"CJS import: destructure parse from the module. No need to call init().","wrong":"const cjsModuleLexer = require('cjs-module-lexer'); cjsModuleLexer.parse(source)","symbol":"parse","correct":"const { parse } = require('cjs-module-lexer'); parse(source)"}],"quickstart":{"code":"import { parse, init } from 'cjs-module-lexer';\n\nconst source = `\n  module.exports.a = 'a';\n  if (maybe) module.exports = require('./dep1.js');\n  module.exports = { b, c: d };\n`;\n\nawait init();\nconst { exports, reexports } = parse(source);\nconsole.log(exports);   // ['a', 'b', 'c', '__esModule']\nconsole.log(reexports); // ['./dep1.js']\n","lang":"typescript","description":"Demonstrates ESM usage with Wasm: import parse and init, await init(), parse a CJS source, and obtain exports/reexports arrays."},"warnings":[{"fix":"Add await init() before calling parse() in ESM environments. CJS users are unaffected.","message":"In v2.0.0, the Wasm build was introduced and the ESM API changed: init() must be called before parse(). Previously, init() was not required and Wasm was not used.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Do not rely on detection of non-standard patterns. Ensure your code uses the documented export forms (e.g., exports.X = ..., module.exports = { ... }, Object.defineProperty(exports, ...)).","message":"The detection patterns are frozen; new export patterns will not be added. This ensures backwards compatibility but means some modern CJS patterns may not be detected.","severity":"deprecated","affected_versions":">=1.0.0"},{"fix":"Test your modules with the lexer to ensure expected exports are detected. For complex cases, consider alternative tools.","message":"The lexer does not handle all JavaScript edge cases (e.g., dynamic require, conditional exports inside functions). It uses a token grammar that may miss exports with unusual whitespace or comments.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Filter out '__esModule' from exports if not needed: exports.filter(e => e !== '__esModule')","message":"The `__esModule` export is always included in the exports array if Object.defineProperty(module.exports, '__esModule', ...) is present. This may be unexpected for some users.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Upgrade to 2.2.0 or later, and verify export detection.","message":"Version 1.4.2 included a change that moved to a common wasm-builder, but this was later refined. Users upgrading from 1.x should test exports detection thoroughly.","severity":"breaking","affected_versions":"1.4.2"}],"env_vars":null,"last_verified":"2026-05-01T00:00:00.000Z","next_check":"2026-07-30T00:00:00.000Z","problems":[{"fix":"Add await init(); before any parse() call in ESM context.","cause":"Using ESM import with Wasm build but not calling await init() first.","error":"Error: Must call init() before parse()"},{"fix":"Use const { parse } = require('cjs-module-lexer'); in CommonJS.","cause":"Importing cjs-module-lexer incorrectly in CJS, e.g., using default import or wrong destructure.","error":"TypeError: parse is not a function"},{"fix":"Ensure source code is wrapped in a CommonJS module wrapper when lexing; the lexer expects valid CJS syntax.","cause":"Trying to access exports in a context where the CJS wrapper (function(exports, module, require) { ... }) is not provided.","error":"ReferenceError: exports is not defined"},{"fix":"Use require('./foo') with a string literal; ensure no dynamic expressions.","cause":"Using module.exports = require('./foo') without quotes around the path? Actually, the lexer expects string literals.","error":"Warning: cjs-module-lexer detected a reexport but the path './foo' is not quoted?"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}