Node.js v25.9.0 documentation
- Node.js v25.9.0
- Table of contents
- Modules: CommonJS modules
- Enabling
- Accessing the main module
- Package manager tips
- Loading ECMAScript modules using
require() - All together
- Caching
- Built-in modules
- Cycles
- File modules
- Folders as modules
- Loading from
node_modulesfolders - Loading from the global folders
- The module wrapper
- The module scope
- The
moduleobject - The
Moduleobject - Source map v3 support
- Modules: CommonJS modules
- Index
- About this documentation
- Usage and example
- Assertion testing
- Asynchronous context tracking
- Async hooks
- Buffer
- C++ addons
- C/C++ addons with Node-API
- C++ embedder API
- Child processes
- Cluster
- Command-line options
- Console
- Crypto
- Debugger
- Deprecated APIs
- Diagnostics Channel
- DNS
- Domain
- Environment Variables
- Errors
- Events
- File system
- Globals
- HTTP
- HTTP/2
- HTTPS
- Inspector
- Internationalization
- Modules: CommonJS modules
- Modules: ECMAScript modules
- Modules:
node:moduleAPI - Modules: Packages
- Modules: TypeScript
- Net
- Iterable Streams API
- OS
- Path
- Performance hooks
- Permissions
- Process
- Punycode
- Query strings
- Readline
- REPL
- Report
- Single executable applications
- SQLite
- Stream
- String decoder
- Test runner
- Timers
- TLS/SSL
- Trace events
- TTY
- UDP/datagram
- URL
- Utilities
- V8
- VM
- WASI
- Web Crypto API
- Web Streams API
- Worker threads
- Zlib
- Zlib Iterable Compression
- Other versions
- Options
Modules: CommonJS modules#
Stability: 2 - Stable
CommonJS modules are the original way to package JavaScript code for Node.js. Node.js also supports the ECMAScript modules standard used by browsers and other JavaScript runtimes.
In Node.js, each file is treated as a separate module. For
example, consider a file named foo.js:
const circle = require('./circle.js');
console.log(`The area of a circle of radius 4 is ${circle.area(4)}`);
On the first line, foo.js loads the module circle.js that is in the same
directory as foo.js.
Here are the contents of circle.js:
const { PI } = Math;
exports.area = (r) => PI * r ** 2;
exports.circumference = (r) => 2 * PI * r;
The module circle.js has exported the functions area() and
circumference(). Functions and objects are added to the root of a module
by specifying additional properties on the special exports object.
Variables local to the module will be private, because the module is wrapped
in a function by Node.js (see module wrapper).
In this example, the variable PI is private to circle.js.
The module.exports property can be assigned a new value (such as a function
or object).
In the following code, bar.js makes use of the square module, which exports
a Square class:
const Square = require('./square.js');
const mySquare = new Square(2);
console.log(`The area of mySquare is ${mySquare.area()}`);
The square module is defined in square.js:
// Assigning to exports will not modify module, must use module.exports
module.exports = class Square {
constructor(width) {
this.width = width;
}
area() {
return this.width ** 2;
}
};
The CommonJS module system is implemented in the module core module.
Enabling#
Node.js has two module systems: CommonJS modules and ECMAScript modules.
By default, Node.js will treat the following as CommonJS modules:
-
Files with a
.cjsextension; -
Files with a
.jsextension when the nearest parentpackage.jsonfile contains a top-level field"type"with a value of"commonjs". -
Files with a
.jsextension or without an extension, when the nearest parentpackage.jsonfile doesn't contain a top-level field"type"or there is nopackage.jsonin any parent folder; unless the file contains syntax that errors unless it is evaluated as an ES module. Package authors should include the"type"field, even in packages where all sources are CommonJS. Being explicit about thetypeof the package will make things easier for build tools and loaders to determine how the files in the package should be interpreted. -
Files with an extension that is not
.mjs,.cjs,.json,.node, or.js(when the nearest parentpackage.jsonfile contains a top-level field"type"with a value of"module", those files will be recognized as CommonJS modules only if they are being included viarequire(), not when used as the command-line entry point of the program).
See Determining module system for more details.
Calling require() always use the CommonJS module loader. Calling import()
always use the ECMAScript module loader.
Accessing the main module#
When a file is run directly from Node.js, require.main is set to its
module. That means that it is possible to determine whether a file has been
run directly by testing require.main === module.
For a file foo.js, this will be true if run via node foo.js, but
false if run by require('./foo').
When the entry point is not a CommonJS module, require.main is undefined,
and the main module is out of reach.
Package manager tips#
The semantics of the Node.js require() function were designed to be general
enough to support reasonable directory structures. Package manager programs
such as dpkg, rpm, and npm will hopefully find it possible to build
native packages from Node.js modules without modification.
In the following, we give a suggested directory structure that could work:
Let's say that we wanted to have the folder at
/usr/lib/node/<some-package>/<some-version> hold the contents of a
specific version of a package.
Packages can depend on one another. In order to install package foo, it
may be necessary to install a specific version of package bar. The bar
package may itself have dependencies, and in some cases, these may even collide
or form cyclic dependencies.
Because Node.js looks up the realpath of any modules it loads (that is, it
resolves symlinks) and then looks for their dependencies in node_modules folders,
this situation can be resolved with the following architecture:
/usr/lib/node/foo/1.2.3/: Contents of thefoopackage, version 1.2.3./usr/lib/node/bar/4.3.2/: Contents of thebarpackage thatfoodepends on./usr/lib/node/foo/1.2.3/node_modules/bar: Symbolic link to/usr/lib/node/bar/4.3.2/./usr/lib/node/bar/4.3.2/node_modules/*: Symbolic links to the packages thatbardepends on.
Thus, even if a cycle is encountered, or if there are dependency conflicts, every module will be able to get a version of its dependency that it can use.
When the code in the foo package does require('bar'), it will get the
version that is symlinked into /usr/lib/node/foo/1.2.3/node_modules/bar.
Then, when the code in the bar package calls require('quux'), it'll get
the version that is symlinked into
/usr/lib/node/bar/4.3.2/node_modules/quux.
Furthermore, to make the module lookup process even more optimal, rather
than putting packages directly in /usr/lib/node, we could put them in
/usr/lib/node_modules/<name>/<version>. Then Node.js will not bother
looking for missing dependencies in /usr/node_modules or /node_modules.
In order to make modules available to the Node.js REPL, it might be useful to
also add the /usr/lib/node_modules folder to the $NODE_PATH environment
variable. Since the module lookups using node_modules folders are all
relative, and based on the real path of the files making the calls to
require(), the packages themselves can be anywhere.
Loading ECMAScript modules using require()#
The .mjs extension is reserved for ECMAScript Modules.
See Determining module system section for more info
regarding which files are parsed as ECMAScript modules.
require() only supports loading ECMAScript modules that meet the following requirements:
- The module is fully synchronous (contains no top-level
await); and - One of these conditions are met:
- The file has a
.mjsextension. - The file has a
.jsextension, and the closestpackage.jsoncontains"type": "module" - The file has a
.jsextension, the closestpackage.jsondoes not contain"type": "commonjs", and the module contains ES module syntax.
- The file has a
If the ES Module being loaded meets the requirements, require() can load it and
return the module namespace object. In this case it is similar to dynamic
import() but is run synchronously and returns the name space object
directly.
With the following ES Modules:
// distance.mjs
export function distance(a, b) { return Math.sqrt((b.x - a.x) ** 2 + (b.y - a.y) ** 2); }
// point.mjs
export default class Point {
constructor(x, y) { this.x = x; this.y = y; }
}
A CommonJS module can load them with require():
const distance = require('./distance.mjs');
console.log(distance);
// [Module: null prototype] {
// distance: [Function: distance]
// }
const point = require('./point.mjs');
console.log(point);
// [Module: null prototype] {
// default: [class Point],
// __esModule: true,
// }
For interoperability with existing tools that convert ES Modules into CommonJS,
which could then load real ES Modules through require(), the returned namespace
would contain a __esModule: true property if it has a default export so that
consuming code generated by tools can recognize the default exports in real
ES Modules. If the namespace already defines __esModule, this would not be added.
This property is experimental and can change in the future. It should only be used
by tools converting ES modules into CommonJS modules, following existing ecosystem
conventions. Code authored directly in CommonJS should avoid depending on it.
The result returned by require() is the module namespace object, which places
the default export in the .default property, similar to the results returned by import().
To customize what should be returned by require(esm) directly, the ES Module can export the
desired value using the string name "module.exports".
// point.mjs
export default class Point {
constructor(x,