Skip to content

Node.js module extensions (.cjs / .mjs / .cts / .mts) are not recognized; modern Node packages index with near-zero coverage #156

Description

@Widthdom

Summary

cdidx languages maps JavaScript to .js / .jsx and TypeScript to .ts / .tsx only. The Node.js ecosystem has used additional, standard, non-optional extensions for years:

  • .cjs — explicit CommonJS module (Node ≥ 12, widely used since ~2019).
  • .mjs — explicit ES module (Node ≥ 12, widely used since ~2019).
  • .cts — TypeScript authored for CommonJS output (tsc standard).
  • .mts — TypeScript authored for ESM output (tsc standard).
  • .d.cts / .d.mts — matching type declaration variants.

Files with these extensions are silently skipped by the scanner, so indexing any modern Node package yields a misleadingly small file count and a near-empty symbol graph.

Repro

On this environment Node 22's bundled packages are installed at /opt/node22/lib/node_modules:

curl -fsSL https://raw.githubusercontent.com/Widthdom/CodeIndex/main/install.sh | bash
CDIDX=/root/.local/bin/cdidx

"$CDIDX" /opt/node22/lib/node_modules/prettier --db /tmp/prettier.db
"$CDIDX" map --db /tmp/prettier.db

Observed

Files : 34
Lines : 9,772
Symbols : 292

Prettier ships 19 .mjs files (doc.mjs, index.mjs, standalone.mjs, and the entire plugins/ directory: babel.mjs, typescript.mjs, markdown.mjs, html.mjs, ...), all of which are invisible to the scanner. The only files indexed are a handful of .js and .ts leftovers plus READMEs, not the actual prettier logic.

Same pattern reproduces across /opt/node22/lib/node_modules/pnpm (entire runtime is a single dist/pnpm.cjs, indexed as 0 symbols), eslint (many .cjs / .d.cts type declarations missed), playwright (index.mjs / test.mjs missed), and so on.

Rough file-type counts under /opt/node22 show dozens of .mjs, dozens of .cjs, and dozens of .cts files, none of which are indexable today.

Root cause

src/CodeIndex/Indexer/FileIndexer.csLangMap is built from a fixed extension table and the current JavaScript / TypeScript entries do not cover .cjs / .mjs / .cts / .mts:

Confirmed via cdidx languages:

javascript     .js .jsx                             yes       yes
typescript     .ts .tsx                             yes       yes

Why it matters

  • Coverage collapse on modern Node packages. Pure-ESM packages ("type": "module" in package.json, all sources as .mjs) and dual-publish packages (bundlers emit both .cjs and .mjs) index as empty or near-empty. Users running cdidx on their own Node monorepo will silently get the wrong view.
  • Asymmetric with TypeScript's own conventions. tsc officially emits .cts / .mts for explicit CJS / ESM targeting, and many library authors have adopted them for dual-publishing. Missing these makes cdidx's TypeScript coverage noticeably partial on real-world repos.
  • Silent failure. The scanner just doesn't add the file — there's no warning, no "unsupported extension" hint. A user sees Files : 34 and must know Node's extension conventions to realize what's missing.

Suggested direction

  1. Add the extensions to the language map. Treat .cjs and .mjs as javascript; .cts and .mts as typescript. .d.cts / .d.mts are type declaration variants that parallel .d.ts — treat the same way .d.ts is treated today.
  2. Confirm the regex patterns in SymbolExtractor.cs and ReferenceExtractor.cs don't key off the extension specifically (they shouldn't — they key off language name), so adding extensions to the language map should be sufficient.
  3. Update cdidx languages output to include the new extensions.
  4. Add README notes for "modern Node extensions supported" so users running dual-publish monorepos know cdidx covers them.

Bonus follow-up (separate issue if desired): surface a WARN when cdidx <path> scans find files whose extensions are not in LangMap but are unusually common (e.g. .cjs, .pm, .vim), to avoid silent zero-index.

Scope

  • src/CodeIndex/Indexer/FileIndexer.cs — extend LangMap entries.
  • src/CodeIndex/Cli/ConsoleUi.cs — update help / languages tables if any of them hardcode the list.
  • tests/CodeIndex.Tests/FileIndexerTests.cs — regression fixtures covering each new extension + one .d.cts / .d.mts type declaration.
  • README / DEVELOPER_GUIDE language tables if they enumerate extensions.

Related

Environment

  • cdidx: v1.9.0 (installed via install.sh).
  • Indexed: /opt/node22/lib/node_modules/prettier (8.2 MB, ships mostly .mjs bundles); repro also trivially hits on pnpm, eslint, playwright, ts-node, chromedriver, http-server.
  • Platform: linux-x64 container.
  • Filed from a cloud Claude Code session per CLOUD_BOOTSTRAP_PROMPT.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions