Skip to content

Modules & npm

Node.js ships with two module systems. CommonJS (CJS) is the original system and uses require() to load modules synchronously. ECMAScript Modules (ESM) is the modern standard, shared with browsers, and uses import / export statements.

Both systems are fully supported in current Node.js versions. Which one a file uses depends on the file extension and the "type" field in the nearest package.json.

CommonJSESM
Syntaxrequire() / module.exportsimport / export
File extension.js (default) or .cjs.mjs, or .js when "type": "module"
"type" in package.json"commonjs" (or absent)"module"
LoadingSynchronousAsynchronous (static analysis)
Top-level awaitNot supportedSupported
LessonTopic
Overview (this page)CJS vs ESM comparison and module system basics
package.json Deep DiveKey fields, semver ranges, and npm init
Module ResolutionHow Node finds files, the exports map, and bare specifiers
Managing DependenciesInstalling, updating, and auditing packages with npm
Publishing PackagesPreparing and publishing a package to the npm registry

The snippet below uses ESM import to load the built-in path module and print the platform path separator — the character Node uses between directory components (/ on Unix, \ on Windows):

Node.js

Needs the Node.js runtime — open in StackBlitz to run.

Which syntax does CommonJS use to load another module?
What file extension always forces a file to be treated as an ES module regardless of package.json?
Which package.json field switches the entire package to ESM so that .js files are treated as ES modules?