Esmodules in Node

last updated Feb 28, 2021


With the introduction of Nodejs in May of 2009 it’s module system was CommonJS by default. It was created in January of 2009 to address the lack of a standard way for structuring and organizing JavaScript codes. ever since then it was the standard that Nodejs uses when working with modules.

//CommonJS code example
var file = require('./file_path');

function sayHello() {

exports.sayHello = sayHello;

ESModule is a new standard way of writing modular JavaScript code, It’s proposal was approved in June of 2015 (ES2015), It was added into node in the january of 2017 in experimental where you could use them by running nodejs and add --experimental flag to make it work.

//ESM code example
import file from 'file_path';

export function sayHello() {

ESModules Vs CommonJS

  1. EsModule have a declarative syntax (for importing and exporting) while commonjs use require syntax

  2. EsModules can be statically Imported.

    In CommonJS You don’t load a module you execute a module. while in esm modules are parsed.

  3. EsModules are asynchronous

This simply means that with many imports loading, parsing, binding can happen concurrently before execution stats. While in CommonJS loading execution happens at the sometime so it is synchronous.

  1. EsModules Supports top level await outside of async which can be help full to asynchronously read a file or a conditional import. this feature is available in node v13.3+
const getData = await import(`/path/another_path`);
  1. ESM imports are static by default

    Imported modules are in strict mode

  2. To use esm you have to add extension in node to make compatibility with browser

You might be thinking that why es modules while Babel already does the same thing, the answers is no. Babel does a good job at transpiring JavaScript code but it’s different from esmodules. since it uses the node.js module resolution.

ESM vs Babel

  1. ESM is browser compatible but Babel’s transpiration is not because it uses nodejs module system which is CommonJS and CommonJS doesn’t run in browser.
  2. ESM is statically parsed, Babel transpiration is not. Esmodules is statically parsed while Babel’s transpired is is parsed and executed at the same time.
  3. ESM is async and Supports top level await, Babel transpiration is not and doesn’t.
  4. ESM is native, Babel is a transpiration.

How to use ESmodules

Currently all major Browsers supports ESModules natively, so there is no need to load a big, giant bundled file which can make the performance slow. you can split it into small pieces. using esmodules will make browsers loading each module as needed. which can make your applications faster. to use esmodules in Browsers all you need todo is adding type="module" in script tag

<script type="module" src="file_path"></script>

In node to use esmodules is Simple make sure you are running node v12.0 or higher and in package.json add a property called type with it’s value. That’s it you don’t have to do any thing else every feature of esmodules should work.

	type: 'module';

If you are Using TypeScript in your workflow, you can configure the compiler to output ESmodules, to do so all you need to do is adding module:ES2020 in tsconfig.json. ES2020 simply means ECMAScript corresponding to the year 2020. You can rollback or go to future version of ECMAScript by simply writing ES+any year as long as that version exists.

  "compilerOptions": {
    "target": "ES2015",
    "module": "ES2020",
    "strict": true,