- Assertion testing
- Async hooks
- Buffer
- C++ addons
- C/C++ addons with Node-API
- C++ embedder API
- Child processes
- Cluster
- Command-line options
- Console
- Corepack
- Crypto
- Debugger
- Deprecated APIs
- Diagnostics Channel
- DNS
- Domain
- Errors
- Events
- File system
- Globals
- HTTP
- HTTP/2
- HTTPS
- Inspector
- Internationalization
- Modules: CommonJS modules
- Modules: ECMAScript modules
- Modules:
moduleAPI - Modules: Packages
- Net
- OS
- Path
- Performance hooks
- Policies
- Process
- Punycode
- Query strings
- Readline
- REPL
- Report
- Stream
- String decoder
- Timers
- TLS/SSL
- Trace events
- TTY
- UDP/datagram
- URL
- Utilities
- V8
- VM
- WASI
- Worker threads
- Zlib
Node.js v14.21.3 documentation
Table of contents
Modules: ECMAScript modules#
Introduction#
ECMAScript modules are the official standard format to package JavaScript
code for reuse. Modules are defined using a variety of import and
export statements.
The following example of an ES module exports a function:
// addTwo.mjs
function addTwo(num) {
return num + 2;
}
export { addTwo };
The following example of an ES module imports the function from addTwo.mjs:
// app.mjs
import { addTwo } from './addTwo.mjs';
// Prints: 6
console.log(addTwo(4));
Node.js fully supports ECMAScript modules as they are currently specified and provides interoperability between them and its original module format, CommonJS.
Enabling#
Node.js treats JavaScript code as CommonJS modules by default.
Authors can tell Node.js to treat JavaScript code as ECMAScript modules
via the .mjs file extension, the package.json "type" field, or the
--input-type flag. See
Modules: Packages for more
details.
Packages#
This section was moved to Modules: Packages.
import Specifiers#
Terminology#
The specifier of an import statement is the string after the from keyword,
e.g. 'path' in import { sep } from 'path'. Specifiers are also used in
export from statements, and as the argument to an import() expression.
There are three types of specifiers:
-
Relative specifiers like
'./startup.js'or'../config.mjs'. They refer to a path relative to the location of the importing file. The file extension is always necessary for these. -
Bare specifiers like
'some-package'or'some-package/shuffle'. They can refer to the main entry point of a package by the package name, or a specific feature module within a package prefixed by the package name as per the examples respectively. Including the file extension is only necessary for packages without an"exports"field. -
Absolute specifiers like
'file:///opt/nodejs/config.js'. They refer directly and explicitly to a full path.
Bare specifier resolutions are handled by the Node.js module resolution algorithm. All other specifier resolutions are always only resolved with the standard relative URL resolution semantics.
Like in CommonJS, module files within packages can be accessed by appending a
path to the package name unless the package’s package.json contains an
"exports" field, in which case files within packages can only be accessed
via the paths defined in "exports".
For details on these package resolution rules that apply to bare specifiers in the Node.js module resolution, see the packages documentation.
Mandatory file extensions#
A file extension must be provided when using the import keyword to resolve
relative or absolute specifiers. Directory indexes (e.g. './startup/index.js')
must also be fully specified.
This behavior matches how import behaves in browser environments, assuming a
typically configured server.
URLs#
ES modules are resolved and cached as URLs. This means that files containing
special characters such as # and ? need to be escaped.
file:, node:, and data: URL schemes are supported. A specifier like
'https://example.com/app.js' is not supported natively in Node.js unless using
a custom HTTPS loader.
file: URLs#
Modules are loaded multiple times if the import specifier used to resolve
them has a different query or fragment.
import './foo.mjs?query=1'; // loads ./foo.mjs with query of "?query=1"
import './foo.mjs?query=2'; // loads ./foo.mjs with query of "?query=2"
The volume root may be referenced via /, // or file:///. Given the
differences between URL and path resolution (such as percent encoding
details), it is recommended to use url.pathToFileURL when importing a path.
data: Imports#
data: URLs are supported for importing with the following MIME types:
text/javascriptfor ES Modulesapplication/jsonfor JSON (requires--experimental-json-modulesflag)application/wasmfor Wasm (requires--experimental-wasm-modulesflag)
data: URLs only resolve Bare specifiers for builtin modules
and Absolute specifiers. Resolving
Relative specifiers does not work because data: is not a
special scheme. For example, attempting to load ./foo
from data:text/javascript,import "./foo"; fails to resolve because there
is no concept of relative resolution for data: URLs. An example of a data:
URLs being used is:
import 'data:text/javascript,console.log("hello!");';
import _ from 'data:application/json,"world!"';
node: Imports#
node: URLs are supported as an alternative means to load Node.js builtin
modules. This URL scheme allows for builtin modules to be referenced by valid
absolute URL strings.
import fs from 'node:fs/promises';
Builtin modules#
Core modules provide named exports of their public API. A
default export is also provided which is the value of the CommonJS exports.
The default export can be used for, among other things, modifying the named
exports. Named exports of builtin modules are updated only by calling
module.syncBuiltinESMExports().
import EventEmitter from 'events';
const e = new EventEmitter();
import { readFile } from 'fs';
readFile('./foo.txt', (err, source) => {
if (err) {
console.error(err);
} else {
console.log(source);
}
});
import fs, { readFileSync } from 'fs';
import { syncBuiltinESMExports } from 'module';
fs.readFileSync = () => Buffer.from('Hello, ESM');
syncBuiltinESMExports();
fs.readFileSync === readFileSync;
import() expressions#
Dynamic import() is supported in both CommonJS and ES modules. In CommonJS
modules it can be used to load ES modules.
import.meta#
The import.meta meta property is an Object that contains the following
properties.