Modules & require
As your code grows, you need to split it into files. Modules let you organize code and share functionality between files.
Why Modules?
Imagine a 5,000-line file with everything mixed together:
// nightmare.js - Don't do this!
// Database connection code...
// User authentication...
// Email sending...
// API routes...
// Utility functions...
// More chaos...
With modules, you organize by responsibility:
/project
/src
database.js // Database logic
auth.js // Authentication
email.js // Email utilities
utils.js // Helper functions
app.js // Main entry point
Creating a Module
Create a file called math.js:
// math.js
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
function multiply(a, b) {
return a * b;
}
// Export what you want others to use
module.exports = {
add,
subtract,
multiply
};
Using a Module
Create app.js in the same folder:
// app.js
const math = require('./math');
console.log(math.add(5, 3)); // 8
console.log(math.subtract(10, 4)); // 6
console.log(math.multiply(3, 7)); // 21
Run it:
node app.js
Output:
8
6
21
The require Path Matters
// Local files - use relative paths (start with . or ..)
const math = require('./math'); // same folder
const utils = require('./lib/utils'); // subfolder
const config = require('../config'); // parent folder
// npm packages - just the name (no ./)
const express = require('express');
const lodash = require('lodash');
// Built-in modules - just the name
const fs = require('fs');
const path = require('path');
Common mistake:
// WRONG - Node thinks 'math' is an npm package
const math = require('math');
// CORRECT - ./ tells Node it's a local file
const math = require('./math');
Different Export Styles
Style 1: Export an object// utils.js
module.exports = {
formatDate: (date) => date.toISOString(),
capitalize: (str) => str.charAt(0).toUpperCase() + str.slice(1)
};
// usage
const utils = require('./utils');
utils.formatDate(new Date());
utils.capitalize('hello');
Style 2: Export a single function
// logger.js
module.exports = function log(message) {
console.log(`[${new Date().toISOString()}] ${message}`);
};
// usage
const log = require('./logger');
log('Server started');
Style 3: Export a class
// User.js
class User {
constructor(name, email) {
this.name = name;
this.email = email;
}
greet() {
return `Hello, I'm ${this.name}`;
}
}
module.exports = User;
// usage
const User = require('./User');
const alice = new User('Alice', 'alice@example.com');
console.log(alice.greet());
Destructuring Imports
If you only need specific exports:
// Instead of this:
const math = require('./math');
const result = math.add(1, 2);
// You can do this:
const { add, multiply } = require('./math');
const result = add(1, 2);
Built-in Modules
Node.js comes with useful modules built-in:
// File system
const fs = require('fs');
// Path utilities
const path = require('path');
// Operating system info
const os = require('os');
// HTTP server/client
const http = require('http');
// Cryptography
const crypto = require('crypto');
Quick example with path:
// path-demo.js
const path = require('path');
const filePath = '/users/alice/documents/report.pdf';
console.log(path.basename(filePath)); // report.pdf
console.log(path.dirname(filePath)); // /users/alice/documents
console.log(path.extname(filePath)); // .pdf
// Join paths safely (handles / automatically)
const newPath = path.join('users', 'bob', 'file.txt');
console.log(newPath); // users/bob/file.txt
Try It Yourself
Create a mini project with multiple modules:
strings.js:// strings.js
module.exports = {
reverse: (str) => str.split('').reverse().join(''),
isPalindrome: (str) => {
const clean = str.toLowerCase().replace(/[^a-z]/g, '');
return clean === clean.split('').reverse().join('');
}
};
numbers.js:
// numbers.js
module.exports = {
isEven: (n) => n % 2 === 0,
factorial: (n) => n <= 1 ? 1 : n * factorial(n - 1)
};
main.js:
// main.js
const strings = require('./strings');
const numbers = require('./numbers');
console.log(strings.reverse('hello')); // olleh
console.log(strings.isPalindrome('racecar')); // true
console.log(numbers.isEven(4)); // true
console.log(numbers.factorial(5)); // 120
Run it:
node main.js
ES Modules (Quick Note)
Node.js also supports the newer import/export syntax:
// math.mjs (note .mjs extension)
export function add(a, b) {
return a + b;
}
// app.mjs
import { add } from './math.mjs';
console.log(add(1, 2));
For now, we'll use require() (CommonJS) as it's still the most common in Node.js tutorials and existing code.
Key Takeaways
- Modules split code into organized files
- module.exports defines what a file shares
- require('./file') imports local files (note the
./) - require('package') imports npm packages
- Built-in modules like
fs,path,httpcome with Node.js
Next, let's explore npm and the world of packages!