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