How does the Node.js module system work?
Tags: node, javascript, npm
Published: 2021-07-05 10:59:40

---
title: How does the Node.js module system work?
published: true
date: 2021-03-23 00:00:00 UTC
tags: node, javascript, npm
canonical_url: https://www.mariokandut.com/how-does-the-node-js-module-system-work/
---

Modules are building blocks of code structures and allow Node.js developers to better structure, reuse, and distribute code. A module is a **self-contained code block** in a file or in a directory, which then can be included wherever we need it. Modules and the module system are fundamental parts of how Node.js applications are written and structured.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#the-nodejs-module-system)The Node.js Module System

The module system from Node.js helps to write reusable code, but what is a module and how can it be created or imported?

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#what-is-a-module)What is a module?

**A module is a unit of code** , organized into a file or folder. In a module functionality is exported so that it can be included in other parts. In Node.js, each file has a global object in its scope called `module`. This module holds information about that specific file. The module variable is an object, which has a property called exports.

Assigning values to module.exports will expose them for importing in other parts of the application. Modules can be reused where needed and help to organize the applications codebase. Creating modules for specific tasks helps to maintain clean code.

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#types-of-modules)Types of Modules

Node.js has three types of modules:

- Built-in modules
- Local modules
- External modules

#### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#built-in-modules)Built-in modules

- Built-in modules are distributed with Node.js itself. No separate installation required.
- You load them using `require`.
- These built-in modules make up the standard library of Node.js.
- The built-in modules of Node.js are developed by the core Node.js team, and are part of the language itself.

#### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#local-modules)Local modules

- These are modules you write yourself, they are part of your actual codebase and are checked into version control.
- Local modules are how to reuse code in your project.
- An example would be creating a file for utilities. You can then export code from that file to be used in different parts of your application.

#### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#external-modules)External modules

- External modules are basically NPM packages.
- An external module is installed as a dependency, tracked in your package.json, and located in the node\_modules/ directory.
- The actual code of an external module is not checked into version control, since the reference is tracked with the `package.json` file.

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#how-to-use-the-module-system)How to use the module system?

With modules the code can be broken up into smaller chunks and organized by functionality. The module system lets you encapsulate a unit of code and expose it to be reused by other parts of your application. This is done by assigning values to the file's `module.exports` object. The module system extends the `CommonJS` standard. Starting with Node.js v16 the ESM (EcmaScript Modules) are used, see [docs](https://nodejs.org/api/esm.html#esm_modules_ecmascript_modules).

> In the early days of Node.js, there was no explicit module system that the language used, so CommonJS was adopted and extended to fill the gap and set forth a standard the community can use. If the NPM registry is the heart of the Node.js ecosystem, then CommonJS and the module system are the backbone.

Let's export a simple function from a module:

```
// math.js
const multiplyByTwo = function(x) {
  return x * 2;
};

module.exports = multiplyByTwo;
```

In the example above, we have exported a single function from a file called `math.js`, by assigning the function to `module.exports`.

In any given file, we can assign a value to `module.exports`, and then include that value elsewhere by passing the file's path to the `require` function. The require function loads a file or package and returns the value assigned to module.exports.

For example, we want to use the function from the above module:

```
// index.js
const multiplyByTwo = require('./math.js');

console.log(multiplyByTwo(10));
// 20
```

Multiple values can be assigned to `module.exports` :

```
// mathFunctions.js
const add = function(x, y) {
  return x + y;
};
const subtract = function(x, y) {
  return x - y;
};
const multiplyByTwo = function(x) {
  return x * 2;
};

module.exports = {
  add,
  subtract,
  multiplyByTwo,
};
```

Another way to export values is to use the global object `exports`, which is available in each file, but it is an alias of `module.exports`.

```
// mathFunctions.js
exports.add = function(x, y) {
  return x + y;
};
exports.subtract = function(x, y) {
  return x - y;
};
exports.multiplyByTwo = function(x) {
  return x * 2;
};
```

**Important:** Don't mix the `exports` and `module.exports` usages, it might result in a loss of the previous used reference.

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#what-is-require)What is require?

Exporting code using `module.exports` is only half of the module system. You need a way to import the code in other parts of the application. You can do that with the `require` function.

In order to load a **local module** , we pass its **relative file path** to the require function, which returns the value of `module.exports` from the file. When requiring an **npm package** , the name of the package is passed to the `require` function, and the same thing is happening in `the node_modules/` folder

A module is **evaluated the first time** it is passed to the require function. The code in the file will be wrapped in a private scope, run, and the value of module.exports is returned by require. After that, (the module has been required once) **the module is cached** , and requiring the file again will return the cached result, without evaluating the file again.

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#import-and-export-ecmascript-modules)import and export (ECMAScript Modules)

The **ESM (EcmaScript Modules)** uses `import` and `export` keywords when dealing with modules. This is available in the current version of Node.js (v.16). If you are below this Node.js version you can use a transpiler like Babel to convert ESM import and export code into regular CommonJS format through adding a build step to the project.

When developing applications for the frontend, it's standard to use something like Babel to transpile your code to make it compatible with as many browsers as possible. So the import and export syntax can be safely used, because the code is replaced before put into production. But when developing for the backend, there is usually no need for transpilation, because the environment is controlled by the developers, not like the different browsers.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#tldr)TL;DR

- The module system helps us reuse code throughout our application.
- A module is a self-contained file or directory of related code.
- There are three main types of modules: built-in, local and external
- Using the global `module` object or the `exports` object, we can export code from a file to use elsewhere, while keeping some parts of the module encapsulated in their own private scope.
- Project-agnostic modules can be published to the NPM registry as packages for reuse across projects.

Thanks for reading and if you have any **questions** , use the **comment** function or **send me a message** **[@mariokandut](https://www.twitter.com/mariokandut)**.

If you want to know more about **[Node](https://www.mariokandut.com/tags/node)**, have a look at these [Node Tutorials](https://www.mariokandut.com/tags/node).

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#references-and-big-thanks)References (and Big thanks):

[NPM modules](https://docs.npmjs.com/about-packages-and-modules#about-modules),[HeyNode](https://heynode.com/tutorial/set-and-test-dot-env-env-file/),[CommonJS](https://requirejs.org/docs/commonjs.html)[NodeJS - ESM](https://nodejs.org/api/esm.html#esm_modules_ecmascript_modules)