- 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: Packages#
Introduction#
A package is a folder tree described by a package.json file. The package
consists of the folder containing the package.json file and all subfolders
until the next folder containing another package.json file, or a folder
named node_modules.
This page provides guidance for package authors writing package.json files
along with a reference for the package.json fields defined by Node.js.
Determining module system#
Node.js will treat the following as ES modules when passed to node as the
initial input, or when referenced by import statements within ES module code:
-
Files ending in
.mjs. -
Files ending in
.jswhen the nearest parentpackage.jsonfile contains a top-level"type"field with a value of"module". -
Strings passed in as an argument to
--eval, or piped tonodeviaSTDIN, with the flag--input-type=module.
Node.js will treat as CommonJS all other forms of input, such as .js files
where the nearest parent package.json file contains no top-level "type"
field, or string input without the flag --input-type. This behavior is to
preserve backward compatibility. However, now that Node.js supports both
CommonJS and ES modules, it is best to be explicit whenever possible. Node.js
will treat the following as CommonJS when passed to node as the initial input,
or when referenced by import statements within ES module code:
-
Files ending in
.cjs. -
Files ending in
.jswhen the nearest parentpackage.jsonfile contains a top-level field"type"with a value of"commonjs". -
Strings passed in as an argument to
--evalor--print, or piped tonodeviaSTDIN, with the flag--input-type=commonjs.
Package authors should include the "type" field, even in packages where
all sources are CommonJS. Being explicit about the type of the package will
future-proof the package in case the default type of Node.js ever changes, and
it will also make things easier for build tools and loaders to determine how the
files in the package should be interpreted.
package.json and file extensions#
Within a package, the package.json "type" field defines how
Node.js should interpret .js files. If a package.json file does not have a
"type" field, .js files are treated as CommonJS.
A package.json "type" value of "module" tells Node.js to interpret .js
files within that package as using ES module syntax.
The "type" field applies not only to initial entry points (node my-app.js)
but also to files referenced by import statements and import() expressions.
// my-app.js, treated as an ES module because there is a package.json
// file in the same folder with "type": "module".
import './startup/init.js';
// Loaded as ES module since ./startup contains no package.json file,
// and therefore inherits the "type" value from one level up.
import 'commonjs-package';
// Loaded as CommonJS since ./node_modules/commonjs-package/package.json
// lacks a "type" field or contains "type": "commonjs".
import './node_modules/commonjs-package/index.js';
// Loaded as CommonJS since ./node_modules/commonjs-package/package.json
// lacks a "type" field or contains "type": "commonjs".
Files ending with .mjs are always loaded as ES modules regardless of
the nearest parent package.json.
Files ending with .cjs are always loaded as CommonJS regardless of the
nearest parent package.json.
import './legacy-file.cjs';
// Loaded as CommonJS since .cjs is always loaded as CommonJS.
import 'commonjs-package/src/index.mjs';
// Loaded as ES module since .mjs is always loaded as ES module.
The .mjs and .cjs extensions can be used to mix types within the same
package:
-
Within a
"type": "module"package, Node.js can be instructed to interpret a particular file as CommonJS by naming it with a.cjsextension (since both.jsand.mjsfiles are treated as ES modules within a"module"package). -
Within a
"type": "commonjs"package, Node.js can be instructed to interpret a particular file as an ES module by naming it with an.mjsextension (since both.jsand.cjsfiles are treated as CommonJS within a"commonjs"package).
--input-type flag#
Strings passed in as an argument to --eval (or -e), or piped to node via
STDIN, are treated as ES modules when the --input-type=module flag
is set.
node --input-type=module --eval "import { sep } from 'path'; console.log(sep);"
echo "import { sep } from 'path'; console.log(sep);" | node --input-type=module
For completeness there is also --input-type=commonjs, for explicitly running
string input as CommonJS. This is the default behavior if --input-type is
unspecified.
Determining package manager#
While all Node.js projects are expected to be installable by all package managers once published, their development teams are often required to use one specific package manager. To make this process easier, Node.js ships with a tool called Corepack that aims to make all package managers transparently available in your environment - provided you have Node.js installed.
By default Corepack won't enforce any specific package manager and will use
the generic "Last Known Good" versions associated with each Node.js release,
but you can improve this experience by setting the "packageManager" field
in your project's package.json.
Package entry points#
In a package’s package.json file, two fields can define entry points for a
package: "main" and "exports". The "main" field is supported
in all versions of Node.js, but its capabilities are limited: it only defines
the main entry point of the package.
The "exports" field provides an alternative to