Understanding Node.js Modules and require()

Modules are the building blocks of any Node.js application. They help you organize your code into reusable, maintainable, and encapsulated components. In this article, we’ll explore how the Node.js module system works, how to create your own modules, and how to use the require() function to import them.


Table of Contents

  1. What Are Modules in Node.js?
  2. Types of Modules in Node.js
  3. Using the require() Function
  4. Creating Custom Modules
  5. Exporting Multiple Values
  6. Caching Behavior of Modules
  7. The module and exports Objects
  8. ES Modules vs CommonJS
  9. Real-World Use Cases
  10. Conclusion

1. What Are Modules in Node.js?

In Node.js, every file is treated as a separate module. This means you can encapsulate functions, variables, and logic into files and reuse them elsewhere. The Node.js module system is based on CommonJS, which uses require() and module.exports to manage modules.


2. Types of Modules in Node.js

Node.js supports three types of modules:

  • Core Modules: Built-in modules like fs, http, path, etc.
  • Local Modules: Custom modules you create in your application.
  • Third-party Modules: External libraries installed via npm (e.g., express, lodash).

3. Using the require() Function

You use require() to import modules:

const fs = require('fs'); // core module
const math = require('./math'); // local module
const express = require('express'); // npm module

4. Creating Custom Modules

Let’s say you create a math.js file:

// math.js
function add(a, b) {
return a + b;
}

function subtract(a, b) {
return a - b;
}

module.exports = {
add,
subtract
};

Now you can import and use it in another file:

// app.js
const math = require('./math');

console.log(math.add(2, 3)); // Output: 5
console.log(math.subtract(7, 4)); // Output: 3

5. Exporting Multiple Values

You can export functions, objects, or variables individually:

// logger.js
exports.info = (msg) => console.log(`INFO: ${msg}`);
exports.warn = (msg) => console.log(`WARNING: ${msg}`);

Or as a single object:

// logger.js
const logger = {
info: (msg) => console.log(`INFO: ${msg}`),
warn: (msg) => console.log(`WARNING: ${msg}`)
};

module.exports = logger;

6. Caching Behavior of Modules

Node.js caches required modules, meaning it loads them only once:

const a = require('./moduleA');
const b = require('./moduleA');

console.log(a === b); // true — same object due to caching

To reload a module, you’d have to delete it from the cache manually (not recommended in most use cases).


7. The module and exports Objects

Every module in Node.js has a module object and an exports object. They work together like this:

console.log(module.exports === exports); // true initially

You can assign to module.exports to change what gets exported, or add properties to exports.

Avoid assigning directly to exports = ... because it breaks the reference.

8. ES Modules vs CommonJS

Modern Node.js supports ES modules using import/export. To use them:

  • Use .mjs file extension or set "type": "module" in package.json.

Example:

// add.mjs
export function add(a, b) {
return a + b;
}
// main.mjs
import { add } from './add.mjs';
console.log(add(1, 2)); // Output: 3

ES Modules are preferred in modern JavaScript projects, but CommonJS is still widely used.


9. Real-World Use Cases

  • Organizing utility functions into separate files
  • Grouping API routes into modular files in Express apps
  • Wrapping third-party libraries for internal use
  • Managing services like database connections, logging, etc.

10. Conclusion

Node.js modules help structure your application cleanly and effectively. Whether you’re using CommonJS with require() or moving toward ES Modules with import/export, mastering modules is essential for building scalable Node.js applications.