CommonJS vs ES Modules in Node.js

Node.js supports two distinct module systems for organizing and sharing code: CommonJS (CJS) and ECMAScript Modules (ESM). While CommonJS has been the traditional default in Node.js using require() and module.exports, ES Modules represent the modern JavaScript standard utilizing import and export syntax. This article explores the key differences between these two systems, including syntax, loading behavior, configuration, and environment variables.

Syntax: Import/Export vs Require/Exports

The most visible difference between CommonJS and ES Modules is the syntax used to import and export code.

CommonJS

CommonJS uses require() to import modules and module.exports or exports to export them.

// importing
const fs = require('fs');

// exporting
module.exports = function helper() {
  return "helper";
};

ES Modules

ES Modules use standard ES6 import and export statements.

// importing
import fs from 'fs';

// exporting
export default function helper() {
  return "helper";
}

Loading Mechanism: Synchronous vs Asynchronous

The underlying execution and loading behaviors of the two systems are fundamentally different.

Configuration and File Extensions

Node.js determines which module system to use based on file extensions or configuration in package.json.

Global Variables and Context

Several global variables that are standard in CommonJS are not available in ES Modules.

__dirname and __filename

In CommonJS, you can easily get the current directory and file path using __dirname and __filename. These globals do not exist in ES Modules. In ESM, you must replicate this behavior using import.meta.url and the url utility module:

import { fileURLToPath } from 'url';
import { dirname } from 'path';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

Strict Mode

Interoperability

While you can import CommonJS modules into ES Modules, you cannot easily do the reverse.

// Inside a CommonJS file
import('./module.mjs').then((module) => {
  // Use the module here
});