AceDevHub
Beginner Node.js Interview QuestionsBeginnerComparison

Node.js · Question 19

What is the difference between .js, .mjs, and .cjs in Node.js?

Direct answer

.js module type follows package.json "type" field; .mjs is always ESM (import/export); .cjs is always CommonJS (require/module.exports) — use explicit extensions when mixing systems in one project.

Node supports dual module systems during the long ESM migration. Extension + package.json type remove ambiguity for both Node and bundlers.

ExtensionModule systemNotes
.jsDepends on nearest package.json typetype:module → ESM; default/CommonJS → require
.mjsAlways ESMExplicit; good for config at repo root
.cjsAlways CommonJSLegacy tools, some config files
  • node: prefix — import fs from "node:fs" resolves core modules clearly (recommended).
  • Interop — ESM can import CJS default; CJS cannot require ESM without dynamic import().
  • AceDevHub — API uses "type": "module" + .ts compiled to ESM; content import scripts use tsx.
esm-vs-cjs.mjs
// file: utils.mjs — always ESM
export function greet(name) {
  return `Hello, ${name}`;
}

// file: legacy.cjs — always CommonJS
module.exports = { version: 1 };

// ESM importing CJS
import legacy from "./legacy.cjs";
console.log(legacy.version);