1# Modules: Packages
2
3<!--introduced_in=v12.20.0-->
4
5<!-- type=misc -->
6
7<!-- YAML
8changes:
9  - version:
10    - v14.13.0
11    - v12.20.0
12    pr-url: https://github.com/nodejs/node/pull/34718
13    description: Add support for `"exports"` patterns.
14  - version:
15    - v14.6.0
16    - v12.19.0
17    pr-url: https://github.com/nodejs/node/pull/34117
18    description: Add package `"imports"` field.
19  - version:
20    - v13.7.0
21    - v12.17.0
22    pr-url: https://github.com/nodejs/node/pull/29866
23    description: Unflag conditional exports.
24  - version:
25    - v13.7.0
26    - v12.16.0
27    pr-url: https://github.com/nodejs/node/pull/31001
28    description: Remove the `--experimental-conditional-exports` option. In 12.16.0, conditional exports are still behind `--experimental-modules`.
29  - version:
30    - v13.6.0
31    - v12.16.0
32    pr-url: https://github.com/nodejs/node/pull/31002
33    description: Unflag self-referencing a package using its name.
34  - version: v12.7.0
35    pr-url: https://github.com/nodejs/node/pull/28568
36    description:
37      Introduce `"exports"` `package.json` field as a more powerful alternative
38      to the classic `"main"` field.
39  - version: v12.0.0
40    pr-url: https://github.com/nodejs/node/pull/26745
41    description:
42      Add support for ES modules using `.js` file extension via `package.json`
43      `"type"` field.
44-->
45
46## Introduction
47
48A package is a folder tree described by a `package.json` file. The package
49consists of the folder containing the `package.json` file and all subfolders
50until the next folder containing another `package.json` file, or a folder
51named `node_modules`.
52
53This page provides guidance for package authors writing `package.json` files
54along with a reference for the [`package.json`][] fields defined by Node.js.
55
56## Determining module system
57
58### Introduction
59
60Node.js will treat the following as [ES modules][] when passed to `node` as the
61initial input, or when referenced by `import` statements or `import()`
62expressions:
63
64* Files with an `.mjs` extension.
65
66* Files with a `.js` extension when the nearest parent `package.json` file
67  contains a top-level [`"type"`][] field with a value of `"module"`.
68
69* Strings passed in as an argument to `--eval`, or piped to `node` via `STDIN`,
70  with the flag `--input-type=module`.
71
72Node.js will treat the following as [CommonJS][] when passed to `node` as the
73initial input, or when referenced by `import` statements or `import()`
74expressions:
75
76* Files with a `.cjs` extension.
77
78* Files with a `.js` extension when the nearest parent `package.json` file
79  contains a top-level field [`"type"`][] with a value of `"commonjs"`.
80
81* Strings passed in as an argument to `--eval` or `--print`, or piped to `node`
82  via `STDIN`, with the flag `--input-type=commonjs`.
83
84Aside from these explicit cases, there are other cases where Node.js defaults to
85one module system or the other based on the value of the
86[`--experimental-default-type`][] flag:
87
88* Files ending in `.js` or with no extension, if there is no `package.json` file
89  present in the same folder or any parent folder.
90
91* Files ending in `.js` or with no extension, if the nearest parent
92  `package.json` field lacks a `"type"` field; unless the folder is inside a
93  `node_modules` folder. (Package scopes under `node_modules` are always treated
94  as CommonJS when the `package.json` file lacks a `"type"` field, regardless
95  of `--experimental-default-type`, for backward compatibility.)
96
97* Strings passed in as an argument to `--eval` or piped to `node` via `STDIN`,
98  when `--input-type` is unspecified.
99
100This flag currently defaults to `"commonjs"`, but it may change in the future to
101default to `"module"`. For this reason it is best to be explicit wherever
102possible; in particular, package authors should always include the [`"type"`][]
103field in their `package.json` files, even in packages where all sources are
104CommonJS. Being explicit about the `type` of the package will future-proof the
105package in case the default type of Node.js ever changes, and it will also make
106things easier for build tools and loaders to determine how the files in the
107package should be interpreted.
108
109### Modules loaders
110
111Node.js has two systems for resolving a specifier and loading modules.
112
113There is the CommonJS module loader:
114
115* It is fully synchronous.
116* It is responsible for handling `require()` calls.
117* It is monkey patchable.
118* It supports [folders as modules][].
119* When resolving a specifier, if no exact match is found, it will try to add
120  extensions (`.js`, `.json`, and finally `.node`) and then attempt to resolve
121  [folders as modules][].
122* It treats `.json` as JSON text files.
123* `.node` files are interpreted as compiled addon modules loaded with
124  `process.dlopen()`.
125* It treats all files that lack `.json` or `.node` extensions as JavaScript
126  text files.
127* It cannot be used to load ECMAScript modules (although it is possible to
128  [load ECMASCript modules from CommonJS modules][]). When used to load a
129  JavaScript text file that is not an ECMAScript module, it loads it as a
130  CommonJS module.
131
132There is the ECMAScript module loader:
133
134* It is asynchronous.
135* It is responsible for handling `import` statements and `import()` expressions.
136* It is not monkey patchable, can be customized using [loader hooks][].
137* It does not support folders as modules, directory indexes (e.g.
138  `'./startup/index.js'`) must be fully specified.
139* It does no extension searching. A file extension must be provided
140  when the specifier is a relative or absolute file URL.
141* It can load JSON modules, but an import assertion is required.
142* It accepts only `.js`, `.mjs`, and `.cjs` extensions for JavaScript text
143  files.
144* It can be used to load JavaScript CommonJS modules. Such modules
145  are passed through the `cjs-module-lexer` to try to identify named exports,
146  which are available if they can be determined through static analysis.
147  Imported CommonJS modules have their URLs converted to absolute
148  paths and are then loaded via the CommonJS module loader.
149
150### `package.json` and file extensions
151
152Within a package, the [`package.json`][] [`"type"`][] field defines how
153Node.js should interpret `.js` files. If a `package.json` file does not have a
154`"type"` field, `.js` files are treated as [CommonJS][].
155
156A `package.json` `"type"` value of `"module"` tells Node.js to interpret `.js`
157files within that package as using [ES module][] syntax.
158
159The `"type"` field applies not only to initial entry points (`node my-app.js`)
160but also to files referenced by `import` statements and `import()` expressions.
161
162```js
163// my-app.js, treated as an ES module because there is a package.json
164// file in the same folder with "type": "module".
165
166import './startup/init.js';
167// Loaded as ES module since ./startup contains no package.json file,
168// and therefore inherits the "type" value from one level up.
169
170import 'commonjs-package';
171// Loaded as CommonJS since ./node_modules/commonjs-package/package.json
172// lacks a "type" field or contains "type": "commonjs".
173
174import './node_modules/commonjs-package/index.js';
175// Loaded as CommonJS since ./node_modules/commonjs-package/package.json
176// lacks a "type" field or contains "type": "commonjs".
177```
178
179Files ending with `.mjs` are always loaded as [ES modules][] regardless of
180the nearest parent `package.json`.
181
182Files ending with `.cjs` are always loaded as [CommonJS][] regardless of the
183nearest parent `package.json`.
184
185```js
186import './legacy-file.cjs';
187// Loaded as CommonJS since .cjs is always loaded as CommonJS.
188
189import 'commonjs-package/src/index.mjs';
190// Loaded as ES module since .mjs is always loaded as ES module.
191```
192
193The `.mjs` and `.cjs` extensions can be used to mix types within the same
194package:
195
196* Within a `"type": "module"` package, Node.js can be instructed to
197  interpret a particular file as [CommonJS][] by naming it with a `.cjs`
198  extension (since both `.js` and `.mjs` files are treated as ES modules within
199  a `"module"` package).
200
201* Within a `"type": "commonjs"` package, Node.js can be instructed to
202  interpret a particular file as an [ES module][] by naming it with an `.mjs`
203  extension (since both `.js` and `.cjs` files are treated as CommonJS within a
204  `"commonjs"` package).
205
206### `--input-type` flag
207
208<!-- YAML
209added: v12.0.0
210-->
211
212Strings passed in as an argument to `--eval` (or `-e`), or piped to `node` via
213`STDIN`, are treated as [ES modules][] when the `--input-type=module` flag
214is set.
215
216```bash
217node --input-type=module --eval "import { sep } from 'node:path'; console.log(sep);"
218
219echo "import { sep } from 'node:path'; console.log(sep);" | node --input-type=module
220```
221
222For completeness there is also `--input-type=commonjs`, for explicitly running
223string input as CommonJS. This is the default behavior if `--input-type` is
224unspecified.
225
226## Determining package manager
227
228> Stability: 1 - Experimental
229
230While all Node.js projects are expected to be installable by all package
231managers once published, their development teams are often required to use one
232specific package manager. To make this process easier, Node.js ships with a
233tool called [Corepack][] that aims to make all package managers transparently
234available in your environment - provided you have Node.js installed.
235
236By default Corepack won't enforce any specific package manager and will use
237the generic "Last Known Good" versions associated with each Node.js release,
238but you can improve this experience by setting the [`"packageManager"`][] field
239in your project's `package.json`.
240
241## Package entry points
242
243In a package's `package.json` file, two fields can define entry points for a
244package: [`"main"`][] and [`"exports"`][]. Both fields apply to both ES module
245and CommonJS module entry points.
246
247The [`"main"`][] field is supported in all versions of Node.js, but its
248capabilities are limited: it only defines the main entry point of the package.
249
250The [`"exports"`][] provides a modern alternative to [`"main"`][] allowing
251multiple entry points to be defined, conditional entry resolution support
252between environments, and **preventing any other entry points besides those
253defined in [`"exports"`][]**. This encapsulation allows module authors to
254clearly define the public interface for their package.
255
256For new packages targeting the currently supported versions of Node.js, the
257[`"exports"`][] field is recommended. For packages supporting Node.js 10 and
258below, the [`"main"`][] field is required. If both [`"exports"`][] and
259[`"main"`][] are defined, the [`"exports"`][] field takes precedence over
260[`"main"`][] in supported versions of Node.js.
261
262[Conditional exports][] can be used within [`"exports"`][] to define different
263package entry points per environment, including whether the package is
264referenced via `require` or via `import`. For more information about supporting
265both CommonJS and ES modules in a single package please consult
266[the dual CommonJS/ES module packages section][].
267
268Existing packages introducing the [`"exports"`][] field will prevent consumers
269of the package from using any entry points that are not defined, including the
270[`package.json`][] (e.g. `require('your-package/package.json')`. **This will
271likely be a breaking change.**
272
273To make the introduction of [`"exports"`][] non-breaking, ensure that every
274previously supported entry point is exported. It is best to explicitly specify
275entry points so that the package's public API is well-defined. For example,
276a project that previously exported `main`, `lib`,
277`feature`, and the `package.json` could use the following `package.exports`:
278
279```json
280{
281  "name": "my-package",
282  "exports": {
283    ".": "./lib/index.js",
284    "./lib": "./lib/index.js",
285    "./lib/index": "./lib/index.js",
286    "./lib/index.js": "./lib/index.js",
287    "./feature": "./feature/index.js",
288    "./feature/index": "./feature/index.js",
289    "./feature/index.js": "./feature/index.js",
290    "./package.json": "./package.json"
291  }
292}
293```
294
295Alternatively a project could choose to export entire folders both with and
296without extensioned subpaths using export patterns:
297
298```json
299{
300  "name": "my-package",
301  "exports": {
302    ".": "./lib/index.js",
303    "./lib": "./lib/index.js",
304    "./lib/*": "./lib/*.js",
305    "./lib/*.js": "./lib/*.js",
306    "./feature": "./feature/index.js",
307    "./feature/*": "./feature/*.js",
308    "./feature/*.js": "./feature/*.js",
309    "./package.json": "./package.json"
310  }
311}
312```
313
314With the above providing backwards-compatibility for any minor package versions,
315a future major change for the package can then properly restrict the exports
316to only the specific feature exports exposed:
317
318```json
319{
320  "name": "my-package",
321  "exports": {
322    ".": "./lib/index.js",
323    "./feature/*.js": "./feature/*.js",
324    "./feature/internal/*": null
325  }
326}
327```
328
329### Main entry point export
330
331When writing a new package, it is recommended to use the [`"exports"`][] field:
332
333```json
334{
335  "exports": "./index.js"
336}
337```
338
339When the [`"exports"`][] field is defined, all subpaths of the package are
340encapsulated and no longer available to importers. For example,
341`require('pkg/subpath.js')` throws an [`ERR_PACKAGE_PATH_NOT_EXPORTED`][]
342error.
343
344This encapsulation of exports provides more reliable guarantees
345about package interfaces for tools and when handling semver upgrades for a
346package. It is not a strong encapsulation since a direct require of any
347absolute subpath of the package such as
348`require('/path/to/node_modules/pkg/subpath.js')` will still load `subpath.js`.
349
350All currently supported versions of Node.js and modern build tools support the
351`"exports"` field. For projects using an older version of Node.js or a related
352build tool, compatibility can be achieved by including the `"main"` field
353alongside `"exports"` pointing to the same module:
354
355```json
356{
357  "main": "./index.js",
358  "exports": "./index.js"
359}
360```
361
362### Subpath exports
363
364<!-- YAML
365added: v12.7.0
366-->
367
368When using the [`"exports"`][] field, custom subpaths can be defined along
369with the main entry point by treating the main entry point as the
370`"."` subpath:
371
372```json
373{
374  "exports": {
375    ".": "./index.js",
376    "./submodule.js": "./src/submodule.js"
377  }
378}
379```
380
381Now only the defined subpath in [`"exports"`][] can be imported by a consumer:
382
383```js
384import submodule from 'es-module-package/submodule.js';
385// Loads ./node_modules/es-module-package/src/submodule.js
386```
387
388While other subpaths will error:
389
390```js
391import submodule from 'es-module-package/private-module.js';
392// Throws ERR_PACKAGE_PATH_NOT_EXPORTED
393```
394
395#### Extensions in subpaths
396
397Package authors should provide either extensioned (`import 'pkg/subpath.js'`) or
398extensionless (`import 'pkg/subpath'`) subpaths in their exports. This ensures
399that there is only one subpath for each exported module so that all dependents
400import the same consistent specifier, keeping the package contract clear for
401consumers and simplifying package subpath completions.
402
403Traditionally, packages tended to use the extensionless style, which has the
404benefits of readability and of masking the true path of the file within the
405package.
406
407With [import maps][] now providing a standard for package resolution in browsers
408and other JavaScript runtimes, using the extensionless style can result in
409bloated import map definitions. Explicit file extensions can avoid this issue by
410enabling the import map to utilize a [packages folder mapping][] to map multiple
411subpaths where possible instead of a separate map entry per package subpath
412export. This also mirrors the requirement of using [the full specifier path][]
413in relative and absolute import specifiers.
414
415### Exports sugar
416
417<!-- YAML
418added: v12.11.0
419-->
420
421If the `"."` export is the only export, the [`"exports"`][] field provides sugar
422for this case being the direct [`"exports"`][] field value.
423
424```json
425{
426  "exports": {
427    ".": "./index.js"
428  }
429}
430```
431
432can be written:
433
434```json
435{
436  "exports": "./index.js"
437}
438```
439
440### Subpath imports
441
442<!-- YAML
443added:
444  - v14.6.0
445  - v12.19.0
446-->
447
448In addition to the [`"exports"`][] field, there is a package `"imports"` field
449to create private mappings that only apply to import specifiers from within the
450package itself.
451
452Entries in the `"imports"` field must always start with `#` to ensure they are
453disambiguated from external package specifiers.
454
455For example, the imports field can be used to gain the benefits of conditional
456exports for internal modules:
457
458```json
459// package.json
460{
461  "imports": {
462    "#dep": {
463      "node": "dep-node-native",
464      "default": "./dep-polyfill.js"
465    }
466  },
467  "dependencies": {
468    "dep-node-native": "^1.0.0"
469  }
470}
471```
472
473where `import '#dep'` does not get the resolution of the external package
474`dep-node-native` (including its exports in turn), and instead gets the local
475file `./dep-polyfill.js` relative to the package in other environments.
476
477Unlike the `"exports"` field, the `"imports"` field permits mapping to external
478packages.
479
480The resolution rules for the imports field are otherwise analogous to the
481exports field.
482
483### Subpath patterns
484
485<!-- YAML
486added:
487  - v14.13.0
488  - v12.20.0
489changes:
490  - version:
491    - v16.10.0
492    - v14.19.0
493    pr-url: https://github.com/nodejs/node/pull/40041
494    description: Support pattern trailers in "imports" field.
495  - version:
496    - v16.9.0
497    - v14.19.0
498    pr-url: https://github.com/nodejs/node/pull/39635
499    description: Support pattern trailers.
500-->
501
502For packages with a small number of exports or imports, we recommend
503explicitly listing each exports subpath entry. But for packages that have
504large numbers of subpaths, this might cause `package.json` bloat and
505maintenance issues.
506
507For these use cases, subpath export patterns can be used instead:
508
509```json
510// ./node_modules/es-module-package/package.json
511{
512  "exports": {
513    "./features/*.js": "./src/features/*.js"
514  },
515  "imports": {
516    "#internal/*.js": "./src/internal/*.js"
517  }
518}
519```
520
521**`*` maps expose nested subpaths as it is a string replacement syntax
522only.**
523
524All instances of `*` on the right hand side will then be replaced with this
525value, including if it contains any `/` separators.
526
527```js
528import featureX from 'es-module-package/features/x.js';
529// Loads ./node_modules/es-module-package/src/features/x.js
530
531import featureY from 'es-module-package/features/y/y.js';
532// Loads ./node_modules/es-module-package/src/features/y/y.js
533
534import internalZ from '#internal/z.js';
535// Loads ./node_modules/es-module-package/src/internal/z.js
536```
537
538This is a direct static matching and replacement without any special handling
539for file extensions. Including the `"*.js"` on both sides of the mapping
540restricts the exposed package exports to only JS files.
541
542The property of exports being statically enumerable is maintained with exports
543patterns since the individual exports for a package can be determined by
544treating the right hand side target pattern as a `**` glob against the list of
545files within the package. Because `node_modules` paths are forbidden in exports
546targets, this expansion is dependent on only the files of the package itself.
547
548To exclude private subfolders from patterns, `null` targets can be used:
549
550```json
551// ./node_modules/es-module-package/package.json
552{
553  "exports": {
554    "./features/*.js": "./src/features/*.js",
555    "./features/private-internal/*": null
556  }
557}
558```
559
560```js
561import featureInternal from 'es-module-package/features/private-internal/m.js';
562// Throws: ERR_PACKAGE_PATH_NOT_EXPORTED
563
564import featureX from 'es-module-package/features/x.js';
565// Loads ./node_modules/es-module-package/src/features/x.js
566```
567
568### Conditional exports
569
570<!-- YAML
571added:
572  - v13.2.0
573  - v12.16.0
574changes:
575  - version:
576    - v13.7.0
577    - v12.16.0
578    pr-url: https://github.com/nodejs/node/pull/31001
579    description: Unflag conditional exports.
580-->
581
582Conditional exports provide a way to map to different paths depending on
583certain conditions. They are supported for both CommonJS and ES module imports.
584
585For example, a package that wants to provide different ES module exports for
586`require()` and `import` can be written:
587
588```json
589// package.json
590{
591  "exports": {
592    "import": "./index-module.js",
593    "require": "./index-require.cjs"
594  },
595  "type": "module"
596}
597```
598
599Node.js implements the following conditions, listed in order from most
600specific to least specific as conditions should be defined:
601
602* `"node-addons"` - similar to `"node"` and matches for any Node.js environment.
603  This condition can be used to provide an entry point which uses native C++
604  addons as opposed to an entry point which is more universal and doesn't rely
605  on native addons. This condition can be disabled via the
606  [`--no-addons` flag][].
607* `"node"` - matches for any Node.js environment. Can be a CommonJS or ES
608  module file. _In most cases explicitly calling out the Node.js platform is
609  not necessary._
610* `"import"` - matches when the package is loaded via `import` or
611  `import()`, or via any top-level import or resolve operation by the
612  ECMAScript module loader. Applies regardless of the module format of the
613  target file. _Always mutually exclusive with `"require"`._
614* `"require"` - matches when the package is loaded via `require()`. The
615  referenced file should be loadable with `require()` although the condition
616  matches regardless of the module format of the target file. Expected
617  formats include CommonJS, JSON, and native addons but not ES modules as
618  `require()` doesn't support them. _Always mutually exclusive with
619  `"import"`._
620* `"default"` - the generic fallback that always matches. Can be a CommonJS
621  or ES module file. _This condition should always come last._
622
623Within the [`"exports"`][] object, key order is significant. During condition
624matching, earlier entries have higher priority and take precedence over later
625entries. _The general rule is that conditions should be from most specific to
626least specific in object order_.
627
628Using the `"import"` and `"require"` conditions can lead to some hazards,
629which are further explained in [the dual CommonJS/ES module packages section][].
630
631The `"node-addons"` condition can be used to provide an entry point which
632uses native C++ addons. However, this condition can be disabled via the
633[`--no-addons` flag][]. When using `"node-addons"`, it's recommended to treat
634`"default"` as an enhancement that provides a more universal entry point, e.g.
635using WebAssembly instead of a native addon.
636
637Conditional exports can also be extended to exports subpaths, for example:
638
639```json
640{
641  "exports": {
642    ".": "./index.js",
643    "./feature.js": {
644      "node": "./feature-node.js",
645      "default": "./feature.js"
646    }
647  }
648}
649```
650
651Defines a package where `require('pkg/feature.js')` and
652`import 'pkg/feature.js'` could provide different implementations between
653Node.js and other JS environments.
654
655When using environment branches, always include a `"default"` condition where
656possible. Providing a `"default"` condition ensures that any unknown JS
657environments are able to use this universal implementation, which helps avoid
658these JS environments from having to pretend to be existing environments in
659order to support packages with conditional exports. For this reason, using
660`"node"` and `"default"` condition branches is usually preferable to using
661`"node"` and `"browser"` condition branches.
662
663### Nested conditions
664
665In addition to direct mappings, Node.js also supports nested condition objects.
666
667For example, to define a package that only has dual mode entry points for
668use in Node.js but not the browser:
669
670```json
671{
672  "exports": {
673    "node": {
674      "import": "./feature-node.mjs",
675      "require": "./feature-node.cjs"
676    },
677    "default": "./feature.mjs"
678  }
679}
680```
681
682Conditions continue to be matched in order as with flat conditions. If
683a nested condition does not have any mapping it will continue checking
684the remaining conditions of the parent condition. In this way nested
685conditions behave analogously to nested JavaScript `if` statements.
686
687### Resolving user conditions
688
689<!-- YAML
690added:
691  - v14.9.0
692  - v12.19.0
693-->
694
695When running Node.js, custom user conditions can be added with the
696`--conditions` flag:
697
698```bash
699node --conditions=development index.js
700```
701
702which would then resolve the `"development"` condition in package imports and
703exports, while resolving the existing `"node"`, `"node-addons"`, `"default"`,
704`"import"`, and `"require"` conditions as appropriate.
705
706Any number of custom conditions can be set with repeat flags.
707
708### Community Conditions Definitions
709
710Condition strings other than the `"import"`, `"require"`, `"node"`,
711`"node-addons"` and `"default"` conditions
712[implemented in Node.js core](#conditional-exports) are ignored by default.
713
714Other platforms may implement other conditions and user conditions can be
715enabled in Node.js via the [`--conditions` / `-C` flag][].
716
717Since custom package conditions require clear definitions to ensure correct
718usage, a list of common known package conditions and their strict definitions
719is provided below to assist with ecosystem coordination.
720
721* `"types"` - can be used by typing systems to resolve the typing file for
722  the given export. _This condition should always be included first._
723* `"browser"` - any web browser environment.
724* `"development"` - can be used to define a development-only environment
725  entry point, for example to provide additional debugging context such as
726  better error messages when running in a development mode. _Must always be
727  mutually exclusive with `"production"`._
728* `"production"` - can be used to define a production environment entry
729  point. _Must always be mutually exclusive with `"development"`._
730
731For other runtimes, platform-specific condition key definitions are maintained
732by the [WinterCG][] in the [Runtime Keys][] proposal specification.
733
734New conditions definitions may be added to this list by creating a pull request
735to the [Node.js documentation for this section][]. The requirements for listing
736a new condition definition here are that:
737
738* The definition should be clear and unambiguous for all implementers.
739* The use case for why the condition is needed should be clearly justified.
740* There should exist sufficient existing implementation usage.
741* The condition name should not conflict with another condition definition or
742  condition in wide usage.
743* The listing of the condition definition should provide a coordination
744  benefit to the ecosystem that wouldn't otherwise be possible. For example,
745  this would not necessarily be the case for company-specific or
746  application-specific conditions.
747* The condition should be such that a Node.js user would expect it to be in
748  Node.js core documentation. The `"types"` condition is a good example: It
749  doesn't really belong in the [Runtime Keys][] proposal but is a good fit
750  here in the Node.js docs.
751
752The above definitions may be moved to a dedicated conditions registry in due
753course.
754
755### Self-referencing a package using its name
756
757<!-- YAML
758added:
759  - v13.1.0
760  - v12.16.0
761changes:
762  - version:
763    - v13.6.0
764    - v12.16.0
765    pr-url: https://github.com/nodejs/node/pull/31002
766    description: Unflag self-referencing a package using its name.
767-->
768
769Within a package, the values defined in the package's
770`package.json` [`"exports"`][] field can be referenced via the package's name.
771For example, assuming the `package.json` is:
772
773```json
774// package.json
775{
776  "name": "a-package",
777  "exports": {
778    ".": "./index.mjs",
779    "./foo.js": "./foo.js"
780  }
781}
782```
783
784Then any module _in that package_ can reference an export in the package itself:
785
786```js
787// ./a-module.mjs
788import { something } from 'a-package'; // Imports "something" from ./index.mjs.
789```
790
791Self-referencing is available only if `package.json` has [`"exports"`][], and
792will allow importing only what that [`"exports"`][] (in the `package.json`)
793allows. So the code below, given the previous package, will generate a runtime
794error:
795
796```js
797// ./another-module.mjs
798
799// Imports "another" from ./m.mjs. Fails because
800// the "package.json" "exports" field
801// does not provide an export named "./m.mjs".
802import { another } from 'a-package/m.mjs';
803```
804
805Self-referencing is also available when using `require`, both in an ES module,
806and in a CommonJS one. For example, this code will also work:
807
808```cjs
809// ./a-module.js
810const { something } = require('a-package/foo.js'); // Loads from ./foo.js.
811```
812
813Finally, self-referencing also works with scoped packages. For example, this
814code will also work:
815
816```json
817// package.json
818{
819  "name": "@my/package",
820  "exports": "./index.js"
821}
822```
823
824```cjs
825// ./index.js
826module.exports = 42;
827```
828
829```cjs
830// ./other.js
831console.log(require('@my/package'));
832```
833
834```console
835$ node other.js
83642
837```
838
839## Dual CommonJS/ES module packages
840
841Prior to the introduction of support for ES modules in Node.js, it was a common
842pattern for package authors to include both CommonJS and ES module JavaScript
843sources in their package, with `package.json` [`"main"`][] specifying the
844CommonJS entry point and `package.json` `"module"` specifying the ES module
845entry point.
846This enabled Node.js to run the CommonJS entry point while build tools such as
847bundlers used the ES module entry point, since Node.js ignored (and still
848ignores) the top-level `"module"` field.
849
850Node.js can now run ES module entry points, and a package can contain both
851CommonJS and ES module entry points (either via separate specifiers such as
852`'pkg'` and `'pkg/es-module'`, or both at the same specifier via [Conditional
853exports][]). Unlike in the scenario where `"module"` is only used by bundlers,
854or ES module files are transpiled into CommonJS on the fly before evaluation by
855Node.js, the files referenced by the ES module entry point are evaluated as ES
856modules.
857
858### Dual package hazard
859
860When an application is using a package that provides both CommonJS and ES module
861sources, there is a risk of certain bugs if both versions of the package get
862loaded. This potential comes from the fact that the `pkgInstance` created by
863`const pkgInstance = require('pkg')` is not the same as the `pkgInstance`
864created by `import pkgInstance from 'pkg'` (or an alternative main path like
865`'pkg/module'`). This is the “dual package hazard,” where two versions of the
866same package can be loaded within the same runtime environment. While it is
867unlikely that an application or package would intentionally load both versions
868directly, it is common for an application to load one version while a dependency
869of the application loads the other version. This hazard can happen because
870Node.js supports intermixing CommonJS and ES modules, and can lead to unexpected
871behavior.
872
873If the package main export is a constructor, an `instanceof` comparison of
874instances created by the two versions returns `false`, and if the export is an
875object, properties added to one (like `pkgInstance.foo = 3`) are not present on
876the other. This differs from how `import` and `require` statements work in
877all-CommonJS or all-ES module environments, respectively, and therefore is
878surprising to users. It also differs from the behavior users are familiar with
879when using transpilation via tools like [Babel][] or [`esm`][].
880
881### Writing dual packages while avoiding or minimizing hazards
882
883First, the hazard described in the previous section occurs when a package
884contains both CommonJS and ES module sources and both sources are provided for
885use in Node.js, either via separate main entry points or exported paths. A
886package might instead be written where any version of Node.js receives only
887CommonJS sources, and any separate ES module sources the package might contain
888are intended only for other environments such as browsers. Such a package
889would be usable by any version of Node.js, since `import` can refer to CommonJS
890files; but it would not provide any of the advantages of using ES module syntax.
891
892A package might also switch from CommonJS to ES module syntax in a [breaking
893change](https://semver.org/) version bump. This has the disadvantage that the
894newest version of the package would only be usable in ES module-supporting
895versions of Node.js.
896
897Every pattern has tradeoffs, but there are two broad approaches that satisfy the
898following conditions:
899
9001. The package is usable via both `require` and `import`.
9012. The package is usable in both current Node.js and older versions of Node.js
902   that lack support for ES modules.
9033. The package main entry point, e.g. `'pkg'` can be used by both `require` to
904   resolve to a CommonJS file and by `import` to resolve to an ES module file.
905   (And likewise for exported paths, e.g. `'pkg/feature'`.)
9064. The package provides named exports, e.g. `import { name } from 'pkg'` rather
907   than `import pkg from 'pkg'; pkg.name`.
9085. The package is potentially usable in other ES module environments such as
909   browsers.
9106. The hazards described in the previous section are avoided or minimized.
911
912#### Approach #1: Use an ES module wrapper
913
914Write the package in CommonJS or transpile ES module sources into CommonJS, and
915create an ES module wrapper file that defines the named exports. Using
916[Conditional exports][], the ES module wrapper is used for `import` and the
917CommonJS entry point for `require`.
918
919```json
920// ./node_modules/pkg/package.json
921{
922  "type": "module",
923  "exports": {
924    "import": "./wrapper.mjs",
925    "require": "./index.cjs"
926  }
927}
928```
929
930The preceding example uses explicit extensions `.mjs` and `.cjs`.
931If your files use the `.js` extension, `"type": "module"` will cause such files
932to be treated as ES modules, just as `"type": "commonjs"` would cause them
933to be treated as CommonJS.
934See [Enabling](esm.md#enabling).
935
936```cjs
937// ./node_modules/pkg/index.cjs
938exports.name = 'value';
939```
940
941```js
942// ./node_modules/pkg/wrapper.mjs
943import cjsModule from './index.cjs';
944export const name = cjsModule.name;
945```
946
947In this example, the `name` from `import { name } from 'pkg'` is the same
948singleton as the `name` from `const { name } = require('pkg')`. Therefore `===`
949returns `true` when comparing the two `name`s and the divergent specifier hazard
950is avoided.
951
952If the module is not simply a list of named exports, but rather contains a
953unique function or object export like `module.exports = function () { ... }`,
954or if support in the wrapper for the `import pkg from 'pkg'` pattern is desired,
955then the wrapper would instead be written to export the default optionally
956along with any named exports as well:
957
958```js
959import cjsModule from './index.cjs';
960export const name = cjsModule.name;
961export default cjsModule;
962```
963
964This approach is appropriate for any of the following use cases:
965
966* The package is currently written in CommonJS and the author would prefer not
967  to refactor it into ES module syntax, but wishes to provide named exports for
968  ES module consumers.
969* The package has other packages that depend on it, and the end user might
970  install both this package and those other packages. For example a `utilities`
971  package is used directly in an application, and a `utilities-plus` package
972  adds a few more functions to `utilities`. Because the wrapper exports
973  underlying CommonJS files, it doesn't matter if `utilities-plus` is written in
974  CommonJS or ES module syntax; it will work either way.
975* The package stores internal state, and the package author would prefer not to
976  refactor the package to isolate its state management. See the next section.
977
978A variant of this approach not requiring conditional exports for consumers could
979be to add an export, e.g. `"./module"`, to point to an all-ES module-syntax
980version of the package. This could be used via `import 'pkg/module'` by users
981who are certain that the CommonJS version will not be loaded anywhere in the
982application, such as by dependencies; or if the CommonJS version can be loaded
983but doesn't affect the ES module version (for example, because the package is
984stateless):
985
986```json
987// ./node_modules/pkg/package.json
988{
989  "type": "module",
990  "exports": {
991    ".": "./index.cjs",
992    "./module": "./wrapper.mjs"
993  }
994}
995```
996
997#### Approach #2: Isolate state
998
999A [`package.json`][] file can define the separate CommonJS and ES module entry
1000points directly:
1001
1002```json
1003// ./node_modules/pkg/package.json
1004{
1005  "type": "module",
1006  "exports": {
1007    "import": "./index.mjs",
1008    "require": "./index.cjs"
1009  }
1010}
1011```
1012
1013This can be done if both the CommonJS and ES module versions of the package are
1014equivalent, for example because one is the transpiled output of the other; and
1015the package's management of state is carefully isolated (or the package is
1016stateless).
1017
1018The reason that state is an issue is because both the CommonJS and ES module
1019versions of the package might get used within an application; for example, the
1020user's application code could `import` the ES module version while a dependency
1021`require`s the CommonJS version. If that were to occur, two copies of the
1022package would be loaded in memory and therefore two separate states would be
1023present. This would likely cause hard-to-troubleshoot bugs.
1024
1025Aside from writing a stateless package (if JavaScript's `Math` were a package,
1026for example, it would be stateless as all of its methods are static), there are
1027some ways to isolate state so that it's shared between the potentially loaded
1028CommonJS and ES module instances of the package:
1029
10301. If possible, contain all state within an instantiated object. JavaScript's
1031   `Date`, for example, needs to be instantiated to contain state; if it were a
1032   package, it would be used like this:
1033
1034   ```js
1035   import Date from 'date';
1036   const someDate = new Date();
1037   // someDate contains state; Date does not
1038   ```
1039
1040   The `new` keyword isn't required; a package's function can return a new
1041   object, or modify a passed-in object, to keep the state external to the
1042   package.
1043
10442. Isolate the state in one or more CommonJS files that are shared between the
1045   CommonJS and ES module versions of the package. For example, if the CommonJS
1046   and ES module entry points are `index.cjs` and `index.mjs`, respectively:
1047
1048   ```cjs
1049   // ./node_modules/pkg/index.cjs
1050   const state = require('./state.cjs');
1051   module.exports.state = state;
1052   ```
1053
1054   ```js
1055   // ./node_modules/pkg/index.mjs
1056   import state from './state.cjs';
1057   export {
1058     state,
1059   };
1060   ```
1061
1062   Even if `pkg` is used via both `require` and `import` in an application (for
1063   example, via `import` in application code and via `require` by a dependency)
1064   each reference of `pkg` will contain the same state; and modifying that
1065   state from either module system will apply to both.
1066
1067Any plugins that attach to the package's singleton would need to separately
1068attach to both the CommonJS and ES module singletons.
1069
1070This approach is appropriate for any of the following use cases:
1071
1072* The package is currently written in ES module syntax and the package author
1073  wants that version to be used wherever such syntax is supported.
1074* The package is stateless or its state can be isolated without too much
1075  difficulty.
1076* The package is unlikely to have other public packages that depend on it, or if
1077  it does, the package is stateless or has state that need not be shared between
1078  dependencies or with the overall application.
1079
1080Even with isolated state, there is still the cost of possible extra code
1081execution between the CommonJS and ES module versions of a package.
1082
1083As with the previous approach, a variant of this approach not requiring
1084conditional exports for consumers could be to add an export, e.g.
1085`"./module"`, to point to an all-ES module-syntax version of the package:
1086
1087```json
1088// ./node_modules/pkg/package.json
1089{
1090  "type": "module",
1091  "exports": {
1092    ".": "./index.cjs",
1093    "./module": "./index.mjs"
1094  }
1095}
1096```
1097
1098## Node.js `package.json` field definitions
1099
1100This section describes the fields used by the Node.js runtime. Other tools (such
1101as [npm](https://docs.npmjs.com/cli/v8/configuring-npm/package-json)) use
1102additional fields which are ignored by Node.js and not documented here.
1103
1104The following fields in `package.json` files are used in Node.js:
1105
1106* [`"name"`][] - Relevant when using named imports within a package. Also used
1107  by package managers as the name of the package.
1108* [`"main"`][] - The default module when loading the package, if exports is not
1109  specified, and in versions of Node.js prior to the introduction of exports.
1110* [`"packageManager"`][] - The package manager recommended when contributing to
1111  the package. Leveraged by the [Corepack][] shims.
1112* [`"type"`][] - The package type determining whether to load `.js` files as
1113  CommonJS or ES modules.
1114* [`"exports"`][] - Package exports and conditional exports. When present,
1115  limits which submodules can be loaded from within the package.
1116* [`"imports"`][] - Package imports, for use by modules within the package
1117  itself.
1118
1119### `"name"`
1120
1121<!-- YAML
1122added:
1123  - v13.1.0
1124  - v12.16.0
1125changes:
1126  - version:
1127    - v13.6.0
1128    - v12.16.0
1129    pr-url: https://github.com/nodejs/node/pull/31002
1130    description: Remove the `--experimental-resolve-self` option.
1131-->
1132
1133* Type: {string}
1134
1135```json
1136{
1137  "name": "package-name"
1138}
1139```
1140
1141The `"name"` field defines your package's name. Publishing to the
1142_npm_ registry requires a name that satisfies
1143[certain requirements](https://docs.npmjs.com/files/package.json#name).
1144
1145The `"name"` field can be used in addition to the [`"exports"`][] field to
1146[self-reference][] a package using its name.
1147
1148### `"main"`
1149
1150<!-- YAML
1151added: v0.4.0
1152-->
1153
1154* Type: {string}
1155
1156```json
1157{
1158  "main": "./index.js"
1159}
1160```
1161
1162The `"main"` field defines the entry point of a package when imported by name
1163via a `node_modules` lookup.  Its value is a path.
1164
1165When a package has an [`"exports"`][] field, this will take precedence over the
1166`"main"` field when importing the package by name.
1167
1168It also defines the script that is used when the [package directory is loaded
1169via `require()`](modules.md#folders-as-modules).
1170
1171```cjs
1172// This resolves to ./path/to/directory/index.js.
1173require('./path/to/directory');
1174```
1175
1176### `"packageManager"`
1177
1178<!-- YAML
1179added:
1180  - v16.9.0
1181  - v14.19.0
1182-->
1183
1184> Stability: 1 - Experimental
1185
1186* Type: {string}
1187
1188```json
1189{
1190  "packageManager": "<package manager name>@<version>"
1191}
1192```
1193
1194The `"packageManager"` field defines which package manager is expected to be
1195used when working on the current project. It can be set to any of the
1196[supported package managers][], and will ensure that your teams use the exact
1197same package manager versions without having to install anything else other than
1198Node.js.
1199
1200This field is currently experimental and needs to be opted-in; check the
1201[Corepack][] page for details about the procedure.
1202
1203### `"type"`
1204
1205<!-- YAML
1206added: v12.0.0
1207changes:
1208  - version:
1209    - v13.2.0
1210    - v12.17.0
1211    pr-url: https://github.com/nodejs/node/pull/29866
1212    description: Unflag `--experimental-modules`.
1213-->
1214
1215* Type: {string}
1216
1217The `"type"` field defines the module format that Node.js uses for all
1218`.js` files that have that `package.json` file as their nearest parent.
1219
1220Files ending with `.js` are loaded as ES modules when the nearest parent
1221`package.json` file contains a top-level field `"type"` with a value of
1222`"module"`.
1223
1224The nearest parent `package.json` is defined as the first `package.json` found
1225when searching in the current folder, that folder's parent, and so on up
1226until a node\_modules folder or the volume root is reached.
1227
1228```json
1229// package.json
1230{
1231  "type": "module"
1232}
1233```
1234
1235```bash
1236# In same folder as preceding package.json
1237node my-app.js # Runs as ES module
1238```
1239
1240If the nearest parent `package.json` lacks a `"type"` field, or contains
1241`"type": "commonjs"`, `.js` files are treated as [CommonJS][]. If the volume
1242root is reached and no `package.json` is found, `.js` files are treated as
1243[CommonJS][].
1244
1245`import` statements of `.js` files are treated as ES modules if the nearest
1246parent `package.json` contains `"type": "module"`.
1247
1248```js
1249// my-app.js, part of the same example as above
1250import './startup.js'; // Loaded as ES module because of package.json
1251```
1252
1253Regardless of the value of the `"type"` field, `.mjs` files are always treated
1254as ES modules and `.cjs` files are always treated as CommonJS.
1255
1256### `"exports"`
1257
1258<!-- YAML
1259added: v12.7.0
1260changes:
1261  - version:
1262    - v14.13.0
1263    - v12.20.0
1264    pr-url: https://github.com/nodejs/node/pull/34718
1265    description: Add support for `"exports"` patterns.
1266  - version:
1267    - v13.7.0
1268    - v12.17.0
1269    pr-url: https://github.com/nodejs/node/pull/29866
1270    description: Unflag conditional exports.
1271  - version:
1272    - v13.7.0
1273    - v12.16.0
1274    pr-url: https://github.com/nodejs/node/pull/31008
1275    description: Implement logical conditional exports ordering.
1276  - version:
1277    - v13.7.0
1278    - v12.16.0
1279    pr-url: https://github.com/nodejs/node/pull/31001
1280    description: Remove the `--experimental-conditional-exports` option. In 12.16.0, conditional exports are still behind `--experimental-modules`.
1281  - version:
1282    - v13.2.0
1283    - v12.16.0
1284    pr-url: https://github.com/nodejs/node/pull/29978
1285    description: Implement conditional exports.
1286-->
1287
1288* Type: {Object} | {string} | {string\[]}
1289
1290```json
1291{
1292  "exports": "./index.js"
1293}
1294```
1295
1296The `"exports"` field allows defining the [entry points][] of a package when
1297imported by name loaded either via a `node_modules` lookup or a
1298[self-reference][] to its own name. It is supported in Node.js 12+ as an
1299alternative to the [`"main"`][] that can support defining [subpath exports][]
1300and [conditional exports][] while encapsulating internal unexported modules.
1301
1302[Conditional Exports][] can also be used within `"exports"` to define different
1303package entry points per environment, including whether the package is
1304referenced via `require` or via `import`.
1305
1306All paths defined in the `"exports"` must be relative file URLs starting with
1307`./`.
1308
1309### `"imports"`
1310
1311<!-- YAML
1312added:
1313 - v14.6.0
1314 - v12.19.0
1315-->
1316
1317* Type: {Object}
1318
1319```json
1320// package.json
1321{
1322  "imports": {
1323    "#dep": {
1324      "node": "dep-node-native",
1325      "default": "./dep-polyfill.js"
1326    }
1327  },
1328  "dependencies": {
1329    "dep-node-native": "^1.0.0"
1330  }
1331}
1332```
1333
1334Entries in the imports field must be strings starting with `#`.
1335
1336Package imports permit mapping to external packages.
1337
1338This field defines [subpath imports][] for the current package.
1339
1340[Babel]: https://babeljs.io/
1341[CommonJS]: modules.md
1342[Conditional exports]: #conditional-exports
1343[Corepack]: corepack.md
1344[ES module]: esm.md
1345[ES modules]: esm.md
1346[Node.js documentation for this section]: https://github.com/nodejs/node/blob/HEAD/doc/api/packages.md#conditions-definitions
1347[Runtime Keys]: https://runtime-keys.proposal.wintercg.org/
1348[WinterCG]: https://wintercg.org/
1349[`"exports"`]: #exports
1350[`"imports"`]: #imports
1351[`"main"`]: #main
1352[`"name"`]: #name
1353[`"packageManager"`]: #packagemanager
1354[`"type"`]: #type
1355[`--conditions` / `-C` flag]: #resolving-user-conditions
1356[`--experimental-default-type`]: cli.md#--experimental-default-typetype
1357[`--no-addons` flag]: cli.md#--no-addons
1358[`ERR_PACKAGE_PATH_NOT_EXPORTED`]: errors.md#err_package_path_not_exported
1359[`esm`]: https://github.com/standard-things/esm#readme
1360[`package.json`]: #nodejs-packagejson-field-definitions
1361[entry points]: #package-entry-points
1362[folders as modules]: modules.md#folders-as-modules
1363[import maps]: https://github.com/WICG/import-maps
1364[load ECMASCript modules from CommonJS modules]: modules.md#the-mjs-extension
1365[loader hooks]: esm.md#loaders
1366[packages folder mapping]: https://github.com/WICG/import-maps#packages-via-trailing-slashes
1367[self-reference]: #self-referencing-a-package-using-its-name
1368[subpath exports]: #subpath-exports
1369[subpath imports]: #subpath-imports
1370[supported package managers]: corepack.md#supported-package-managers
1371[the dual CommonJS/ES module packages section]: #dual-commonjses-module-packages
1372[the full specifier path]: esm.md#mandatory-file-extensions
1373