DEV Community

Yogesh Bamanier
Yogesh Bamanier

Posted on

Node.js module.exports Explained: Complete Guide for Developers πŸš€

Understanding module.exports in Node.js: A Complete Guide πŸš€

When I was reading through a some.config.js file in a project, I came across this line:

module.exports = { ... }; 
Enter fullscreen mode Exit fullscreen mode

At first glance, it looked ordinary. But then I asked myself:
πŸ‘‰ How does module.exports really work in Node.js?

This question sent me on a deep dive into Node’s module system β€” from how files are wrapped, to how require() works, and how exports differs from module.exports.
Here’s what I learned (and what every JavaScript/Node developer should know) πŸ‘‡


πŸ”Ή What is module.exports in Node.js? πŸ’‘

In Node.js, every file is treated as a module.
When Node loads a file, it doesn’t run it directly. Instead, it wraps your code like this:

(function (exports, require, module, __filename, __dirname) { // your file content }); 
Enter fullscreen mode Exit fullscreen mode

This wrapper gives each file access to:

  • exports
  • require
  • module
  • __filename
  • __dirname

That’s why you can use module.exports anywhere in your file without explicitly importing it.


πŸ”Ή The Relationship Between exports and module.exports πŸ”„

At the beginning of every module, Node does this:

exports = module.exports = {}; 
Enter fullscreen mode Exit fullscreen mode

This means:

  • exports is just a reference to module.exports.
  • By default, both point to the same object.
  • Whatever you add to either (without reassigning) will be exported.

βœ… Example:

exports.a = 10; // works module.exports.b = 20; // works 
Enter fullscreen mode Exit fullscreen mode

Result:

{ a: 10, b: 20 } 
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή The Common Mistake ⚠️

If you reassign exports, you break the link:

// ❌ Won't work exports = function () {  console.log("Hello"); }; 
Enter fullscreen mode Exit fullscreen mode

Now exports points to a new function, but module.exports is still {}.
So nothing gets exported.

βœ… Correct way:

module.exports = function () {  console.log("Hello"); }; 
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή How Does require() Work? πŸ”

When you write:

const myModule = require("./myModule"); 
Enter fullscreen mode Exit fullscreen mode

Here’s the behind-the-scenes flow:

  1. Node resolves the file path (./myModule.js)
  2. Checks the module cache (modules load once per runtime)
  3. Wraps and executes the file inside the function wrapper
  4. Returns module.exports

πŸ’‘ That’s why require() always gives you module.exports β€” not exports.


πŸ”Ή Example: Using module.exports in Practice πŸ“

// user.js module.exports = {  name: "Yogesh", greet() { console.log(`Hello, ${this.name}`); } }; 
Enter fullscreen mode Exit fullscreen mode
// app.js const user = require("./user");  console.log(user.name); // Yogesh user.greet(); // Hello, Yogesh 
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή CommonJS vs ES Modules (CJS vs ESM) ⚑

Modern Node.js supports both CommonJS (CJS) and ES Modules (ESM).

βœ… CommonJS (default in Node)

// math.js module.exports = {  add: (a, b) => a + b };  // app.js const math = require("./math"); console.log(math.add(2, 3)); 
Enter fullscreen mode Exit fullscreen mode

βœ… ES Modules (modern JS standard)

// math.mjs export function add(a, b) {  return a + b; }  // app.mjs import { add } from "./math.mjs"; console.log(add(2, 3)); 
Enter fullscreen mode Exit fullscreen mode

πŸ”‘ Key differences:

  • Syntax β†’ module.exports vs export / import
  • Loading β†’ CommonJS is synchronous; ES Modules are asynchronous
  • Exports β†’ CommonJS typically exports a single object; ESM supports multiple named exports
  • Future-proofing β†’ ESM is the official JavaScript standard, better for modern apps

πŸ”Ή Best Practices βœ…

  • Use exports.x = … for adding multiple exports
  • Use module.exports = … when exporting one main thing (function, class, or object)
  • Prefer ES Modules (import/export) in new projects if supported

✨ Conclusion

That little module.exports line in some.config.js turned out to be a doorway into Node.js internals.

What looks simple β€”

module.exports = { ... }; 
Enter fullscreen mode Exit fullscreen mode

β€” is backed by a powerful module system that:

  • Wraps files in functions
  • Links exports and module.exports
  • Returns only module.exports through require()
  • Supports both CommonJS and ES Modules

Next time you use module.exports, remember:
It’s not just boilerplate β€” it’s the heart of how Node.js manages modules.


✍️ Written by Yogesh Bamanier
πŸ”— LinkedIn

Top comments (0)