Skip to content

Node.js Core

Node.js brings JavaScript to the server, enabling full-stack development with a single language. This comprehensive guide covers Node.js fundamentals, core modules, and advanced server-side development patterns.

Terminal window
# Install Node.js using Node Version Manager (recommended)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
nvm install --lts
nvm use --lts
# Verify installation
node --version
npm --version
# Initialize a new Node.js project
mkdir my-node-app
cd my-node-app
npm init -y
# Install dependencies
npm install express lodash
npm install --save-dev nodemon jest
// app.js - Simple HTTP server
const http = require('http');
const url = require('url');
const querystring = require('querystring');
const server = http.createServer((req, res) => {
const parsedUrl = url.parse(req.url);
const path = parsedUrl.pathname;
const query = querystring.parse(parsedUrl.query);
// Set CORS headers
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
// Simple routing
if (path === '/') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
message: 'Welcome to Node.js Server',
timestamp: new Date().toISOString()
}));
} else if (path === '/api/users' && req.method === 'GET') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify([
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' }
]));
} else {
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Not Found' }));
}
});
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
// Graceful shutdown
process.on('SIGTERM', () => {
console.log('SIGTERM received, shutting down gracefully');
server.close(() => {
process.exit(0);
});
});
const fs = require('fs').promises;
const path = require('path');
class FileManager {
static async readFile(filePath) {
try {
const data = await fs.readFile(filePath, 'utf8');
return data;
} catch (error) {
throw new Error(`Failed to read file ${filePath}: ${error.message}`);
}
}
static async writeFile(filePath, data) {
try {
await fs.writeFile(filePath, data, 'utf8');
console.log(`File written successfully: ${filePath}`);
} catch (error) {
throw new Error(`Failed to write file ${filePath}: ${error.message}`);
}
}
static async appendFile(filePath, data) {
try {
await fs.appendFile(filePath, data, 'utf8');
} catch (error) {
throw new Error(`Failed to append to file ${filePath}: ${error.message}`);
}
}
static async deleteFile(filePath) {
try {
await fs.unlink(filePath);
console.log(`File deleted: ${filePath}`);
} catch (error) {
throw new Error(`Failed to delete file ${filePath}: ${error.message}`);
}
}
static async createDirectory(dirPath) {
try {
await fs.mkdir(dirPath, { recursive: true });
console.log(`Directory created: ${dirPath}`);
} catch (error) {
throw new Error(`Failed to create directory ${dirPath}: ${error.message}`);
}
}
static async listDirectory(dirPath) {
try {
const files = await fs.readdir(dirPath);
const fileStats = await Promise.all(
files.map(async (file) => {
const filePath = path.join(dirPath, file);
const stats = await fs.stat(filePath);
return {
name: file,
path: filePath,
isDirectory: stats.isDirectory(),
size: stats.size,
modified: stats.mtime
};
})
);
return fileStats;
} catch (error) {
throw new Error(`Failed to list directory ${dirPath}: ${error.message}`);
}
}
static async copyFile(source, destination) {
try {
await fs.copyFile(source, destination);
console.log(`File copied from ${source} to ${destination}`);
} catch (error) {
throw new Error(`Failed to copy file: ${error.message}`);
}
}
static async watchFile(filePath, callback) {
try {
const watcher = fs.watch(filePath, (eventType, filename) => {
callback(eventType, filename);
});
return watcher;
} catch (error) {
throw new Error(`Failed to watch file ${filePath}: ${error.message}`);
}
}
}
// Usage examples
async function fileOperations() {
try {
// Create directory
await FileManager.createDirectory('./data');
// Write file
await FileManager.writeFile('./data/users.json', JSON.stringify([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
], null, 2));
// Read file
const users = await FileManager.readFile('./data/users.json');
console.log('Users:', JSON.parse(users));
// List directory
const files = await FileManager.listDirectory('./data');
console.log('Files in directory:', files);
// Watch file for changes
const watcher = await FileManager.watchFile('./data/users.json', (eventType, filename) => {
console.log(`File ${filename} was ${eventType}`);
});
// Clean up watcher after 10 seconds
setTimeout(() => watcher.close(), 10000);
} catch (error) {
console.error('File operation failed:', error.message);
}
}
const http = require('http');
const https = require('https');
const fs = require('fs');
const url = require('url');
class HTTPServer {
constructor(options = {}) {
this.port = options.port || 3000;
this.hostname = options.hostname || 'localhost';
this.routes = new Map();
this.middleware = [];
this.server = null;
}
use(middleware) {
this.middleware.push(middleware);
}
route(method, path, handler) {
const key = `${method.toUpperCase()}:${path}`;
this.routes.set(key, handler);
}
get(path, handler) {
this.route('GET', path, handler);
}
post(path, handler) {
this.route('POST', path, handler);
}
put(path, handler) {
this.route('PUT', path, handler);
}
delete(path, handler) {
this.route('DELETE', path, handler);
}
async handleRequest(req, res) {
const parsedUrl = url.parse(req.url, true);
const path = parsedUrl.pathname;
const method = req.method;
const key = `${method}:${path}`;
// Enhanced request object
req.query = parsedUrl.query;
req.params = {};
// Parse request body for POST/PUT requests
if (method === 'POST' || method === 'PUT') {
req.body = await this.parseBody(req);
}
// Enhanced response object
res.json = (data) => {
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(data));
};
res.status = (code) => {
res.statusCode = code;
return res;
};
// Execute middleware
for (const middleware of this.middleware) {
try {
await middleware(req, res);
} catch (error) {
res.status(500).json({ error: 'Middleware error', message: error.message });
return;
}
}
// Route handling
const handler = this.routes.get(key);
if (handler) {
try {
await handler(req, res);
} catch (error) {
res.status(500).json({ error: 'Internal server error', message: error.message });
}
} else {
res.status(404).json({ error: 'Not Found' });
}
}
async parseBody(req) {
return new Promise((resolve, reject) => {
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
try {
resolve(body ? JSON.parse(body) : {});
} catch (error) {
reject(error);
}
});
req.on('error', reject);
});
}
start() {
this.server = http.createServer((req, res) => {
this.handleRequest(req, res);
});
this.server.listen(this.port, this.hostname, () => {
console.log(`Server running at http://${this.hostname}:${this.port}/`);
});
return this.server;
}
stop() {
if (this.server) {
this.server.close();
}
}
}
// HTTPS Server
class HTTPSServer extends HTTPServer {
constructor(options = {}) {
super(options);
this.sslOptions = options.ssl || {};
}
start() {
if (!this.sslOptions.key || !this.sslOptions.cert) {
throw new Error('SSL key and certificate are required for HTTPS server');
}
this.server = https.createServer(this.sslOptions, (req, res) => {
this.handleRequest(req, res);
});
this.server.listen(this.port, this.hostname, () => {
console.log(`HTTPS Server running at https://${this.hostname}:${this.port}/`);
});
return this.server;
}
}
// Middleware examples
const loggingMiddleware = (req, res) => {
console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`);
};
const corsMiddleware = (req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
};
const authMiddleware = (req, res) => {
const token = req.headers.authorization;
if (!token) {
res.status(401).json({ error: 'Authorization token required' });
return;
}
// Verify token logic here
req.user = { id: 1, name: 'Authenticated User' };
};
// Usage
const server = new HTTPServer({ port: 3000 });
server.use(loggingMiddleware);
server.use(corsMiddleware);
server.get('/', (req, res) => {
res.json({ message: 'Welcome to Node.js API' });
});
server.get('/api/users', authMiddleware, (req, res) => {
res.json([
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' }
]);
});
server.post('/api/users', authMiddleware, (req, res) => {
const newUser = {
id: Date.now(),
...req.body,
createdAt: new Date().toISOString()
};
res.status(201).json(newUser);
});
server.start();
const { Readable, Writable, Transform, pipeline } = require('stream');
const fs = require('fs');
const zlib = require('zlib');
// Custom Readable Stream
class NumberStream extends Readable {
constructor(options = {}) {
super(options);
this.current = options.start || 1;
this.max = options.max || 100;
}
_read() {
if (this.current <= this.max) {
this.push(`${this.current}\n`);
this.current++;
} else {
this.push(null); // End of stream
}
}
}
// Custom Writable Stream
class FileWriterStream extends Writable {
constructor(filename, options = {}) {
super(options);
this.filename = filename;
this.fd = null;
}
_construct(callback) {
fs.open(this.filename, 'w', (err, fd) => {
if (err) {
callback(err);
} else {
this.fd = fd;
callback();
}
});
}
_write(chunk, encoding, callback) {
fs.write(this.fd, chunk, callback);
}
_destroy(err, callback) {
if (this.fd) {
fs.close(this.fd, (closeErr) => callback(closeErr || err));
} else {
callback(err);
}
}
}
// Custom Transform Stream
class UpperCaseTransform extends Transform {
_transform(chunk, encoding, callback) {
this.push(chunk.toString().toUpperCase());
callback();
}
}
class JSONParseTransform extends Transform {
constructor(options = {}) {
super({ ...options, objectMode: true });
this.buffer = '';
}
_transform(chunk, encoding, callback) {
this.buffer += chunk.toString();
const lines = this.buffer.split('\n');
this.buffer = lines.pop(); // Keep incomplete line in buffer
for (const line of lines) {
if (line.trim()) {
try {
const obj = JSON.parse(line);
this.push(obj);
} catch (error) {
this.emit('error', error);
return;
}
}
}
callback();
}
_flush(callback) {
if (this.buffer.trim()) {
try {
const obj = JSON.parse(this.buffer);
this.push(obj);
} catch (error) {
this.emit('error', error);
return;
}
}
callback();
}
}
// Stream utilities
class StreamUtils {
static async streamToString(stream) {
const chunks = [];
return new Promise((resolve, reject) => {
stream.on('data', chunk => chunks.push(chunk));
stream.on('error', reject);
stream.on('end', () => resolve(Buffer.concat(chunks).toString()));
});
}
static async streamToBuffer(stream) {
const chunks = [];
return new Promise((resolve, reject) => {
stream.on('data', chunk => chunks.push(chunk));
stream.on('error', reject);
stream.on('end', () => resolve(Buffer.concat(chunks)));
});
}
static createBackpressureAwareStream(processingFunction) {
return new Transform({
objectMode: true,
async transform(chunk, encoding, callback) {
try {
const result = await processingFunction(chunk);
callback(null, result);
} catch (error) {
callback(error);
}
}
});
}
}
// File processing with streams
async function processLargeFile() {
const readStream = fs.createReadStream('./large-file.txt');
const writeStream = fs.createWriteStream('./processed-file.txt');
const gzipStream = zlib.createGzip();
const upperCaseStream = new UpperCaseTransform();
// Using pipeline for better error handling
pipeline(
readStream,
upperCaseStream,
gzipStream,
writeStream,
(error) => {
if (error) {
console.error('Pipeline failed:', error);
} else {
console.log('Pipeline succeeded');
}
}
);
}
// Memory-efficient CSV processing
class CSVProcessor {
static createParser() {
return new Transform({
objectMode: true,
transform(chunk, encoding, callback) {
const lines = chunk.toString().split('\n');
for (const line of lines) {
if (line.trim()) {
const columns = line.split(',').map(col => col.trim());
this.push(columns);
}
}
callback();
}
});
}
static createFilter(filterFunction) {
return new Transform({
objectMode: true,
transform(chunk, encoding, callback) {
if (filterFunction(chunk)) {
this.push(chunk);
}
callback();
}
});
}
static createMapper(mapFunction) {
return new Transform({
objectMode: true,
transform(chunk, encoding, callback) {
try {
const result = mapFunction(chunk);
this.push(result);
callback();
} catch (error) {
callback(error);
}
}
});
}
}
const EventEmitter = require('events');
const { once, on } = require('events');
class CustomEventEmitter extends EventEmitter {
constructor() {
super();
this.maxListeners = 20;
this.setMaxListeners(this.maxListeners);
}
// Add typed event methods
emitUserRegistered(user) {
this.emit('user:registered', user);
}
emitUserLoggedIn(user) {
this.emit('user:logged-in', user);
}
emitUserLoggedOut(userId) {
this.emit('user:logged-out', userId);
}
onUserRegistered(callback) {
this.on('user:registered', callback);
}
onUserLoggedIn(callback) {
this.on('user:logged-in', callback);
}
onUserLoggedOut(callback) {
this.on('user:logged-out', callback);
}
}
// Application event bus
class ApplicationEventBus extends EventEmitter {
constructor() {
super();
this.namespaces = new Map();
this.setupErrorHandling();
}
setupErrorHandling() {
this.on('error', (error) => {
console.error('EventBus Error:', error);
});
// Handle uncaught exceptions in event handlers
process.on('uncaughtException', (error) => {
console.error('Uncaught Exception in Event Handler:', error);
this.emit('error', error);
});
}
// Namespaced events
namespace(name) {
if (!this.namespaces.has(name)) {
this.namespaces.set(name, new EventEmitter());
}
return this.namespaces.get(name);
}
// Event with timeout
emitWithTimeout(event, data, timeout = 5000) {
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
reject(new Error(`Event ${event} timed out after ${timeout}ms`));
}, timeout);
this.once(`${event}:response`, (response) => {
clearTimeout(timer);
resolve(response);
});
this.emit(event, data);
});
}
// Async event handler support
async emitAsync(event, ...args) {
const listeners = this.listeners(event);
const promises = listeners.map(listener => {
try {
const result = listener(...args);
return Promise.resolve(result);
} catch (error) {
return Promise.reject(error);
}
});
return Promise.allSettled(promises);
}
// Event metrics
getEventMetrics() {
const events = this.eventNames();
const metrics = {};
events.forEach(event => {
metrics[event] = {
listenerCount: this.listenerCount(event),
maxListeners: this.getMaxListeners()
};
});
return metrics;
}
}
// User service with events
class UserService extends EventEmitter {
constructor() {
super();
this.users = new Map();
this.setupEventHandlers();
}
setupEventHandlers() {
this.on('user:registered', this.onUserRegistered.bind(this));
this.on('user:updated', this.onUserUpdated.bind(this));
this.on('user:deleted', this.onUserDeleted.bind(this));
}
async createUser(userData) {
const user = {
id: Date.now(),
...userData,
createdAt: new Date(),
updatedAt: new Date()
};
this.users.set(user.id, user);
this.emit('user:registered', user);
return user;
}
async updateUser(id, updateData) {
const user = this.users.get(id);
if (!user) {
throw new Error('User not found');
}
const updatedUser = {
...user,
...updateData,
updatedAt: new Date()
};
this.users.set(id, updatedUser);
this.emit('user:updated', updatedUser, user);
return updatedUser;
}
async deleteUser(id) {
const user = this.users.get(id);
if (!user) {
throw new Error('User not found');
}
this.users.delete(id);
this.emit('user:deleted', user);
return user;
}
onUserRegistered(user) {
console.log(`User registered: ${user.name} (${user.id})`);
// Send welcome email, create profile, etc.
}
onUserUpdated(updatedUser, previousUser) {
console.log(`User updated: ${updatedUser.name} (${updatedUser.id})`);
// Log changes, send notifications, etc.
}
onUserDeleted(user) {
console.log(`User deleted: ${user.name} (${user.id})`);
// Cleanup related data, send notifications, etc.
}
}
// Event-driven architecture example
class OrderProcessingSystem extends EventEmitter {
constructor() {
super();
this.orders = new Map();
this.setupEventHandlers();
}
setupEventHandlers() {
this.on('order:created', this.processPayment.bind(this));
this.on('payment:successful', this.fulfillOrder.bind(this));
this.on('payment:failed', this.handlePaymentFailure.bind(this));
this.on('order:fulfilled', this.sendConfirmation.bind(this));
this.on('order:cancelled', this.processRefund.bind(this));
}
async createOrder(orderData) {
const order = {
id: Date.now(),
...orderData,
status: 'created',
createdAt: new Date()
};
this.orders.set(order.id, order);
this.emit('order:created', order);
return order;
}
async processPayment(order) {
try {
// Simulate payment processing
await new Promise(resolve => setTimeout(resolve, 1000));
const success = Math.random() > 0.1; // 90% success rate
if (success) {
order.status = 'paid';
order.paidAt = new Date();
this.emit('payment:successful', order);
} else {
order.status = 'payment_failed';
this.emit('payment:failed', order);
}
} catch (error) {
order.status = 'payment_failed';
order.error = error.message;
this.emit('payment:failed', order);
}
}
async fulfillOrder(order) {
try {
// Simulate order fulfillment
await new Promise(resolve => setTimeout(resolve, 2000));
order.status = 'fulfilled';
order.fulfilledAt = new Date();
this.emit('order:fulfilled', order);
} catch (error) {
order.status = 'fulfillment_failed';
order.error = error.message;
this.emit('fulfillment:failed', order);
}
}
handlePaymentFailure(order) {
console.log(`Payment failed for order ${order.id}`);
// Send notification to customer, retry payment, etc.
}
sendConfirmation(order) {
console.log(`Order ${order.id} fulfilled successfully`);
// Send confirmation email, update inventory, etc.
}
processRefund(order) {
console.log(`Processing refund for order ${order.id}`);
// Process refund, update accounting, etc.
}
}
// Usage examples
async function eventExamples() {
// Custom event emitter
const customEmitter = new CustomEventEmitter();
customEmitter.onUserRegistered((user) => {
console.log('User registered event:', user);
});
customEmitter.emitUserRegistered({ id: 1, name: 'Alice' });
// Application event bus
const eventBus = new ApplicationEventBus();
// User service
const userService = new UserService();
const user = await userService.createUser({
name: 'Bob',
email: 'bob@example.com'
});
// Order processing system
const orderSystem = new OrderProcessingSystem();
const order = await orderSystem.createOrder({
customerId: user.id,
items: [{ id: 1, quantity: 2, price: 29.99 }],
total: 59.98
});
}
// Using events with async/await
async function waitForEvent() {
const emitter = new EventEmitter();
// Emit event after delay
setTimeout(() => {
emitter.emit('data', { message: 'Hello World' });
}, 1000);
// Wait for single event
const [data] = await once(emitter, 'data');
console.log('Received data:', data);
// Listen to multiple events
emitter.emit('multiple', 1);
emitter.emit('multiple', 2);
emitter.emit('multiple', 3);
for await (const [value] of on(emitter, 'multiple')) {
console.log('Multiple event value:', value);
if (value === 3) break;
}
}

This comprehensive Node.js guide covers the fundamental concepts and core modules needed for server-side JavaScript development. Each section provides practical examples and best practices for building robust Node.js applications.


Continue exploring Node.js capabilities by diving into specific modules and building real-world applications.