Node.js & Express

Node.js Core Modules

30 min Lesson 3 of 40

Node.js Core Modules

Node.js comes with a rich set of built-in modules (also called core modules) that provide essential functionality for building applications. These modules are part of the Node.js standard library and don't require installation—they're available out of the box. In this lesson, we'll explore the most important core modules and learn how to use them effectively.

What Are Core Modules?

Core modules are pre-compiled C/C++ and JavaScript libraries that come bundled with Node.js. They provide low-level APIs for common tasks like file system operations, networking, cryptography, and more.

Key Characteristics:
  • Built into Node.js (no installation needed)
  • Optimized for performance
  • Maintained by the Node.js team
  • Stable and well-documented
  • Loaded using require() or import

Loading Core Modules

// CommonJS (traditional Node.js) const fs = require('fs'); const path = require('path'); const http = require('http'); // ES Modules (modern JavaScript) import fs from 'fs'; import path from 'path'; import http from 'http'; // Import specific functions import { readFile, writeFile } from 'fs'; import { join, resolve } from 'path';

1. File System Module (fs)

The fs module provides APIs for interacting with the file system—reading, writing, updating, and deleting files and directories.

Reading Files

const fs = require('fs'); // Asynchronous (non-blocking) - recommended fs.readFile('example.txt', 'utf8', (err, data) => { if (err) { console.error('Error reading file:', err); return; } console.log('File content:', data); }); // Synchronous (blocking) - use sparingly try { const data = fs.readFileSync('example.txt', 'utf8'); console.log('File content:', data); } catch (err) { console.error('Error reading file:', err); } // Promise-based (modern approach) const fsPromises = require('fs').promises; async function readFileAsync() { try { const data = await fsPromises.readFile('example.txt', 'utf8'); console.log('File content:', data); } catch (err) { console.error('Error reading file:', err); } }
Best Practice: Always use asynchronous methods (readFile) or promise-based APIs in production to avoid blocking the event loop. Use synchronous methods (readFileSync) only during initialization or in CLI tools.

Writing Files

const fs = require('fs'); // Write string to file (overwrites existing content) fs.writeFile('output.txt', 'Hello Node.js!', 'utf8', (err) => { if (err) { console.error('Error writing file:', err); return; } console.log('File written successfully'); }); // Append to file fs.appendFile('log.txt', 'New log entry\n', (err) => { if (err) throw err; console.log('Log entry added'); }); // Write JSON data const data = { name: 'John', age: 30 }; fs.writeFile('data.json', JSON.stringify(data, null, 2), 'utf8', (err) => { if (err) throw err; console.log('JSON file saved'); });

Working with Directories

const fs = require('fs'); // Create directory fs.mkdir('uploads', { recursive: true }, (err) => { if (err) throw err; console.log('Directory created'); }); // Read directory contents fs.readdir('./', (err, files) => { if (err) throw err; console.log('Files in directory:', files); }); // Check if file/directory exists fs.access('example.txt', fs.constants.F_OK, (err) => { if (err) { console.log('File does not exist'); } else { console.log('File exists'); } }); // Get file/directory information fs.stat('example.txt', (err, stats) => { if (err) throw err; console.log('Is file:', stats.isFile()); console.log('Is directory:', stats.isDirectory()); console.log('Size:', stats.size, 'bytes'); console.log('Modified:', stats.mtime); });

2. Path Module (path)

The path module provides utilities for working with file and directory paths in a cross-platform way.

const path = require('path'); // Join path segments const fullPath = path.join('/users', 'john', 'documents', 'file.txt'); console.log(fullPath); // /users/john/documents/file.txt // Resolve absolute path const absolutePath = path.resolve('files', 'data.txt'); console.log(absolutePath); // /current/working/directory/files/data.txt // Get file extension const ext = path.extname('document.pdf'); console.log(ext); // .pdf // Get file name const fileName = path.basename('/path/to/file.txt'); console.log(fileName); // file.txt // Get file name without extension const name = path.basename('/path/to/file.txt', '.txt'); console.log(name); // file // Get directory name const dirName = path.dirname('/path/to/file.txt'); console.log(dirName); // /path/to // Parse path into object const parsed = path.parse('/home/user/file.txt'); console.log(parsed); // { // root: '/', // dir: '/home/user', // base: 'file.txt', // ext: '.txt', // name: 'file' // } // Build path from object const formatted = path.format({ dir: '/home/user', base: 'file.txt' }); console.log(formatted); // /home/user/file.txt
Cross-Platform Paths: Always use path.join() or path.resolve() instead of manually concatenating paths with / or \. This ensures your code works correctly on Windows, macOS, and Linux.

3. OS Module (os)

The os module provides operating system-related utility methods and properties.

const os = require('os'); // Get platform console.log('Platform:', os.platform()); // darwin, win32, linux // Get architecture console.log('Architecture:', os.arch()); // x64, arm64 // Get CPU information console.log('CPUs:', os.cpus().length, 'cores'); console.log('CPU Model:', os.cpus()[0].model); // Get memory information console.log('Total memory:', os.totalmem() / 1024 / 1024 / 1024, 'GB'); console.log('Free memory:', os.freemem() / 1024 / 1024 / 1024, 'GB'); // Get system uptime console.log('Uptime:', os.uptime() / 60 / 60, 'hours'); // Get home directory console.log('Home directory:', os.homedir()); // Get temporary directory console.log('Temp directory:', os.tmpdir()); // Get hostname console.log('Hostname:', os.hostname()); // Get network interfaces console.log('Network interfaces:', os.networkInterfaces());

4. HTTP Module (http)

The http module allows you to create HTTP servers and make HTTP requests.

Creating HTTP Server

const http = require('http'); // Create server const server = http.createServer((req, res) => { // Set response headers res.writeHead(200, { 'Content-Type': 'text/plain' }); // Handle different routes if (req.url === '/') { res.end('Welcome to Node.js HTTP Server'); } else if (req.url === '/api') { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ message: 'API endpoint' })); } else { res.writeHead(404); res.end('404 Not Found'); } }); // Start server const PORT = 3000; server.listen(PORT, () => { console.log(`Server running at http://localhost:${PORT}/`); });

Making HTTP Requests

const http = require('http'); // GET request http.get('http://api.example.com/users', (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { console.log('Response:', JSON.parse(data)); }); }).on('error', (err) => { console.error('Error:', err); }); // POST request const postData = JSON.stringify({ name: 'John', age: 30 }); const options = { hostname: 'api.example.com', port: 80, path: '/users', method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) } }; const req = http.request(options, (res) => { console.log('Status:', res.statusCode); res.on('data', (chunk) => { console.log('Response:', chunk.toString()); }); }); req.on('error', (err) => { console.error('Error:', err); }); req.write(postData); req.end();

5. Events Module (events)

The events module provides the EventEmitter class for working with events.

const EventEmitter = require('events'); // Create event emitter class MyEmitter extends EventEmitter {} const myEmitter = new MyEmitter(); // Register event listener myEmitter.on('event', (arg) => { console.log('Event occurred:', arg); }); // Register one-time listener myEmitter.once('singleEvent', () => { console.log('This will only run once'); }); // Emit events myEmitter.emit('event', 'Hello'); myEmitter.emit('event', 'World'); myEmitter.emit('singleEvent'); // Runs myEmitter.emit('singleEvent'); // Doesn't run // Real-world example: User registration class UserManager extends EventEmitter { register(user) { console.log(`Registering user: ${user.name}`); this.emit('userRegistered', user); } } const userManager = new UserManager(); userManager.on('userRegistered', (user) => { console.log('Send welcome email to:', user.email); }); userManager.on('userRegistered', (user) => { console.log('Create user profile for:', user.name); }); userManager.register({ name: 'John', email: 'john@example.com' });

6. Buffer Module (buffer)

Buffers are used to handle binary data. They're particularly useful when working with streams, files, and network operations.

// Create buffers const buf1 = Buffer.from('Hello'); const buf2 = Buffer.from([72, 101, 108, 108, 111]); // ASCII codes const buf3 = Buffer.alloc(10); // 10 bytes filled with zeros const buf4 = Buffer.allocUnsafe(10); // Faster but contains old data console.log(buf1); // <Buffer 48 65 6c 6c 6f> console.log(buf1.toString()); // Hello console.log(buf1.toString('hex')); // 48656c6c6f console.log(buf1.toString('base64')); // SGVsbG8= // Write to buffer buf3.write('Node.js'); console.log(buf3.toString()); // Node.js // Buffer operations const buf5 = Buffer.concat([buf1, Buffer.from(' World')]); console.log(buf5.toString()); // Hello World // Compare buffers const buf6 = Buffer.from('ABC'); const buf7 = Buffer.from('DEF'); console.log(buf6.compare(buf7)); // -1 (buf6 comes before buf7) // Check if equal console.log(buf6.equals(buf7)); // false

7. Stream Module (stream)

Streams allow you to process data piece by piece without loading everything into memory at once. Perfect for handling large files or real-time data.

const fs = require('fs'); // Readable stream const readStream = fs.createReadStream('large-file.txt', 'utf8'); readStream.on('data', (chunk) => { console.log('Received chunk:', chunk.length, 'bytes'); }); readStream.on('end', () => { console.log('Finished reading file'); }); readStream.on('error', (err) => { console.error('Error:', err); }); // Writable stream const writeStream = fs.createWriteStream('output.txt'); writeStream.write('First line\n'); writeStream.write('Second line\n'); writeStream.end('Last line\n'); // Piping streams (efficient file copy) const source = fs.createReadStream('source.txt'); const destination = fs.createWriteStream('destination.txt'); source.pipe(destination); // Transform stream (process data while streaming) const { Transform } = require('stream'); const upperCaseTransform = new Transform({ transform(chunk, encoding, callback) { this.push(chunk.toString().toUpperCase()); callback(); } }); fs.createReadStream('input.txt') .pipe(upperCaseTransform) .pipe(fs.createWriteStream('output-upper.txt'));

8. URL Module (url)

The url module provides utilities for URL parsing and formatting.

const url = require('url'); // Parse URL const myUrl = new URL('https://example.com:8080/path?name=John&age=30#section'); console.log(myUrl.protocol); // https: console.log(myUrl.hostname); // example.com console.log(myUrl.port); // 8080 console.log(myUrl.pathname); // /path console.log(myUrl.search); // ?name=John&age=30 console.log(myUrl.hash); // #section // Get query parameters console.log(myUrl.searchParams.get('name')); // John console.log(myUrl.searchParams.get('age')); // 30 // Add query parameters myUrl.searchParams.append('city', 'New York'); console.log(myUrl.toString()); // Legacy API (still useful) const urlString = 'https://example.com/path?name=John'; const parsedUrl = url.parse(urlString, true); console.log(parsedUrl.query); // { name: 'John' }

9. Crypto Module (crypto)

The crypto module provides cryptographic functionality including hashing, encryption, and random number generation.

const crypto = require('crypto'); // Generate hash (SHA256) const hash = crypto.createHash('sha256'); hash.update('password123'); console.log('Hash:', hash.digest('hex')); // Generate HMAC const hmac = crypto.createHmac('sha256', 'secret-key'); hmac.update('important data'); console.log('HMAC:', hmac.digest('hex')); // Generate random bytes crypto.randomBytes(16, (err, buffer) => { if (err) throw err; console.log('Random token:', buffer.toString('hex')); }); // Password hashing with scrypt const password = 'myPassword123'; const salt = crypto.randomBytes(16).toString('hex'); crypto.scrypt(password, salt, 64, (err, derivedKey) => { if (err) throw err; console.log('Hashed password:', derivedKey.toString('hex')); }); // Encryption and Decryption const algorithm = 'aes-256-cbc'; const key = crypto.randomBytes(32); const iv = crypto.randomBytes(16); function encrypt(text) { const cipher = crypto.createCipheriv(algorithm, key, iv); let encrypted = cipher.update(text, 'utf8', 'hex'); encrypted += cipher.final('hex'); return encrypted; } function decrypt(encrypted) { const decipher = crypto.createDecipheriv(algorithm, key, iv); let decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted; } const message = 'Secret message'; const encrypted = encrypt(message); const decrypted = decrypt(encrypted); console.log('Original:', message); console.log('Encrypted:', encrypted); console.log('Decrypted:', decrypted);

Practical Exercise: File Manager CLI

Create a command-line file manager using core modules:

const fs = require('fs').promises; const path = require('path'); const os = require('os'); async function fileManager() { const command = process.argv[2]; const arg1 = process.argv[3]; const arg2 = process.argv[4]; try { switch (command) { case 'list': const files = await fs.readdir(arg1 || './'); console.log('Files:', files.join(', ')); break; case 'read': const content = await fs.readFile(arg1, 'utf8'); console.log('Content:', content); break; case 'write': await fs.writeFile(arg1, arg2); console.log('File written successfully'); break; case 'info': const stats = await fs.stat(arg1); console.log('Size:', stats.size, 'bytes'); console.log('Modified:', stats.mtime); console.log('Is file:', stats.isFile()); break; case 'system': console.log('Platform:', os.platform()); console.log('CPU cores:', os.cpus().length); console.log('Free memory:', os.freemem() / 1024 / 1024, 'MB'); break; default: console.log('Unknown command'); } } catch (err) { console.error('Error:', err.message); } } fileManager(); // Usage: // node file-manager.js list ./ // node file-manager.js read file.txt // node file-manager.js write test.txt "Hello" // node file-manager.js info file.txt // node file-manager.js system

Summary

In this lesson, you've learned about Node.js core modules:

  • fs: File system operations (read, write, directories)
  • path: Cross-platform path manipulation
  • os: Operating system information and utilities
  • http: Creating servers and making HTTP requests
  • events: Event-driven programming with EventEmitter
  • buffer: Working with binary data
  • stream: Processing data efficiently chunk by chunk
  • url: URL parsing and manipulation
  • crypto: Cryptographic operations and security

These core modules form the foundation of most Node.js applications. In the next lesson, we'll dive deep into asynchronous programming patterns in Node.js!