{"$schema":"https://doc-kit.nodejs.org/schemas/api-doc/1.0.0.json","id":"packages","path":"/packages","type":"misc","module":null,"title":"Modules: Packages","introducedIn":"v12.20.0","sourceLink":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[{"versions":["v14.13.0","v12.20.0"],"prUrl":"https://github.com/nodejs/node/pull/34718","commit":null,"description":"Add support for `\"exports\"` patterns."},{"versions":["v14.6.0","v12.19.0"],"prUrl":"https://github.com/nodejs/node/pull/34117","commit":null,"description":"Add package `\"imports\"` field."},{"versions":["v13.7.0","v12.17.0"],"prUrl":"https://github.com/nodejs/node/pull/29866","commit":null,"description":"Unflag conditional exports."},{"versions":["v13.7.0","v12.16.0"],"prUrl":"https://github.com/nodejs/node/pull/31001","commit":null,"description":"Remove the `--experimental-conditional-exports` option. In 12.16.0, conditional exports are still behind `--experimental-modules`."},{"versions":["v13.6.0","v12.16.0"],"prUrl":"https://github.com/nodejs/node/pull/31002","commit":null,"description":"Unflag self-referencing a package using its name."},{"versions":["v12.7.0"],"prUrl":"https://github.com/nodejs/node/pull/28568","commit":null,"description":"Introduce `\"exports\"` `package.json` field as a more powerful alternative to the classic `\"main\"` field."},{"versions":["v12.0.0"],"prUrl":"https://github.com/nodejs/node/pull/26745","commit":null,"description":"Add support for ES modules using `.js` file extension via `package.json` `\"type\"` field."}],"description":"","summary":"","examples":[],"children":[{"kind":"section","id":"introduction","name":"Introduction","title":"Introduction","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"A package is a folder tree described by a `package.json` file. The package\nconsists of the folder containing the `package.json` file and all subfolders\nuntil the next folder containing another `package.json` file, or a folder\nnamed `node_modules`.\n\nThis page provides guidance for package authors writing `package.json` files\nalong with a reference for the [`package.json`](#nodejs-packagejson-field-definitions) fields defined by Node.js.","summary":"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`.","examples":[],"children":[]},{"kind":"section","id":"determining-module-system","name":"Determining module system","title":"Determining module system","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"","summary":"","examples":[],"children":[{"kind":"section","id":"introduction-1","name":"Introduction","title":"Introduction","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"Node.js will treat the following as [ES modules](esm.html) when passed to `node` as the\ninitial input, or when referenced by `import` statements or `import()`\nexpressions:\n\n* Files with an `.mjs` extension.\n\n* Files with a `.js` extension when the nearest parent `package.json` file\n  contains a top-level [`\"type\"`](#type) field with a value of `\"module\"`.\n\n* Strings passed in as an argument to `--eval`, or piped to `node` via `STDIN`,\n  with the flag `--input-type=module`.\n\n* Code containing syntax only successfully parsed as [ES modules](esm.html), such as\n  `import` or `export` statements or `import.meta`, with no explicit marker of\n  how it should be interpreted. Explicit markers are `.mjs` or `.cjs`\n  extensions, `package.json` `\"type\"` fields with either `\"module\"` or\n  `\"commonjs\"` values, or the `--input-type` flag. Dynamic `import()`\n  expressions are supported in either CommonJS or ES modules and would not force\n  a file to be treated as an ES module. See [Syntax detection](#syntax-detection).\n\nNode.js will treat the following as [CommonJS](modules.html) when passed to `node` as the\ninitial input, or when referenced by `import` statements or `import()`\nexpressions:\n\n* Files with a `.cjs` extension.\n\n* Files with a `.js` extension when the nearest parent `package.json` file\n  contains a top-level field [`\"type\"`](#type) with a value of `\"commonjs\"`.\n\n* Strings passed in as an argument to `--eval` or `--print`, or piped to `node`\n  via `STDIN`, with the flag `--input-type=commonjs`.\n\n* Files with a `.js` extension with no parent `package.json` file or where the\n  nearest parent `package.json` file lacks a `type` field, and where the code\n  can evaluate successfully as CommonJS. In other words, Node.js tries to run\n  such \"ambiguous\" files as CommonJS first, and will retry evaluating them as ES\n  modules if the evaluation as CommonJS fails because the parser found ES module\n  syntax.\n\nWriting ES module syntax in \"ambiguous\" files incurs a performance cost, and\ntherefore it is encouraged that authors be explicit wherever possible. In\nparticular, package authors should always include the [`\"type\"`](#type) field in\ntheir `package.json` files, even in packages where all sources are CommonJS.\nBeing explicit about the `type` of the package will future-proof the package in\ncase the default type of Node.js ever changes, and it will also make things\neasier for build tools and loaders to determine how the files in the package\nshould be interpreted.","summary":"Node.js will treat the following as ES modules when passed to `node` as the initial input, or when referenced by `import` statements or `import()` expressions:","examples":[],"children":[]},{"kind":"section","id":"syntax-detection","name":"Syntax detection","title":"Syntax detection","scope":"module","overloadOf":null,"stability":{"index":"1.2","description":"Release candidate"},"added":["v21.1.0","v20.10.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[{"versions":["v22.7.0","v20.19.0"],"prUrl":"https://github.com/nodejs/node/pull/53619","commit":null,"description":"Syntax detection is enabled by default."}],"description":"Node.js will inspect the source code of ambiguous input to determine whether it\ncontains ES module syntax; if such syntax is detected, the input will be treated\nas an ES module.\n\nAmbiguous input is defined as:\n\n* Files with a `.js` extension or no extension; and either no controlling\n  `package.json` file or one that lacks a `type` field.\n* String input (`--eval` or `STDIN`) when `--input-type`is not specified.\n\nES module syntax is defined as syntax that would throw when evaluated as\nCommonJS. This includes the following:\n\n* `import` statements (but *not* `import()` expressions, which are valid in\n  CommonJS).\n* `export` statements.\n* `import.meta` references.\n* `await` at the top level of a module.\n* Lexical redeclarations of the CommonJS wrapper variables (`require`, `module`,\n  `exports`, `__dirname`, `__filename`).","summary":"Node.js will inspect the source code of ambiguous input to determine whether it contains ES module syntax; if such syntax is detected, the input will be treated as an ES module.","examples":[],"children":[]},{"kind":"section","id":"module-resolution-and-loading","name":"Module resolution and loading","title":"Module resolution and loading","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"Node.js has two types of module resolution and loading, chosen based on how the module is requested.\n\nWhen a module is requested via `require()` (available by default in CommonJS modules,\nand can be dynamically generated using `createRequire()` in both CommonJS and ES Modules):\n\n* Resolution:\n  * The resolution initiated by `require()` supports [folders as modules](modules.html#folders-as-modules).\n  * When resolving a specifier, if no exact match is found, `require()` will try to add\n    extensions (`.js`, `.json`, and finally `.node`) and then attempt to resolve\n    [folders as modules](modules.html#folders-as-modules).\n  * It does not support URLs as specifiers by default.\n* Loading:\n  * `.json` files are treated as JSON text files.\n  * `.node` files are interpreted as compiled addon modules loaded with `process.dlopen()`.\n  * `.ts`, `.mts` and `.cts` files are treated as [TypeScript](typescript.html) text files.\n  * Files with any other extension, or without extensions, are treated as JavaScript\n    text files.\n  * `require()` can only be used to [load ECMAScript modules from CommonJS modules](modules.html#loading-ecmascript-modules-using-require) if\n    the [ECMAScript module](esm.html) *and its dependencies* are synchronous\n    (i.e. they do not contain top-level `await`).\n\nWhen a module is requested via static `import` statements (only available in ES Modules)\nor `import()` expressions (available in both CommonJS and ES Modules):\n\n* Resolution:\n  * The resolution of `import`/`import()` does not support folders as modules,\n    directory indexes (e.g. `'./startup/index.js'`) must be fully specified.\n  * It does not perform extension searching. A file extension must be provided\n    when the specifier is a relative or absolute file URL.\n  * It supports `file://` and `data:` URLs as specifiers by default.\n* Loading:\n  * `.json` files are treated as JSON text files. When importing JSON modules,\n    an import type attribute is required (e.g.\n    `import json from './data.json' with { type: 'json' }`).\n  * `.node` files are interpreted as compiled addon modules loaded with\n    `process.dlopen()`, if [`--experimental-addon-modules`](cli.html#--experimental-addon-modules) is enabled.\n  * `.ts`, `.mts` and `.cts` files are treated as [TypeScript](typescript.html) text files.\n  * It accepts only `.js`, `.mjs`, and `.cjs` extensions for JavaScript text\n    files.\n  * `.wasm` files are treated as [WebAssembly modules](esm.html#wasm-modules).\n  * Any other file extensions will result in a  [`ERR_UNKNOWN_FILE_EXTENSION`](errors.html#err_unknown_file_extension) error.\n    Additional file extensions can be facilitated via [customization hooks](module.html#customization-hooks).\n  * `import`/`import()` can be used to load JavaScript [CommonJS modules](modules.html).\n    Such modules are passed through [merve](https://github.com/anonrig/merve) to try to identify named\n    exports, which are available if they can be determined through static analysis.\n\nRegardless of how a module is requested, the resolution and loading process can be customized\nusing [customization hooks](module.html#customization-hooks).","summary":"Node.js has two types of module resolution and loading, chosen based on how the module is requested.","examples":[],"children":[]},{"kind":"section","id":"packagejson-and-file-extensions","name":"package.json and file extensions","title":"`package.json` and file extensions","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"Within a package, the [`package.json`](#nodejs-packagejson-field-definitions) [`\"type\"`](#type) field defines how\nNode.js should interpret `.js` files. If a `package.json` file does not have a\n`\"type\"` field, `.js` files are treated as [CommonJS](modules.html).\n\nA `package.json` `\"type\"` value of `\"module\"` tells Node.js to interpret `.js`\nfiles within that package as using [ES module](esm.html) syntax.\n\nThe `\"type\"` field applies not only to initial entry points (`node my-app.js`)\nbut also to files referenced by `import` statements and `import()` expressions.\n\n```js\n// my-app.js, treated as an ES module because there is a package.json\n// file in the same folder with \"type\": \"module\".\n\nimport './startup/init.js';\n// Loaded as ES module since ./startup contains no package.json file,\n// and therefore inherits the \"type\" value from one level up.\n\nimport 'commonjs-package';\n// Loaded as CommonJS since ./node_modules/commonjs-package/package.json\n// lacks a \"type\" field or contains \"type\": \"commonjs\".\n\nimport './node_modules/commonjs-package/index.js';\n// Loaded as CommonJS since ./node_modules/commonjs-package/package.json\n// lacks a \"type\" field or contains \"type\": \"commonjs\".\n```\n\nFiles ending with `.mjs` are always loaded as [ES modules](esm.html) regardless of\nthe nearest parent `package.json`.\n\nFiles ending with `.cjs` are always loaded as [CommonJS](modules.html) regardless of the\nnearest parent `package.json`.\n\n```js\nimport './legacy-file.cjs';\n// Loaded as CommonJS since .cjs is always loaded as CommonJS.\n\nimport 'commonjs-package/src/index.mjs';\n// Loaded as ES module since .mjs is always loaded as ES module.\n```\n\nThe `.mjs` and `.cjs` extensions can be used to mix types within the same\npackage:\n\n* Within a `\"type\": \"module\"` package, Node.js can be instructed to\n  interpret a particular file as [CommonJS](modules.html) by naming it with a `.cjs`\n  extension (since both `.js` and `.mjs` files are treated as ES modules within\n  a `\"module\"` package).\n\n* Within a `\"type\": \"commonjs\"` package, Node.js can be instructed to\n  interpret a particular file as an [ES module](esm.html) by naming it with an `.mjs`\n  extension (since both `.js` and `.cjs` files are treated as CommonJS within a\n  `\"commonjs\"` package).","summary":"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.","examples":[{"language":"js","displayName":null,"code":"// my-app.js, treated as an ES module because there is a package.json\n// file in the same folder with \"type\": \"module\".\n\nimport './startup/init.js';\n// Loaded as ES module since ./startup contains no package.json file,\n// and therefore inherits the \"type\" value from one level up.\n\nimport 'commonjs-package';\n// Loaded as CommonJS since ./node_modules/commonjs-package/package.json\n// lacks a \"type\" field or contains \"type\": \"commonjs\".\n\nimport './node_modules/commonjs-package/index.js';\n// Loaded as CommonJS since ./node_modules/commonjs-package/package.json\n// lacks a \"type\" field or contains \"type\": \"commonjs\"."},{"language":"js","displayName":null,"code":"import './legacy-file.cjs';\n// Loaded as CommonJS since .cjs is always loaded as CommonJS.\n\nimport 'commonjs-package/src/index.mjs';\n// Loaded as ES module since .mjs is always loaded as ES module."}],"children":[]},{"kind":"section","id":"--input-type-flag","name":"--input-type flag","title":"`--input-type` flag","scope":"module","overloadOf":null,"stability":null,"added":["v12.0.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"Strings passed in as an argument to `--eval` (or `-e`), or piped to `node` via\n`STDIN`, are treated as [ES modules](esm.html) when the `--input-type=module` flag\nis set.\n\n```bash\nnode --input-type=module --eval \"import { sep } from 'node:path'; console.log(sep);\"\n\necho \"import { sep } from 'node:path'; console.log(sep);\" | node --input-type=module\n```\n\nFor completeness there is also `--input-type=commonjs`, for explicitly running\nstring input as CommonJS. This is the default behavior if `--input-type` is\nunspecified.","summary":"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.","examples":[{"language":"bash","displayName":null,"code":"node --input-type=module --eval \"import { sep } from 'node:path'; console.log(sep);\"\n\necho \"import { sep } from 'node:path'; console.log(sep);\" | node --input-type=module"}],"children":[]}]},{"kind":"section","id":"package-entry-points","name":"Package entry points","title":"Package entry points","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"In a package's `package.json` file, two fields can define entry points for a\npackage: [`\"main\"`](#main) and [`\"exports\"`](#exports). Both fields apply to both ES module\nand CommonJS module entry points.\n\nThe [`\"main\"`](#main) field is supported in all versions of Node.js, but its\ncapabilities are limited: it only defines the main entry point of the package.\n\nThe [`\"exports\"`](#exports) provides a modern alternative to [`\"main\"`](#main) allowing\nmultiple entry points to be defined, conditional entry resolution support\nbetween environments, and **preventing any other entry points besides those\ndefined in [`\"exports\"`](#exports)**. This encapsulation allows module authors to\nclearly define the public interface for their package.\n\nFor new packages targeting the currently supported versions of Node.js, the\n[`\"exports\"`](#exports) field is recommended. For packages supporting Node.js 10 and\nbelow, the [`\"main\"`](#main) field is required. If both [`\"exports\"`](#exports) and\n[`\"main\"`](#main) are defined, the [`\"exports\"`](#exports) field takes precedence over\n[`\"main\"`](#main) in supported versions of Node.js.\n\n[Conditional exports](#conditional-exports) can be used within [`\"exports\"`](#exports) to define different\npackage entry points per environment, including whether the package is\nreferenced via `require` or via `import`. For more information about supporting\nboth CommonJS and ES modules in a single package please consult\n[the dual CommonJS/ES module packages section](#dual-commonjses-module-packages).\n\nExisting packages introducing the [`\"exports\"`](#exports) field will prevent consumers\nof the package from using any entry points that are not defined, including the\n[`package.json`](#nodejs-packagejson-field-definitions) (e.g. `require('your-package/package.json')`). **This will\nlikely be a breaking change.**\n\nTo make the introduction of [`\"exports\"`](#exports) non-breaking, ensure that every\npreviously supported entry point is exported. It is best to explicitly specify\nentry points so that the package's public API is well-defined. For example,\na project that previously exported `main`, `lib`,\n`feature`, and the `package.json` could use the following `package.exports`:\n\n```json\n{\n  \"name\": \"my-package\",\n  \"exports\": {\n    \".\": \"./lib/index.js\",\n    \"./lib\": \"./lib/index.js\",\n    \"./lib/index\": \"./lib/index.js\",\n    \"./lib/index.js\": \"./lib/index.js\",\n    \"./feature\": \"./feature/index.js\",\n    \"./feature/index\": \"./feature/index.js\",\n    \"./feature/index.js\": \"./feature/index.js\",\n    \"./package.json\": \"./package.json\"\n  }\n}\n```\n\nAlternatively a project could choose to export entire folders both with and\nwithout extensioned subpaths using export patterns:\n\n```json\n{\n  \"name\": \"my-package\",\n  \"exports\": {\n    \".\": \"./lib/index.js\",\n    \"./lib\": \"./lib/index.js\",\n    \"./lib/*\": \"./lib/*.js\",\n    \"./lib/*.js\": \"./lib/*.js\",\n    \"./feature\": \"./feature/index.js\",\n    \"./feature/*\": \"./feature/*.js\",\n    \"./feature/*.js\": \"./feature/*.js\",\n    \"./package.json\": \"./package.json\"\n  }\n}\n```\n\nWith the above providing backwards-compatibility for any minor package versions,\na future major change for the package can then properly restrict the exports\nto only the specific feature exports exposed:\n\n```json\n{\n  \"name\": \"my-package\",\n  \"exports\": {\n    \".\": \"./lib/index.js\",\n    \"./feature/*.js\": \"./feature/*.js\",\n    \"./feature/internal/*\": null\n  }\n}\n```","summary":"In a package's `package.json` file, two fields can define entry points for a package: `\"main\"` and `\"exports\"`. Both fields apply to both ES module and CommonJS module entry points.","examples":[{"language":"json","displayName":null,"code":"{\n  \"name\": \"my-package\",\n  \"exports\": {\n    \".\": \"./lib/index.js\",\n    \"./lib\": \"./lib/index.js\",\n    \"./lib/index\": \"./lib/index.js\",\n    \"./lib/index.js\": \"./lib/index.js\",\n    \"./feature\": \"./feature/index.js\",\n    \"./feature/index\": \"./feature/index.js\",\n    \"./feature/index.js\": \"./feature/index.js\",\n    \"./package.json\": \"./package.json\"\n  }\n}"},{"language":"json","displayName":null,"code":"{\n  \"name\": \"my-package\",\n  \"exports\": {\n    \".\": \"./lib/index.js\",\n    \"./lib\": \"./lib/index.js\",\n    \"./lib/*\": \"./lib/*.js\",\n    \"./lib/*.js\": \"./lib/*.js\",\n    \"./feature\": \"./feature/index.js\",\n    \"./feature/*\": \"./feature/*.js\",\n    \"./feature/*.js\": \"./feature/*.js\",\n    \"./package.json\": \"./package.json\"\n  }\n}"},{"language":"json","displayName":null,"code":"{\n  \"name\": \"my-package\",\n  \"exports\": {\n    \".\": \"./lib/index.js\",\n    \"./feature/*.js\": \"./feature/*.js\",\n    \"./feature/internal/*\": null\n  }\n}"}],"children":[{"kind":"section","id":"main-entry-point-export","name":"Main entry point export","title":"Main entry point export","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"When writing a new package, it is recommended to use the [`\"exports\"`](#exports) field:\n\n```json\n{\n  \"exports\": \"./index.js\"\n}\n```\n\nWhen the [`\"exports\"`](#exports) field is defined, all subpaths of the package are\nencapsulated and no longer available to importers. For example,\n`require('pkg/subpath.js')` throws an [`ERR_PACKAGE_PATH_NOT_EXPORTED`](errors.html#err_package_path_not_exported)\nerror.\n\nThis encapsulation of exports provides more reliable guarantees\nabout package interfaces for tools and when handling semver upgrades for a\npackage. It is not a strong encapsulation since a direct require of any\nabsolute subpath of the package such as\n`require('/path/to/node_modules/pkg/subpath.js')` will still load `subpath.js`.\n\nAll currently supported versions of Node.js and modern build tools support the\n`\"exports\"` field. For projects using an older version of Node.js or a related\nbuild tool, compatibility can be achieved by including the `\"main\"` field\nalongside `\"exports\"` pointing to the same module:\n\n```json\n{\n  \"main\": \"./index.js\",\n  \"exports\": \"./index.js\"\n}\n```","summary":"When writing a new package, it is recommended to use the `\"exports\"` field:","examples":[{"language":"json","displayName":null,"code":"{\n  \"exports\": \"./index.js\"\n}"},{"language":"json","displayName":null,"code":"{\n  \"main\": \"./index.js\",\n  \"exports\": \"./index.js\"\n}"}],"children":[]},{"kind":"section","id":"subpath-exports","name":"Subpath exports","title":"Subpath exports","scope":"module","overloadOf":null,"stability":null,"added":["v12.7.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"When using the [`\"exports\"`](#exports) field, custom subpaths can be defined along\nwith the main entry point by treating the main entry point as the\n`\".\"` subpath:\n\n```json\n{\n  \"exports\": {\n    \".\": \"./index.js\",\n    \"./submodule.js\": \"./src/submodule.js\"\n  }\n}\n```\n\nNow only the defined subpath in [`\"exports\"`](#exports) can be imported by a consumer:\n\n```js\nimport submodule from 'es-module-package/submodule.js';\n// Loads ./node_modules/es-module-package/src/submodule.js\n```\n\nWhile other subpaths will error:\n\n```js\nimport submodule from 'es-module-package/private-module.js';\n// Throws ERR_PACKAGE_PATH_NOT_EXPORTED\n```","summary":"When using the `\"exports\"` field, custom subpaths can be defined along with the main entry point by treating the main entry point as the `\".\"` subpath:","examples":[{"language":"json","displayName":null,"code":"{\n  \"exports\": {\n    \".\": \"./index.js\",\n    \"./submodule.js\": \"./src/submodule.js\"\n  }\n}"},{"language":"js","displayName":null,"code":"import submodule from 'es-module-package/submodule.js';\n// Loads ./node_modules/es-module-package/src/submodule.js"},{"language":"js","displayName":null,"code":"import submodule from 'es-module-package/private-module.js';\n// Throws ERR_PACKAGE_PATH_NOT_EXPORTED"}],"children":[{"kind":"section","id":"extensions-in-subpaths","name":"Extensions in subpaths","title":"Extensions in subpaths","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"Package authors should provide either extensioned (`import 'pkg/subpath.js'`) or\nextensionless (`import 'pkg/subpath'`) subpaths in their exports. This ensures\nthat there is only one subpath for each exported module so that all dependents\nimport the same consistent specifier, keeping the package contract clear for\nconsumers and simplifying package subpath completions.\n\nTraditionally, packages tended to use the extensionless style, which has the\nbenefits of readability and of masking the true path of the file within the\npackage.\n\nWith [import maps](https://github.com/WICG/import-maps) now providing a standard for package resolution in browsers\nand other JavaScript runtimes, using the extensionless style can result in\nbloated import map definitions. Explicit file extensions can avoid this issue by\nenabling the import map to utilize a [packages folder mapping](https://github.com/WICG/import-maps#packages-via-trailing-slashes) to map multiple\nsubpaths where possible instead of a separate map entry per package subpath\nexport. This also mirrors the requirement of using [the full specifier path](esm.html#mandatory-file-extensions)\nin relative and absolute import specifiers.","summary":"Package authors should provide either extensioned (`import 'pkg/subpath.js'`) or extensionless (`import 'pkg/subpath'`) subpaths in their exports. This ensures that there is only one subpath for each exported module so that all dependents import the same consistent specifier, keeping the package contract clear for consumers and simplifying package subpath completions.","examples":[],"children":[]},{"kind":"section","id":"path-rules-and-validation-for-export-targets","name":"Path Rules and Validation for Export Targets","title":"Path Rules and Validation for Export Targets","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"When defining paths as targets in the [`\"exports\"`](#exports) field, Node.js enforces\nseveral rules to ensure security, predictability, and proper encapsulation.\nUnderstanding these rules is crucial for authors publishing packages.","summary":"When defining paths as targets in the `\"exports\"` field, Node.js enforces several rules to ensure security, predictability, and proper encapsulation. Understanding these rules is crucial for authors publishing packages.","examples":[],"children":[{"kind":"section","id":"targets-must-be-relative-urls","name":"Targets must be relative URLs","title":"Targets must be relative URLs","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"All target paths in the [`\"exports\"`](#exports) map (the values associated with export\nkeys) must be relative URL strings starting with `./`.\n\n```json\n// package.json\n{\n  \"name\": \"my-package\",\n  \"exports\": {\n    \".\": \"./dist/main.js\",          // Correct\n    \"./feature\": \"./lib/feature.js\", // Correct\n    // \"./origin-relative\": \"/dist/main.js\", // Incorrect: Must start with ./\n    // \"./absolute\": \"file:///dev/null\", // Incorrect: Must start with ./\n    // \"./outside\": \"../common/util.js\" // Incorrect: Must start with ./\n  }\n}\n```\n\nReasons for this behavior include:\n\n* **Security:** Prevents exporting arbitrary files from outside the\n  package's own directory.\n* **Encapsulation:** Ensures all exported paths are resolved relative to\n  the package root, making the package self-contained.","summary":"All target paths in the `\"exports\"` map (the values associated with export keys) must be relative URL strings starting with `./`.","examples":[{"language":"json","displayName":null,"code":"// package.json\n{\n  \"name\": \"my-package\",\n  \"exports\": {\n    \".\": \"./dist/main.js\",          // Correct\n    \"./feature\": \"./lib/feature.js\", // Correct\n    // \"./origin-relative\": \"/dist/main.js\", // Incorrect: Must start with ./\n    // \"./absolute\": \"file:///dev/null\", // Incorrect: Must start with ./\n    // \"./outside\": \"../common/util.js\" // Incorrect: Must start with ./\n  }\n}"}],"children":[]},{"kind":"section","id":"no-path-traversal-or-invalid-segments","name":"No path traversal or invalid segments","title":"No path traversal or invalid segments","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"Export targets must not resolve to a location outside the package's root\ndirectory. Additionally, path segments like `.` (single dot), `..` (double dot),\nor `node_modules` (and their URL-encoded equivalents) are generally disallowed\nwithin the `target` string after the initial `./` and in any `subpath` part\nsubstituted into a target pattern.\n\n```json\n// package.json\n{\n  \"name\": \"my-package\",\n  \"exports\": {\n    // \".\": \"./dist/../../elsewhere/file.js\", // Invalid: path traversal\n    // \".\": \"././dist/main.js\",             // Invalid: contains \".\" segment\n    // \".\": \"./dist/../dist/main.js\",       // Invalid: contains \"..\" segment\n    // \"./utils/./helper.js\": \"./utils/helper.js\" // Key has invalid segment\n  }\n}\n```","summary":"Export targets must not resolve to a location outside the package's root directory. Additionally, path segments like `.` (single dot), `..` (double dot), or `node_modules` (and their URL-encoded equivalents) are generally disallowed within the `target` string after the initial `./` and in any `subpath` part substituted into a target pattern.","examples":[{"language":"json","displayName":null,"code":"// package.json\n{\n  \"name\": \"my-package\",\n  \"exports\": {\n    // \".\": \"./dist/../../elsewhere/file.js\", // Invalid: path traversal\n    // \".\": \"././dist/main.js\",             // Invalid: contains \".\" segment\n    // \".\": \"./dist/../dist/main.js\",       // Invalid: contains \"..\" segment\n    // \"./utils/./helper.js\": \"./utils/helper.js\" // Key has invalid segment\n  }\n}"}],"children":[]}]}]},{"kind":"section","id":"exports-sugar","name":"Exports sugar","title":"Exports sugar","scope":"module","overloadOf":null,"stability":null,"added":["v12.11.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"If the `\".\"` export is the only export, the [`\"exports\"`](#exports) field provides sugar\nfor this case being the direct [`\"exports\"`](#exports) field value.\n\n```json\n{\n  \"exports\": {\n    \".\": \"./index.js\"\n  }\n}\n```\n\ncan be written:\n\n```json\n{\n  \"exports\": \"./index.js\"\n}\n```","summary":"If the `\".\"` export is the only export, the `\"exports\"` field provides sugar for this case being the direct `\"exports\"` field value.","examples":[{"language":"json","displayName":null,"code":"{\n  \"exports\": {\n    \".\": \"./index.js\"\n  }\n}"},{"language":"json","displayName":null,"code":"{\n  \"exports\": \"./index.js\"\n}"}],"children":[]},{"kind":"section","id":"subpath-imports","name":"Subpath imports","title":"Subpath imports","scope":"module","overloadOf":null,"stability":null,"added":["v14.6.0","v12.19.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[{"versions":["v25.4.0","v24.14.0"],"prUrl":"https://github.com/nodejs/node/pull/60864","commit":null,"description":"Allow subpath imports that start with `#/`."}],"description":"In addition to the [`\"exports\"`](#exports) field, there is a package `\"imports\"` field\nto create private mappings that only apply to import specifiers from within the\npackage itself.\n\nEntries in the `\"imports\"` field must always start with `#` to ensure they are\ndisambiguated from external package specifiers.\n\nFor example, the imports field can be used to gain the benefits of conditional\nexports for internal modules:\n\n```json\n// package.json\n{\n  \"imports\": {\n    \"#dep\": {\n      \"node\": \"dep-node-native\",\n      \"default\": \"./dep-polyfill.js\"\n    }\n  },\n  \"dependencies\": {\n    \"dep-node-native\": \"^1.0.0\"\n  }\n}\n```\n\nwhere `import '#dep'` does not get the resolution of the external package\n`dep-node-native` (including its exports in turn), and instead gets the local\nfile `./dep-polyfill.js` relative to the package in other environments.\n\nUnlike the `\"exports\"` field, the `\"imports\"` field permits mapping to external\npackages.\n\nThe resolution rules for the imports field are otherwise analogous to the\nexports field.","summary":"In addition to the `\"exports\"` field, there is a package `\"imports\"` field to create private mappings that only apply to import specifiers from within the package itself.","examples":[{"language":"json","displayName":null,"code":"// package.json\n{\n  \"imports\": {\n    \"#dep\": {\n      \"node\": \"dep-node-native\",\n      \"default\": \"./dep-polyfill.js\"\n    }\n  },\n  \"dependencies\": {\n    \"dep-node-native\": \"^1.0.0\"\n  }\n}"}],"children":[]},{"kind":"section","id":"subpath-patterns","name":"Subpath patterns","title":"Subpath patterns","scope":"module","overloadOf":null,"stability":null,"added":["v14.13.0","v12.20.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[{"versions":["v16.10.0","v14.19.0"],"prUrl":"https://github.com/nodejs/node/pull/40041","commit":null,"description":"Support pattern trailers in \"imports\" field."},{"versions":["v16.9.0","v14.19.0"],"prUrl":"https://github.com/nodejs/node/pull/39635","commit":null,"description":"Support pattern trailers."}],"description":"For packages with a small number of exports or imports, we recommend\nexplicitly listing each exports subpath entry. But for packages that have\nlarge numbers of subpaths, this might cause `package.json` bloat and\nmaintenance issues.\n\nFor these use cases, subpath export patterns can be used instead:\n\n```json\n// ./node_modules/es-module-package/package.json\n{\n  \"exports\": {\n    \"./features/*.js\": \"./src/features/*.js\"\n  },\n  \"imports\": {\n    \"#internal/*.js\": \"./src/internal/*.js\"\n  }\n}\n```\n\n**`*` maps expose nested subpaths as it is a string replacement syntax\nonly.**\n\nAll instances of `*` on the right hand side will then be replaced with this\nvalue, including if it contains any `/` separators.\n\n```js\nimport featureX from 'es-module-package/features/x.js';\n// Loads ./node_modules/es-module-package/src/features/x.js\n\nimport featureY from 'es-module-package/features/y/y.js';\n// Loads ./node_modules/es-module-package/src/features/y/y.js\n\nimport internalZ from '#internal/z.js';\n// Loads ./src/internal/z.js\n```\n\nThis is a direct static matching and replacement without any special handling\nfor file extensions. Including the `\"*.js\"` on both sides of the mapping\nrestricts the exposed package exports to only JS files.\n\nThe property of exports being statically enumerable is maintained with exports\npatterns since the individual exports for a package can be determined by\ntreating the right hand side target pattern as a `**` glob against the list of\nfiles within the package. Because `node_modules` paths are forbidden in exports\ntargets, this expansion is dependent on only the files of the package itself.\n\nTo exclude private subfolders from patterns, `null` targets can be used:\n\n```json\n// ./node_modules/es-module-package/package.json\n{\n  \"exports\": {\n    \"./features/*.js\": \"./src/features/*.js\",\n    \"./features/private-internal/*\": null\n  }\n}\n```\n\n```js\nimport featureInternal from 'es-module-package/features/private-internal/m.js';\n// Throws: ERR_PACKAGE_PATH_NOT_EXPORTED\n\nimport featureX from 'es-module-package/features/x.js';\n// Loads ./node_modules/es-module-package/src/features/x.js\n```","summary":"For packages with a small number of exports or imports, we recommend explicitly listing each exports subpath entry. But for packages that have large numbers of subpaths, this might cause `package.json` bloat and maintenance issues.","examples":[{"language":"json","displayName":null,"code":"// ./node_modules/es-module-package/package.json\n{\n  \"exports\": {\n    \"./features/*.js\": \"./src/features/*.js\"\n  },\n  \"imports\": {\n    \"#internal/*.js\": \"./src/internal/*.js\"\n  }\n}"},{"language":"js","displayName":null,"code":"import featureX from 'es-module-package/features/x.js';\n// Loads ./node_modules/es-module-package/src/features/x.js\n\nimport featureY from 'es-module-package/features/y/y.js';\n// Loads ./node_modules/es-module-package/src/features/y/y.js\n\nimport internalZ from '#internal/z.js';\n// Loads ./src/internal/z.js"},{"language":"json","displayName":null,"code":"// ./node_modules/es-module-package/package.json\n{\n  \"exports\": {\n    \"./features/*.js\": \"./src/features/*.js\",\n    \"./features/private-internal/*\": null\n  }\n}"},{"language":"js","displayName":null,"code":"import featureInternal from 'es-module-package/features/private-internal/m.js';\n// Throws: ERR_PACKAGE_PATH_NOT_EXPORTED\n\nimport featureX from 'es-module-package/features/x.js';\n// Loads ./node_modules/es-module-package/src/features/x.js"}],"children":[]},{"kind":"section","id":"conditional-exports","name":"Conditional exports","title":"Conditional exports","scope":"module","overloadOf":null,"stability":null,"added":["v13.2.0","v12.16.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[{"versions":["v13.7.0","v12.16.0"],"prUrl":"https://github.com/nodejs/node/pull/31001","commit":null,"description":"Unflag conditional exports."}],"description":"Conditional exports provide a way to map to different paths depending on\ncertain conditions. They are supported for both CommonJS and ES module imports.\n\nFor example, a package that wants to provide different ES module exports for\n`require()` and `import` can be written:\n\n```json\n// package.json\n{\n  \"exports\": {\n    \"import\": \"./index-module.js\",\n    \"require\": \"./index-require.cjs\"\n  },\n  \"type\": \"module\"\n}\n```\n\nNode.js implements the following conditions, listed in order from most\nspecific to least specific as conditions should be defined:\n\n* `\"node-addons\"` - similar to `\"node\"` and matches for any Node.js environment.\n  This condition can be used to provide an entry point which uses native C++\n  addons as opposed to an entry point which is more universal and doesn't rely\n  on native addons. This condition can be disabled via the\n  [`--no-addons` flag](cli.html#--no-addons).\n* `\"node\"` - matches for any Node.js environment. Can be a CommonJS or ES\n  module file. *In most cases explicitly calling out the Node.js platform is\n  not necessary.*\n* `\"import\"` - matches when the package is loaded via `import` or\n  `import()`, or via any top-level import or resolve operation by the\n  ECMAScript module loader. Applies regardless of the module format of the\n  target file. *Always mutually exclusive with `\"require\"`.*\n* `\"require\"` - matches when the package is loaded via `require()`. The\n  referenced file should be loadable with `require()` although the condition\n  matches regardless of the module format of the target file. Expected\n  formats include CommonJS, JSON, native addons, and ES modules. *Always mutually\n  exclusive with `\"import\"`.*\n* `\"module-sync\"` - matches no matter the package is loaded via `import`,\n  `import()` or `require()`. The format is expected to be ES modules that does\n  not contain top-level await in its module graph - if it does,\n  `ERR_REQUIRE_ASYNC_MODULE` will be thrown when the module is `require()`-ed.\n* `\"default\"` - the generic fallback that always matches. Can be a CommonJS\n  or ES module file. *This condition should always come last.*\n\nWithin the [`\"exports\"`](#exports) object, key order is significant. During condition\nmatching, earlier entries have higher priority and take precedence over later\nentries. *The general rule is that conditions should be from most specific to\nleast specific in object order*.\n\nUsing the `\"import\"` and `\"require\"` conditions can lead to some hazards,\nwhich are further explained in [the dual CommonJS/ES module packages section](#dual-commonjses-module-packages).\n\nThe `\"node-addons\"` condition can be used to provide an entry point which\nuses native C++ addons. However, this condition can be disabled via the\n[`--no-addons` flag](cli.html#--no-addons). When using `\"node-addons\"`, it's recommended to treat\n`\"default\"` as an enhancement that provides a more universal entry point, e.g.\nusing WebAssembly instead of a native addon.\n\nConditional exports can also be extended to exports subpaths, for example:\n\n```json\n{\n  \"exports\": {\n    \".\": \"./index.js\",\n    \"./feature.js\": {\n      \"node\": \"./feature-node.js\",\n      \"default\": \"./feature.js\"\n    }\n  }\n}\n```\n\nDefines a package where `require('pkg/feature.js')` and\n`import 'pkg/feature.js'` could provide different implementations between\nNode.js and other JS environments.\n\nWhen using environment branches, always include a `\"default\"` condition where\npossible. Providing a `\"default\"` condition ensures that any unknown JS\nenvironments are able to use this universal implementation, which helps avoid\nthese JS environments from having to pretend to be existing environments in\norder to support packages with conditional exports. For this reason, using\n`\"node\"` and `\"default\"` condition branches is usually preferable to using\n`\"node\"` and `\"browser\"` condition branches.","summary":"Conditional exports provide a way to map to different paths depending on certain conditions. They are supported for both CommonJS and ES module imports.","examples":[{"language":"json","displayName":null,"code":"// package.json\n{\n  \"exports\": {\n    \"import\": \"./index-module.js\",\n    \"require\": \"./index-require.cjs\"\n  },\n  \"type\": \"module\"\n}"},{"language":"json","displayName":null,"code":"{\n  \"exports\": {\n    \".\": \"./index.js\",\n    \"./feature.js\": {\n      \"node\": \"./feature-node.js\",\n      \"default\": \"./feature.js\"\n    }\n  }\n}"}],"children":[]},{"kind":"section","id":"nested-conditions","name":"Nested conditions","title":"Nested conditions","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"In addition to direct mappings, Node.js also supports nested condition objects.\n\nFor example, to define a package that only has dual mode entry points for\nuse in Node.js but not the browser:\n\n```json\n{\n  \"exports\": {\n    \"node\": {\n      \"import\": \"./feature-node.mjs\",\n      \"require\": \"./feature-node.cjs\"\n    },\n    \"default\": \"./feature.mjs\"\n  }\n}\n```\n\nConditions continue to be matched in order as with flat conditions. If\na nested condition does not have any mapping it will continue checking\nthe remaining conditions of the parent condition. In this way nested\nconditions behave analogously to nested JavaScript `if` statements.","summary":"In addition to direct mappings, Node.js also supports nested condition objects.","examples":[{"language":"json","displayName":null,"code":"{\n  \"exports\": {\n    \"node\": {\n      \"import\": \"./feature-node.mjs\",\n      \"require\": \"./feature-node.cjs\"\n    },\n    \"default\": \"./feature.mjs\"\n  }\n}"}],"children":[]},{"kind":"section","id":"resolving-user-conditions","name":"Resolving user conditions","title":"Resolving user conditions","scope":"module","overloadOf":null,"stability":null,"added":["v14.9.0","v12.19.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"When running Node.js, custom user conditions can be added with the\n`--conditions` flag:\n\n```bash\nnode --conditions=development index.js\n```\n\nwhich would then resolve the `\"development\"` condition in package imports and\nexports, while resolving the existing `\"node\"`, `\"node-addons\"`, `\"default\"`,\n`\"import\"`, and `\"require\"` conditions as appropriate.\n\nAny number of custom conditions can be set with repeat flags.\n\nTypical conditions should only contain alphanumerical characters,\nusing \":\", \"-\", or \"=\" as separators if necessary. Anything else may run\ninto compatibility issues outside of node.\n\nIn node, conditions have very few restrictions, but specifically these include:\n\n1. They must contain at least one character.\n2. They cannot start with \".\" since they may appear in places that also\n   allow relative paths.\n3. They cannot contain \",\" since they may be parsed as a comma-separated\n   list by some CLI tools.\n4. They cannot be integer property keys like \"10\" since that can have\n   unexpected effects on property key ordering for JS objects.","summary":"When running Node.js, custom user conditions can be added with the `--conditions` flag:","examples":[{"language":"bash","displayName":null,"code":"node --conditions=development index.js"}],"children":[]},{"kind":"section","id":"community-conditions-definitions","name":"Community Conditions Definitions","title":"Community Conditions Definitions","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"Condition strings other than the `\"import\"`, `\"require\"`, `\"node\"`, `\"module-sync\"`,\n`\"node-addons\"` and `\"default\"` conditions\n[implemented in Node.js core](#conditional-exports) are ignored by default.\n\nOther platforms may implement other conditions and user conditions can be\nenabled in Node.js via the [`--conditions` / `-C` flag](#resolving-user-conditions).\n\nSince custom package conditions require clear definitions to ensure correct\nusage, a list of common known package conditions and their strict definitions\nis provided below to assist with ecosystem coordination.\n\n* `\"types\"` - can be used by typing systems to resolve the typing file for\n  the given export. *This condition should always be included first.*\n* `\"browser\"` - any web browser environment.\n* `\"development\"` - can be used to define a development-only environment\n  entry point, for example to provide additional debugging context such as\n  better error messages when running in a development mode. *Must always be\n  mutually exclusive with `\"production\"`.*\n* `\"production\"` - can be used to define a production environment entry\n  point. *Must always be mutually exclusive with `\"development\"`.*\n\nFor other runtimes, platform-specific condition key definitions are maintained\nby the [WinterCG](https://wintercg.org/) in the [Runtime Keys](https://runtime-keys.proposal.wintercg.org/) proposal specification.\n\nNew conditions definitions may be added to this list by creating a pull request\nto the [Node.js documentation for this section](https://github.com/nodejs/node/blob/HEAD/doc/api/packages.md#conditions-definitions). The requirements for listing\na new condition definition here are that:\n\n* The definition should be clear and unambiguous for all implementers.\n* The use case for why the condition is needed should be clearly justified.\n* There should exist sufficient existing implementation usage.\n* The condition name should not conflict with another condition definition or\n  condition in wide usage.\n* The listing of the condition definition should provide a coordination\n  benefit to the ecosystem that wouldn't otherwise be possible. For example,\n  this would not necessarily be the case for company-specific or\n  application-specific conditions.\n* The condition should be such that a Node.js user would expect it to be in\n  Node.js core documentation. The `\"types\"` condition is a good example: It\n  doesn't really belong in the [Runtime Keys](https://runtime-keys.proposal.wintercg.org/) proposal but is a good fit\n  here in the Node.js docs.\n\nThe above definitions may be moved to a dedicated conditions registry in due\ncourse.","summary":"Condition strings other than the `\"import\"`, `\"require\"`, `\"node\"`, `\"module-sync\"`, `\"node-addons\"` and `\"default\"` conditions implemented in Node.js core are ignored by default.","examples":[],"children":[]},{"kind":"section","id":"self-referencing-a-package-using-its-name","name":"Self-referencing a package using its name","title":"Self-referencing a package using its name","scope":"module","overloadOf":null,"stability":null,"added":["v13.1.0","v12.16.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[{"versions":["v13.6.0","v12.16.0"],"prUrl":"https://github.com/nodejs/node/pull/31002","commit":null,"description":"Unflag self-referencing a package using its name."}],"description":"Within a package, the values defined in the package's\n`package.json` [`\"exports\"`](#exports) field can be referenced via the package's name.\nFor example, assuming the `package.json` is:\n\n```json\n// package.json\n{\n  \"name\": \"a-package\",\n  \"exports\": {\n    \".\": \"./index.mjs\",\n    \"./foo.js\": \"./foo.js\"\n  }\n}\n```\n\nThen any module *in that package* can reference an export in the package itself:\n\n```js\n// ./a-module.mjs\nimport { something } from 'a-package'; // Imports \"something\" from ./index.mjs.\n```\n\nSelf-referencing is available only if `package.json` has [`\"exports\"`](#exports), and\nwill allow importing only what that [`\"exports\"`](#exports) (in the `package.json`)\nallows. So the code below, given the previous package, will generate a runtime\nerror:\n\n```js\n// ./another-module.mjs\n\n// Imports \"another\" from ./m.mjs. Fails because\n// the \"package.json\" \"exports\" field\n// does not provide an export named \"./m.mjs\".\nimport { another } from 'a-package/m.mjs';\n```\n\nSelf-referencing is also available when using `require`, both in an ES module,\nand in a CommonJS one. For example, this code will also work:\n\n```cjs\n// ./a-module.js\nconst { something } = require('a-package/foo.js'); // Loads from ./foo.js.\n```\n\nFinally, self-referencing also works with scoped packages. For example, this\ncode will also work:\n\n```json\n// package.json\n{\n  \"name\": \"@my/package\",\n  \"exports\": \"./index.js\"\n}\n```\n\n```cjs\n// ./index.js\nmodule.exports = 42;\n```\n\n```cjs\n// ./other.js\nconsole.log(require('@my/package'));\n```\n\n```console\n$ node other.js\n42\n```","summary":"Within a package, the values defined in the package's `package.json` `\"exports\"` field can be referenced via the package's name. For example, assuming the `package.json` is:","examples":[{"language":"json","displayName":null,"code":"// package.json\n{\n  \"name\": \"a-package\",\n  \"exports\": {\n    \".\": \"./index.mjs\",\n    \"./foo.js\": \"./foo.js\"\n  }\n}"},{"language":"js","displayName":null,"code":"// ./a-module.mjs\nimport { something } from 'a-package'; // Imports \"something\" from ./index.mjs."},{"language":"js","displayName":null,"code":"// ./another-module.mjs\n\n// Imports \"another\" from ./m.mjs. Fails because\n// the \"package.json\" \"exports\" field\n// does not provide an export named \"./m.mjs\".\nimport { another } from 'a-package/m.mjs';"},{"language":"cjs","displayName":null,"code":"// ./a-module.js\nconst { something } = require('a-package/foo.js'); // Loads from ./foo.js."},{"language":"json","displayName":null,"code":"// package.json\n{\n  \"name\": \"@my/package\",\n  \"exports\": \"./index.js\"\n}"},{"language":"cjs","displayName":null,"code":"// ./index.js\nmodule.exports = 42;"},{"language":"cjs","displayName":null,"code":"// ./other.js\nconsole.log(require('@my/package'));"},{"language":"console","displayName":null,"code":"$ node other.js\n42"}],"children":[]}]},{"kind":"section","id":"dual-commonjses-module-packages","name":"Dual CommonJS/ES module packages","title":"Dual CommonJS/ES module packages","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"See [the package examples repository](https://github.com/nodejs/package-examples) for details.","summary":"See the package examples repository for details.","examples":[],"children":[]},{"kind":"section","id":"package-maps","name":"Package maps","title":"Package maps","scope":"module","overloadOf":null,"stability":{"index":"1","description":"Experimental. Enable this API with [`--experimental-package-map`](cli.html#--experimental-package-mappath)."},"added":["v26.4.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"Package maps provide a mechanism to control package resolution without relying\non the `node_modules` folder structure. When enabled via the\n[`--experimental-package-map`](cli.html#--experimental-package-mappath) flag, Node.js uses a JSON configuration file\nto determine how bare specifiers are resolved.\n\nThis feature is useful for:\n\n* **Monorepos**: Define explicit dependency relationships between workspace\n  packages without symlinks or hoisting complexities.\n* **Dependency isolation**: Prevent packages from accessing undeclared\n  dependencies (phantom dependencies).\n* **Low file system coupling**: The package resolution algorithm runs without\n  inspecting the file system, relying instead on static data tables.","summary":"Package maps provide a mechanism to control package resolution without relying on the `node_modules` folder structure. When enabled via the `--experimental-package-map` flag, Node.js uses a JSON configuration file to determine how bare specifiers are resolved.","examples":[],"children":[{"kind":"section","id":"configuration-file-format","name":"Configuration file format","title":"Configuration file format","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"The package map configuration file is a JSON file with a `packages` object.\nEach key in `packages` is called a package ID and is a unique identifier for a package entry:\n\n```json\n{\n  \"packages\": {\n    \"app\": {\n      \"url\": \"./packages/app\",\n      \"dependencies\": {\n        \"@myorg/utils\": \"utils\",\n        \"@myorg/ui-lib\": \"ui-lib\"\n      }\n    },\n    \"utils\": {\n      \"url\": \"./packages/utils\"\n    },\n    \"ui-lib\": {\n      \"url\": \"./packages/ui-lib\",\n      \"dependencies\": {\n        \"@myorg/utils\": \"utils\"\n      }\n    }\n  }\n}\n```\n\nEach package entry has the following fields:\n\n* `url` {string} **Required.** An absolute or relative URL. This is parsed using\n  the WHATWG [`URL`](url.html#the-whatwg-url-api) API, using the configuration file URL as base. Only\n  `file:` protocol is supported. Multiple packages are allowed to share the\n  same URL; consumers must key module instances by both module url **and package IDs**\n  to differentiate them.\n* `dependencies` {Object} An object mapping bare specifiers to package keys.\n  Each key is the import name used in source code, and each value is the\n  corresponding package key in the `packages` object. Defaults to an empty\n  object.","summary":"The package map configuration file is a JSON file with a `packages` object. Each key in `packages` is called a package ID and is a unique identifier for a package entry:","examples":[{"language":"json","displayName":null,"code":"{\n  \"packages\": {\n    \"app\": {\n      \"url\": \"./packages/app\",\n      \"dependencies\": {\n        \"@myorg/utils\": \"utils\",\n        \"@myorg/ui-lib\": \"ui-lib\"\n      }\n    },\n    \"utils\": {\n      \"url\": \"./packages/utils\"\n    },\n    \"ui-lib\": {\n      \"url\": \"./packages/ui-lib\",\n      \"dependencies\": {\n        \"@myorg/utils\": \"utils\"\n      }\n    }\n  }\n}"}],"children":[]},{"kind":"section","id":"resolution-algorithm","name":"Resolution algorithm","title":"Resolution algorithm","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"When a bare specifier is encountered:\n\n1. Node.js determines which package performs the resolution request.\n   * If possible the package ID for the importer file should be provided to the resolution algorithm.\n   * Failing that, the resolution will check if the file path is within any\n     package location decoded from its `url`.\n2. If no package ID is provided and the importing file is not within any mapped package, an\n   [`ERR_PACKAGE_MAP_EXTERNAL_FILE`](errors.html#err_package_map_external_file) error is thrown.\n3. Node.js looks up the specifier's package name in the importing package's\n   `dependencies` object to find the corresponding package key.\n4. If found, the resolution algorithm locates the target package location from the\n   package's `url` field in the package map.\n5. If the specifier is not in `dependencies`, a\n   `MODULE_NOT_FOUND` error is thrown.\n6. The package location is forwarded to the regular Node.js resolution algorithm to\n   finish the resolution (`index.js`, exports field, etc).\n\nMore details can be found in the [resolution algorithm pseudo-code](modules.html#all-together).","summary":"When a bare specifier is encountered:","examples":[],"children":[]},{"kind":"section","id":"multiple-package-versions","name":"Multiple package versions","title":"Multiple package versions","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"Different packages can depend on different versions of the same package.\nBecause `dependencies` maps bare specifiers to package keys, two packages\ncan map the same specifier to different targets:\n\n```json\n{\n  \"packages\": {\n    \"app\": {\n      \"url\": \"./app\",\n      \"dependencies\": {\n        \"component\": \"component-v2\"\n      }\n    },\n    \"legacy\": {\n      \"url\": \"./legacy\",\n      \"dependencies\": {\n        \"component\": \"component-v1\"\n      }\n    },\n    \"component-v1\": {\n      \"url\": \"./vendor/component-1.0.0\"\n    },\n    \"component-v2\": {\n      \"url\": \"./vendor/component-2.0.0\"\n    }\n  }\n}\n```\n\nBoth `app` and `legacy` can `import 'component'`, but they resolve to\ndifferent paths based on their declared dependencies.","summary":"Different packages can depend on different versions of the same package. Because `dependencies` maps bare specifiers to package keys, two packages can map the same specifier to different targets:","examples":[{"language":"json","displayName":null,"code":"{\n  \"packages\": {\n    \"app\": {\n      \"url\": \"./app\",\n      \"dependencies\": {\n        \"component\": \"component-v2\"\n      }\n    },\n    \"legacy\": {\n      \"url\": \"./legacy\",\n      \"dependencies\": {\n        \"component\": \"component-v1\"\n      }\n    },\n    \"component-v1\": {\n      \"url\": \"./vendor/component-1.0.0\"\n    },\n    \"component-v2\": {\n      \"url\": \"./vendor/component-2.0.0\"\n    }\n  }\n}"}],"children":[]},{"kind":"section","id":"multiple-packages-for-the-same-url","name":"Multiple packages for the same URL","title":"Multiple packages for the same URL","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"To address complex hoisting situations, multiple packages may share the same\nURL, which introduces ambiguity when determining which package an import\noriginates from:\n\n```json\n{\n  \"packages\": {\n    \"app-old\": {\n      \"url\": \"./app-old\",\n      \"dependencies\": {\n        \"lib\": \"lib-old\"\n      }\n    },\n    \"app-new\": {\n      \"url\": \"./app-new\",\n      \"dependencies\": {\n        \"lib\": \"lib-new\"\n      }\n    },\n    \"lib-old\": {\n      \"url\": \"./lib\",\n      \"dependencies\": {\n        \"react\": \"react-15\"\n      }\n    },\n    \"lib-new\": {\n      \"url\": \"./lib\",\n      \"dependencies\": {\n        \"react\": \"react-18\"\n      }\n    }\n  }\n}\n```\n\nIn the example above both `lib-old` and `lib-new` use the same `./lib` folder to\nstore their sources, the only difference being in which version of `react` they'll\naccess when performing `require` calls or using `import`.\n\nBecause multiple package entries share the same URL, resolving a bare specifier\nfrom a file within that URL is ambiguous unless the originating package ID is\nknown. If the package ID cannot be determined (for example, because the caller\ndid not propagate it from a previous resolution), Node.js will throw an error\nrather than guess.\n\nTo support this pattern, implementers must key module instances by package ID\nand propagate it from each resolution result to subsequent resolution requests.\nThis ensures that when `lib` requires `react`, the runtime knows whether the\nrequest comes from `lib-old` or `lib-new` and can select the correct dependency.","summary":"To address complex hoisting situations, multiple packages may share the same URL, which introduces ambiguity when determining which package an import originates from:","examples":[{"language":"json","displayName":null,"code":"{\n  \"packages\": {\n    \"app-old\": {\n      \"url\": \"./app-old\",\n      \"dependencies\": {\n        \"lib\": \"lib-old\"\n      }\n    },\n    \"app-new\": {\n      \"url\": \"./app-new\",\n      \"dependencies\": {\n        \"lib\": \"lib-new\"\n      }\n    },\n    \"lib-old\": {\n      \"url\": \"./lib\",\n      \"dependencies\": {\n        \"react\": \"react-15\"\n      }\n    },\n    \"lib-new\": {\n      \"url\": \"./lib\",\n      \"dependencies\": {\n        \"react\": \"react-18\"\n      }\n    }\n  }\n}"}],"children":[]},{"kind":"section","id":"interaction-with-other-resolution","name":"Interaction with other resolution","title":"Interaction with other resolution","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"Package maps only apply to bare specifiers that are not Node.js builtin\nmodules. The following cases are not affected by package maps and continue\nto use standard resolution:\n\n* Relative paths or URLs (`./` or `../`).\n* Absolute paths or URLs.\n* Node.js builtin modules (`node:fs`, etc.).","summary":"Package maps only apply to bare specifiers that are not Node.js builtin modules. The following cases are not affected by package maps and continue to use standard resolution:","examples":[],"children":[]},{"kind":"section","id":"limitations","name":"Limitations","title":"Limitations","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"* Package maps must be a single static file; dynamic configuration is not\n  supported.\n* Circular dependency detection is not performed by the package map resolver.\n* The package map file is loaded synchronously at startup.","summary":"","examples":[],"children":[]}]},{"kind":"section","id":"nodejs-packagejson-field-definitions","name":"Node.js package.json field definitions","title":"Node.js `package.json` field definitions","scope":"module","overloadOf":null,"stability":null,"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"This section describes the fields used by the Node.js runtime. Other tools (such\nas [npm](https://docs.npmjs.com/cli/v8/configuring-npm/package-json)) use\nadditional fields which are ignored by Node.js and not documented here.\n\nThe following fields in `package.json` files are used in Node.js:\n\n* [`\"name\"`](#name) - Relevant when using named imports within a package. Also used\n  by package managers as the name of the package.\n* [`\"main\"`](#main) - The default module when loading the package, if exports is not\n  specified, and in versions of Node.js prior to the introduction of exports.\n* [`\"type\"`](#type) - The package type determining whether to load `.js` files as\n  CommonJS or ES modules.\n* [`\"exports\"`](#exports) - Package exports and conditional exports. When present,\n  limits which submodules can be loaded from within the package.\n* [`\"imports\"`](#imports) - Package imports, for use by modules within the package\n  itself.","summary":"This section describes the fields used by the Node.js runtime. Other tools (such as npm) use additional fields which are ignored by Node.js and not documented here.","examples":[],"children":[{"kind":"section","id":"name","name":"\"name\"","title":"`\"name\"`","scope":"module","overloadOf":null,"stability":null,"added":["v13.1.0","v12.16.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[{"versions":["v13.6.0","v12.16.0"],"prUrl":"https://github.com/nodejs/node/pull/31002","commit":null,"description":"Remove the `--experimental-resolve-self` option."}],"description":"* Type: {string}\n\n```json\n{\n  \"name\": \"package-name\"\n}\n```\n\nThe `\"name\"` field defines your package's name. Publishing to the\n*npm* registry requires a name that satisfies\n[certain requirements](https://docs.npmjs.com/files/package.json#name).\n\nThe `\"name\"` field can be used in addition to the [`\"exports\"`](#exports) field to\n[self-reference](#self-referencing-a-package-using-its-name) a package using its name.","summary":"The `\"name\"` field defines your package's name. Publishing to the _npm_ registry requires a name that satisfies certain requirements.","examples":[{"language":"json","displayName":null,"code":"{\n  \"name\": \"package-name\"\n}"}],"children":[]},{"kind":"section","id":"main","name":"\"main\"","title":"`\"main\"`","scope":"module","overloadOf":null,"stability":null,"added":["v0.4.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"* Type: {string}\n\n```json\n{\n  \"main\": \"./index.js\"\n}\n```\n\nThe `\"main\"` field defines the entry point of a package when imported by name\nvia a `node_modules` lookup.  Its value is a path.\n\nThe [`\"exports\"`](#exports) field, if it exists, takes precedence over the\n`\"main\"` field when importing the package by name.\n\nIt also defines the script that is used when the [package directory is loaded\nvia `require()`](modules.html#folders-as-modules).\n\n```cjs\n// This resolves to ./path/to/directory/index.js.\nrequire('./path/to/directory');\n```","summary":"The `\"main\"` field defines the entry point of a package when imported by name via a `node_modules` lookup.  Its value is a path.","examples":[{"language":"json","displayName":null,"code":"{\n  \"main\": \"./index.js\"\n}"},{"language":"cjs","displayName":null,"code":"// This resolves to ./path/to/directory/index.js.\nrequire('./path/to/directory');"}],"children":[]},{"kind":"section","id":"type","name":"\"type\"","title":"`\"type\"`","scope":"module","overloadOf":null,"stability":null,"added":["v12.0.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[{"versions":["v13.2.0","v12.17.0"],"prUrl":"https://github.com/nodejs/node/pull/29866","commit":null,"description":"Unflag `--experimental-modules`."}],"description":"* Type: {string}\n\nThe `\"type\"` field defines the module format that Node.js uses for all\n`.js` files that have that `package.json` file as their nearest parent.\n\nFiles ending with `.js` are loaded as ES modules when the nearest parent\n`package.json` file contains a top-level field `\"type\"` with a value of\n`\"module\"`.\n\nThe nearest parent `package.json` is defined as the first `package.json` found\nwhen searching in the current folder, that folder's parent, and so on up\nuntil a node\\_modules folder or the volume root is reached.\n\n```json\n// package.json\n{\n  \"type\": \"module\"\n}\n```\n\n```bash\n# In same folder as preceding package.json\nnode my-app.js # Runs as ES module\n```\n\nIf the nearest parent `package.json` lacks a `\"type\"` field, or contains\n`\"type\": \"commonjs\"`, `.js` files are treated as [CommonJS](modules.html). If the volume\nroot is reached and no `package.json` is found, `.js` files are treated as\n[CommonJS](modules.html).\n\n`import` statements of `.js` files are treated as ES modules if the nearest\nparent `package.json` contains `\"type\": \"module\"`.\n\n```js\n// my-app.js, part of the same example as above\nimport './startup.js'; // Loaded as ES module because of package.json\n```\n\nRegardless of the value of the `\"type\"` field, `.mjs` files are always treated\nas ES modules and `.cjs` files are always treated as CommonJS.","summary":"The `\"type\"` field defines the module format that Node.js uses for all `.js` files that have that `package.json` file as their nearest parent.","examples":[{"language":"json","displayName":null,"code":"// package.json\n{\n  \"type\": \"module\"\n}"},{"language":"bash","displayName":null,"code":"# In same folder as preceding package.json\nnode my-app.js # Runs as ES module"},{"language":"js","displayName":null,"code":"// my-app.js, part of the same example as above\nimport './startup.js'; // Loaded as ES module because of package.json"}],"children":[]},{"kind":"section","id":"exports","name":"\"exports\"","title":"`\"exports\"`","scope":"module","overloadOf":null,"stability":null,"added":["v12.7.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[{"versions":["v14.13.0","v12.20.0"],"prUrl":"https://github.com/nodejs/node/pull/34718","commit":null,"description":"Add support for `\"exports\"` patterns."},{"versions":["v13.7.0","v12.17.0"],"prUrl":"https://github.com/nodejs/node/pull/29866","commit":null,"description":"Unflag conditional exports."},{"versions":["v13.7.0","v12.16.0"],"prUrl":"https://github.com/nodejs/node/pull/31008","commit":null,"description":"Implement logical conditional exports ordering."},{"versions":["v13.7.0","v12.16.0"],"prUrl":"https://github.com/nodejs/node/pull/31001","commit":null,"description":"Remove the `--experimental-conditional-exports` option. In 12.16.0, conditional exports are still behind `--experimental-modules`."},{"versions":["v13.2.0","v12.16.0"],"prUrl":"https://github.com/nodejs/node/pull/29978","commit":null,"description":"Implement conditional exports."}],"description":"* Type: {Object | string | string[]}\n\n```json\n{\n  \"exports\": \"./index.js\"\n}\n```\n\nThe `\"exports\"` field allows defining the [entry points](#package-entry-points) of a package when\nimported by name loaded either via a `node_modules` lookup or a\n[self-reference](#self-referencing-a-package-using-its-name) to its own name. It is supported in Node.js 12+ as an\nalternative to the [`\"main\"`](#main) that can support defining [subpath exports](#subpath-exports)\nand [conditional exports](#conditional-exports) while encapsulating internal unexported modules.\n\n[Conditional Exports](#conditional-exports) can also be used within `\"exports\"` to define different\npackage entry points per environment, including whether the package is\nreferenced via `require` or via `import`.\n\nAll paths defined in the `\"exports\"` must be relative file URLs starting with\n`./`.","summary":"The `\"exports\"` field allows defining the entry points of a package when imported by name loaded either via a `node_modules` lookup or a self-reference to its own name. It is supported in Node.js 12+ as an alternative to the `\"main\"` that can support defining subpath exports and conditional exports while encapsulating internal unexported modules.","examples":[{"language":"json","displayName":null,"code":"{\n  \"exports\": \"./index.js\"\n}"}],"children":[]},{"kind":"section","id":"imports","name":"\"imports\"","title":"`\"imports\"`","scope":"module","overloadOf":null,"stability":null,"added":["v14.6.0","v12.19.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"* Type: {Object}\n\n```json\n// package.json\n{\n  \"imports\": {\n    \"#dep\": {\n      \"node\": \"dep-node-native\",\n      \"default\": \"./dep-polyfill.js\"\n    }\n  },\n  \"dependencies\": {\n    \"dep-node-native\": \"^1.0.0\"\n  }\n}\n```\n\nEntries in the imports field must be strings starting with `#`.\n\nPackage imports permit mapping to external packages.\n\nThis field defines [subpath imports](#subpath-imports) for the current package.","summary":"Entries in the imports field must be strings starting with `#`.","examples":[{"language":"json","displayName":null,"code":"// package.json\n{\n  \"imports\": {\n    \"#dep\": {\n      \"node\": \"dep-node-native\",\n      \"default\": \"./dep-polyfill.js\"\n    }\n  },\n  \"dependencies\": {\n    \"dep-node-native\": \"^1.0.0\"\n  }\n}"}],"children":[]}]}]}