Node 13.2.0 & Above
NodeJS 13.2.0 now supports ES Modules without a flag ???? However, the implementation is still marked as experimental so use in production with caution.
To enable ESM support in 13.2.0, add the following to your
.mjs (or files without an extension) will be treated as ESM.
There are a number of different options other than entire
package.json opt-in, all of which are detailed in the Documentation for 13.2.0.
Node 13.1.0 & Below
Those still using older versions of Node may want to try the esm module loader, which is a production-ready implementation of the ES Modules Spec for NodeJS:
node -r esm main.js
23 April 2019
A PR recently landed to change the way ES Modules are detected:
It's still behind the
--experimental-modules flag, but there are major changes in the way modules can be loaded:
package.type which can be either
.js is parsed as commonjs
- default for entry point without an extension is commonjs
.js is parsed as esm
- does not support loading JSON or Native Module by default
- default for entry point without an extension is esm
--type=[mode] to let you set the type on entry point. Will override
package.type for entry point.
- A new file extension
- this is specifically to support importing commonjs in the
- this is only in the esm loader, the commonjs loader remains untouched, but the extension will work in the old loader if you use the full file path.
- options are
explicit (default) and
- by default our loader will not allow for optional extensions in the import, the path for a module must include the extension if there is one
- by default our loader will not allow for importing directories that have an index file
- developers can use
--es-module-specifier-resolution=node to enable the commonjs specifier resolution algorithm
- This is not a “feature” but rather an implementation for experimentation. It is expected to change before the flag is removed
- the only way to import json when
- when enable all
import 'thing.json' will go through the experimental loader independent of mode
- based on whatwg/html#4315
- You can use
package.main to set an entry point for a module
- the file extensions used in main will be resolved based on the type of the module
17 January 2019
Node 11.6.0 still lists ES Modules as experimental, behind a flag.
13 September 2017
NodeJS 8.5.0 has been released with support for mjs files behind a flag:
node --experimental-modules index.mjs
The plan for this is to remove the flag for the v10.0 LTS release.
--Outdated Information. Kept here for historical purposes--
8 September 2017
NodeJS master branch has been updated with initial support for ESM modules:
This should be available in the latest nightly (this can be installed via nvm to run alongside your existing install):
And enabled behind the
"main": "index.mjs" <-- Set this to be an mjs file
node --experimental-modules .
The NodeJS guys have decided that the least bad solution is to use the
.mjs file extension. The takeaway from this is:
In other words, given two files
bar.mjs , using
from 'foo' will treat
foo.js as CommonJS while
import * from 'bar'
bar.mjs as an ES6 Module
And as for timelines...
At the current point in time, there are still a number of
specification and implementation issues that need to happen on the ES6
and Virtual Machine side of things before Node.js can even begin
working up a supportable implementation of ES6 modules. Work is in
progress but it is going to take some time?—?We’re currently looking
at around a year at least.
One of the developers on Node.JS recently attended a TC-39 meeting and wrote up a superb article on the blockers to implementing for Node.JS:
The basic take-away from that is:
- ES Modules are statically analyzed, CommonJS are evaluated
- CommonJS modules allow for monkey-patching exports, ES Modules currently do not
- It's difficult to detect what is an ES Module and what is CommonJS without some form of user input, but they are trying.
*.mjs seems the most likely solution, unless they can accurately detect an ES Module without user-input
-- Original Answer --
This has been a hot potato for quite some time. Bottom line is that yes, Node will eventually support the ES2015 syntax for importing/exporting modules - most likely when the spec for loading modules is finalized and agreed upon.
Here is a good overview of what's holding NodeJS up. Essentially, they need to make sure that the new spec works for Node which is primarily conditional, synchronous loading and also HTML which is primarily asynchronous.
Nobody knows for sure right now, but I imagine Node will support
import/export for static loading, in addition to the new
System.import for dynamic loading - while still keeping
require for legacy code.
Here's a few proposals on how Node might achieve this: