Node.js 13.2.0 comes with ECMAScript support for modules known for their import and export syntax.  Previously, this functionality was behind the --experimental-modules
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     flag, which is no longer required.  However, the implementation is still experimental and is subject to change. 
From a translator: this long-awaited feature will finally allow us to use the standard modular syntax already available in modern browsers, and now also in Node.js without flags and transpilers
Activation
Node.js will process the code as ES modules in the following cases:
-   Files with the 
.mjs
extension -   Files with the 
.js
extension or without the extension at all, provided that the parentpackage.json
closest to them contains the value"type": "module"
 -   Code passed through the 
—-eval
or STDIN argument, along with the—-input-type=module
flag 
  In all other cases, the code will be considered CommonJS.  This applies to .js
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     files without "type": "module"
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     in the nearest package.json
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     and to the code passed through the command line without specifying --input-type
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     .  This is done in order to maintain backward compatibility.  However, since we now have two kinds of modules, CommonJS and ES, it will be better to specify the type of modules explicitly. 
You can explicitly mark your code as CommonJS with the following features:
-   Files with the 
.cjs
extension -   Files with the extension 
.js
or without extension at all, provided that the closest parentpackage.json
contains the value"type": "“commonjs”"
 -   Code passed via the 
--eval
or STDIN argument with the explicit flag--input-type=commonjs
 
  To learn more about these features, see the "Package Scope and File Extensions" documentation sections and   --input-type
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
Syntax import and export
  In the context of the ES module, you can use import
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     , pointing to other Javascript files.  They can be specified in one of the following formats: 
-   Relative URL: 
"./file.mjs"
 -   Absolute URL c 
file://
, for example,"file:///opt/app/file.mjs"
 -   Package Name: 
"es-module-package"
 -   The path to the file inside the package: 
"es-module-package/lib/file.mjs"
 
  In imports, you can use default ( import _ from "es-module-package"
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     ) and named values ( import { shuffle } from "es-module-package"
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     ), as well as import everything as one namespace ( import * as fs from "fs"
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     ).  All built-in Node.js packages, like fs
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     or path
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     , support all three types of imports. 
  Imports that point to CommonJS code (that is, all current JavaScript written for Node.js  require
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     and module.exports
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     ) can only use the default option ( import _ from "commonjs-package"
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     ). 
  Importing other file formats such as JSON and WASM remains experimental, and requires the flags --experimental-json-modules
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     and --experimental-wasm-modules
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     respectively.  However, you can download these files using the module.createRequire
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     API, which is available without additional flags. 
In your ES modules, you can use the export keyword to export default and named values.
  Dynamic expressions with import()
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     can be used to load ES modules from either CommonJS or ES code.  Note that import()
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     does not return a module but its promise (Promise). 
  import.meta.url
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     is import.meta.url
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     available in the modules, which contains the absolute URL of the current ES module. 
Files and the new "type" field in package.json
  Add "type": "module"
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     to the package.json of your project, and Node.js will begin to perceive all .js
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     files of your project as ES modules. 
  If some files of your project still use CommonJS and you cannot migrate the whole project at once, you can either use the .cjs
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     extension for this code, or put it in a separate directory and add package.json
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     containing { "type": "commonjs" }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     , which tells Node.js that it should be treated as CommonJS. 
  For each downloaded file, Node.js will look at package.json
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     in the directory containing it, then one level up, and so on until it reaches the root directory.  This mechanism is similar to how  Babel  .babelrc
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     files .  This approach allows Node.js to use package.json
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     as a source of various metadata about the package and configuration, similar to how it already works in Babel and other tools. 
  We recommend that all package developers specify a type
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     field, even if commonjs
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     is written commonjs
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     . 
Package entry points and the "exports" field in package.json
  Now we have two fields for specifying the entry point into the package: main
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     and exports
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     .  The main
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     field is supported by all versions of Node.js, but its capabilities are limited: with it you can define only one main entry point in the package.  The new exports
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     field also allows you to define the main entry point, as well as additional paths.  This gives additional encapsulation for packages where only the explicit exports
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     paths are available for import from outside the package.  exports
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     applies to both types of modules, CommonJS and ES, it doesn't matter if they are used through require
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     or import
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     . 
  This functionality will allow pkg/feature
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     type imports to point to a real path like ./node_modules/pkg/esm/feature.js
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     .  Also, Node.js will throw an error if the import refers to pkg/esm/feature.js
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     which is not specified in exports
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     . 
  An additional, still experimental, feature, conditional exports provides the ability to export different files for different environments.  This will allow the package to give CommonJS code to call require("pkg")
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     and the ES module code to import through import "pkg"
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     , although writing such a package is not without other problems .  You can enable conditional exports with the —-experimental-conditional-exports
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     flag. 
The main rake of the new modules
Required file extensions
When using imports, you must specify the file extension. When importing an index file from a directory, you must also completely specify the path to the file, that is, "./startup/index.js".
This behavior coincides with how imports work in browsers when accessing a regular server without additional configuration.
  module.exports
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     , exports
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     , module.exports
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     , __filename
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     , __dirname
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
        These values from CommonJS are not available in the context of ES modules.  However, require
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     can be imported into an ES module through module.createRequire()
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     .  The equivalents __filename
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     and __dirname
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     can be obtained from import.meta.url
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     . 
Creating packages
At the moment, we recommend that package authors use either fully CommonJS or fully ES modules for their Node.js projects. The module working group for Node.js continues to look for ways to improve support for dual packages, with CommonJS for legacy users and ES modules for new ones. Conditional exports are now experimental and we hope to roll out this functionality or its alternative by the end of January 2020, or even earlier.
To learn more about this, see our examples and recommendations for creating dual CommonJS / ES Module packages.
What will happen next
  Loaders.  Work continues on the API for writing custom loaders, for implementing module transpilation in runtime, redefining import paths (packages or individual files), and also instrumentation of code.  The experimental API, accessible under the —-experimental-loader
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     flag, will be subject to significant alterations before we remove it from the flag. 
  Dual CommonJS / ES module packages.  We want to provide a standard way to publish a package that can be used both through require
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     in CommonJS and through import
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     in ES modules.  We have more information about this in the documentation .  We plan to complete the work and withdraw from the flag by the end of January 2020, if not earlier. 
That's all! We hope ECMAScript module support brings Node.js closer to JavaScript standards and brings new compatibility features across the JavaScript ecosystem. The workflow for improving module support is being done publicly here: https://github.com/nodejs/modules .