Node.js9 min read

Node.js Modules: require and module.exports

Master Node.js modules. Understand CommonJS, why modules exist, how require works, and code organization.

Sarah Chen
December 19, 2025
0.0k0

Node.js Modules: require and module.exports

What are Modules?

Modules let you split code into separate files. Each file is a module that can be imported and used in other files.

The Problem: Without Modules

app.js (1000+ lines)
├── Database functions
├── Authentication logic
├── User management
├── Email sending
├── File processing
└── API routes

Problems:
❌ Hard to find code
❌ Hard to maintain
❌ Can't reuse code
❌ Variable name conflicts
❌ Everything in global scope

The Solution: Modules

project/
├── app.js (main file)
├── db.js (database module)
├── auth.js (authentication module)
├── users.js (user module)
├── email.js (email module)
└── routes.js (routes module)

Benefits:
✅ Organized code
✅ Easy to find
✅ Reusable
✅ No name conflicts
✅ Each module has its own scope

How Modules Work

┌─────────────────────────────────┐
│      Module A (math.js)          │
│  ┌──────────────────────────┐   │
│  │ function add()           │   │
│  │ function subtract()      │   │
│  │                          │   │
│  │ module.exports = {       │   │
│  │   add, subtract          │   │
│  │ }                        │   │
│  └──────────────────────────┘   │
└─────────────────────────────────┘
               │
               │ require('./math')
               │
┌──────────────▼────────────────────┐
│      Module B (app.js)            │
│  ┌──────────────────────────┐   │
│  │ const math = require(     │   │
│  │   './math'               │   │
│  │ )                        │   │
│  │                          │   │
│  │ math.add(5, 3)           │   │
│  └──────────────────────────┘   │
└─────────────────────────────────┘

Benefits of Modules

1. Code Organization

Without Modules: 1 file, 1000 lines
With Modules: 10 files, 100 lines each

Much easier to navigate!

2. Reusability

utils.js (shared utilities)
├── Used by app.js
├── Used by routes.js
└── Used by auth.js

Write once, use everywhere!

3. Scope Isolation

math.js:
  const PI = 3.14  // Only in math.js

app.js:
  const PI = 3.14159  // Different variable!

No conflicts!

4. Easier Testing

Test each module independently
math.js → test math.js
auth.js → test auth.js

Why Modules?

Exporting from a Module

Single export:

// greet.js
function greet(name) {
  return `Hello, ${name}!`;
}

module.exports = greet;

Multiple exports:

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

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

module.exports = { add, subtract };
// or
module.exports.add = add;
module.exports.subtract = subtract;

Importing with require

// app.js
const greet = require('./greet');
const { add, subtract } = require('./math');

console.log(greet('Alice'));      // Hello, Alice!
console.log(add(5, 3));           // 8
console.log(subtract(10, 4));     // 6

The ./ Matters!

// Your files - need ./
const myModule = require('./myModule');

// npm packages - no ./
const express = require('express');

// Built-in modules - no ./
const fs = require('fs');

exports vs module.exports

// These are equivalent
exports.add = add;
module.exports.add = add;

// BUT this breaks exports
exports = { add };         // ❌ Won't work
module.exports = { add };  // ✅ Works

Rule: When exporting a single thing or replacing the whole export, use module.exports.

Exporting a Class

// User.js
class User {
  constructor(name) {
    this.name = name;
  }
  
  sayHi() {
    return `Hi, I'm ${this.name}`;
  }
}

module.exports = User;
// app.js
const User = require('./User');
const alice = new User('Alice');
console.log(alice.sayHi());

Module Caching

Modules are cached after first require:

const config1 = require('./config');
const config2 = require('./config');

// config1 === config2 (same object)

Organizing Modules

project/
├── index.js
├── utils/
│   ├── index.js
│   ├── format.js
│   └── validate.js
└── models/
    ├── index.js
    └── User.js
// utils/index.js - re-export everything
module.exports = {
  ...require('./format'),
  ...require('./validate')
};

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

Key Takeaway

CommonJS modules use require to import and module.exports to export. Use ./ for local files, no prefix for packages. This system keeps your code organized and reusable.

#Node.js#Modules#CommonJS#Beginner