Language: EN


What are and how to use modules in Node.js

We have seen that Node.js is compatible with files with the extensions .js and .mjs. If it seems a bit confusing, hold on because here comes the hard part I’ll explain it to you right now.

CommonJS and ECMAScript Modules (ESM) are two module systems used in JavaScript to organize and reuse code in different files.

In summary, modules are a way to export the code from a file so that it can be used by other files.

When Node.js appeared (2009), JavaScript did not have a native module system. Node.js decided to create its own, CommonJS. A decision that we continue to carry to this day.

Later, JavaScript creates its “official” file system, ECMAScript Modules (ESM) (2015). They were a bit behind. But the official syntax had many improvements over the previous ones.

You might say, well… “everything is perfect, we leave CommonJS and use ESM!“. By that time there was so much code that it has taken years to replace them.

In fact, Node.js took until version 12 (2019) to be compatible with ESM. That’s 10 years of CommonJS. So there are still many tools and libraries that have not been ported.

That’s why there are two extensions:

  • .js works with CommonJS modules 🤔
  • .mjs works with ECMAScript Modules (ESM) 👍

Whenever possible, use ECMAScript Modules (ESM). They are the standard solution, and should replace CommonJS.

Using modules in JavaScript

Let’s see how to use CommonJS and ECMAScript Modules. As I said, unless some library is not compatible, or some other compelling reason, prefer the second.

But let’s see the syntax of both, because you will find half of the internet documentation, libraries, or projects you have to work on, in each system.

CommonJS Legacy

CommonJS is a module system that was developed for use in server environments, such as Node.js. It uses the keywords require and module.exports to import and export modules.

Here is an example of its use.

// Import a module
const anotherModule = require('./anotherModule');

// Export a module
module.exports = {
  foo: 'bar'

Node.js has used CommonJS as its main module system for a long time.

ECMAScript Modules (ESM) Standard

ECMAScript Modules are the standard JavaScript module system defined in the ECMAScript standard (the underlying standard of JavaScript). It uses the keywords import and export to import and export modules, respectively.

Example of its use:

// Import a module
import anotherModule from './anotherModule';

// Export a module
export const foo = 'bar';

ECMAScript modules are designed to work both in modern web browsers and server environments (such as Node.js), which means they are more portable.

In addition, ECMAScript modules are loaded asynchronously, which can be more efficient in certain scenarios.

JS and MJS extensions

Before the adoption of ECMAScript modules in Node.js, JavaScript files were written with the extension .js and used CommonJS for importing and exporting code.

From Node.js v12, support for ECMAScript modules was introduced, allowing the use of the same import/export syntax used in modern web browsers.

Since the “good” extension was already taken, they had to call it .mjs. To create an .mjs file, simply name it with that extension, for example: file.mjs. Nothing else is needed.

Both module systems can coexist in the same project. In general, it’s not a good idea. If you can avoid it, better. Although if you can’t, because you would have to rewrite 300 libraries… take a deep breath.

Finally, to convert a .js file to .mjs, you just have to change the extension, and change the require to imports, and the module.exports to exports. But all the libraries and files you use have to be compatible with ECMAScript themselves.