Complete Reference Guide

Master Node.js

From core concepts to production deployment. Your comprehensive guide to server-side JavaScript.

Introduction to Node.js

What is Node.js?

Node.js is a runtime environment that allows you to run JavaScript on the server side, built on Chrome's V8 JavaScript engine. It enables developers to build scalable network applications using JavaScript on both frontend and backend.

Event-driven architecture
Non-blocking I/O operations
Single-threaded with event loop

Real-world Scenario

Building a web server that can handle thousands of concurrent connections efficiently without creating a new thread for each request, making it perfect for real-time applications like chat systems and streaming services.

server.js
// Simple Node.js HTTP Server
const http = require('http');

const server = http.createServer((req, res) => {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World from Node.js!');
});

server.listen(3000, () => {
    console.log('Server running on port 3000');
});

Event-Driven Architecture

Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Perfect for handling file uploads while simultaneously serving other requests.

events.js
const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();

// Register event listener
myEmitter.on('event', (data) => {
    console.log('Event triggered:', data);
});

// Emit event
myEmitter.emit('event', 'Hello World');

Core Modules

File System (fs)

File interaction & manipulation

Essential for reading configuration files, processing uploads, or generating reports. Supports both synchronous and asynchronous operations.

filesystem.js
const fs = require('fs');

// Async reading (Non-blocking)
fs.readFile('config.json', 'utf8', (err, data) => {
    if (err) throw err;
    console.log('Content:', data);
});

// Sync reading (Blocking)
const data = fs.readFileSync('config.json', 'utf8');

// Writing files
fs.writeFile('output.txt', 'Hello', (err) => {
    if (err) throw err;
    console.log('Saved!');
});

HTTP Module

Server & client functionality

Create HTTP servers and clients, handle requests and responses. Foundation for building REST APIs without external frameworks.

http-server.js
const http = require('http');
const url = require('url');

const server = http.createServer((req, res) => {
    const parsedUrl = url.parse(req.url, true);
    
    if (parsedUrl.pathname === '/api/users') {
        res.writeHead(200, {'Content-Type': 'application/json'});
        res.end(JSON.stringify({users: ['John', 'Jane']}));
    } else {
        res.writeHead(404);
        res.end('Not Found');
    }
});

server.listen(3000);

Path Module

const path = require('path');
  • path.join() - Join paths
  • path.resolve() - Resolve absolute
  • path.extname() - Get extension

OS Module

const os = require('os');
  • os.platform() - OS platform
  • os.cpus() - CPU info
  • os.freemem() - Free memory

Process Object

Global process object
  • process.env - Environment vars
  • process.argv - CLI arguments
  • process.exit() - Exit process
ex

Express.js Framework

Basic Express Setup

The most popular Node.js web framework for building APIs and web applications. Minimalist, flexible, and robust.

app.js
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;

// Essential Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Routes
app.get('/', (req, res) => {
    res.json({ message: 'Welcome to our API!' });
});

app.get('/api/users', (req, res) => {
    res.json([
        { id: 1, name: 'John Doe' },
        { id: 2, name: 'Jane Smith' }
    ]);
});

app.listen(port, () => {
    console.log(`Server running on port ${port}`);
});

Middleware Functions

Functions that execute during the request-response cycle. Essential for authentication, logging, error handling, and request validation.

middleware.js
// Custom Logger Middleware
const logger = (req, res, next) => {
    console.log(`${new Date().toISOString()} - ${req.method} ${req.path}`);
    next(); // Continue to next middleware
};

// Authentication Middleware
const authenticate = (req, res, next) => {
    const token = req.header('Authorization');
    if (!token) {
        return res.status(401).json({ error: 'Access denied' });
    }
    next();
};

// Apply middleware
app.use(logger); // Global
app.use('/api/protected', authenticate); // Route-specific
error-handler.js
// Error Handling Middleware
app.use((err, req, res, next) => {
    console.error(err.stack);
    res.status(500).json({ 
        error: 'Something went wrong!',
        message: err.message
    });
});

// 404 Handler
app.use((req, res) => {
    res.status(404).json({ 
        error: 'Route not found' 
    });
});

Asynchronous Programming

Promises

A better way to handle asynchronous operations with cleaner syntax and better error handling compared to callbacks.

promises.js
const fs = require('fs').promises;

// Promise-based file reading
fs.readFile('config.json', 'utf8')
    .then(data => console.log('File:', data))
    .catch(err => console.error('Error:', err));

// Promise.all for parallel execution
Promise.all([
    fs.readFile('file1.txt'),
    fs.readFile('file2.txt')
])
.then(([data1, data2]) => {
    console.log('Both files read');
})
.catch(err => console.error(err));

Async/Await

Modern

Modern syntax for handling asynchronous operations with synchronous-like code. Easier to read and debug.

async-await.js
const fs = require('fs').promises;

async function processFiles() {
    try {
        // Sequential execution
        const data1 = await fs.readFile('file1.txt', 'utf8');
        const data2 = await fs.readFile('file2.txt', 'utf8');
        
        const combined = data1 + data2;
        await fs.writeFile('combined.txt', combined);
        
        console.log('Success!');
        return combined;
    } catch (error) {
        console.error('Error:', error);
        throw error;
    }
}

Async Patterns Comparison

Pattern Readability Error Handling Use Case
Callbacks Low (Callback Hell) Manual Legacy code
Promises Medium .catch() chain Parallel operations
Async/Await High Try/Catch Modern applications

Database Integration

MongoDB with Mongoose

Object Data Modeling (ODM) library

Mongoose provides a straightforward, schema-based solution to model your application data. It includes built-in type casting, validation, query building, and business logic hooks.

database.js
const mongoose = require('mongoose');

// Connection
await mongoose.connect('mongodb://localhost:27017/myapp');

// Define Schema
const userSchema = new mongoose.Schema({
    name: { type: String, required: true },
    email: { type: String, required: true, unique: true },
    age: { type: Number, min: 0, max: 120 },
    createdAt: { type: Date, default: Date.now }
});

const User = mongoose.model('User', userSchema);

// CRUD Operations
async function userOperations() {
    // Create
    const newUser = await User.create({
        name: 'John Doe',
        email: 'john@example.com',
        age: 30
    });
    
    // Read
    const users = await User.find();
    const user = await User.findById(newUser._id);
    
    // Update
    await User.findByIdAndUpdate(user._id, { age: 31 });
    
    // Delete
    await User.findByIdAndDelete(user._id);
}

Create

Model.create()

Insert new documents

Read

Model.find() / findOne()

Query documents

Update/Delete

findByIdAndUpdate/Delete

Modify documents

Advanced Topics

Streams & Buffers

Handle large data efficiently. Perfect for processing large files without loading everything into memory.

streams.js
const fs = require('fs');
const readline = require('readline');

// Read large files in chunks
const stream = fs.createReadStream('large-file.txt', {
    highWaterMark: 1024 // 1KB chunks
});

stream.on('data', (chunk) => {
    console.log('Received:', chunk.length, 'bytes');
});

// Process line by line
const rl = readline.createInterface({
    input: fs.createReadStream('data.csv')
});

rl.on('line', (line) => {
    console.log('Line:', line);
});

WebSockets (Socket.IO)

Real-time bidirectional communication. Ideal for chat apps, live notifications, and collaborative tools.

websocket.js
const io = require('socket.io')(server);

io.on('connection', (socket) => {
    console.log('User connected:', socket.id);
    
    socket.on('joinRoom', (roomId) => {
        socket.join(roomId);
        socket.to(roomId).emit('userJoined');
    });
    
    socket.on('sendMessage', (data) => {
        io.to(data.roomId).emit('newMessage', {
            userId: socket.id,
            message: data.message,
            timestamp: new Date()
        });
    });
});

Security Best Practices

Input validation, sanitization, and protection against common attacks using Joi and validator.

security.js
const Joi = require('joi');

const userSchema = Joi.object({
    name: Joi.string().min(2).required(),
    email: Joi.string().email().required(),
    password: Joi.string().min(8).pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])/)
});

const validate = (schema) => {
    return (req, res, next) => {
        const { error } = schema.validate(req.body);
        if (error) {
            return res.status(400).json({ 
                error: error.details[0].message 
            });
        }
        next();
    };
};

app.post('/api/users', validate(userSchema), handler);

Docker Deployment

Containerize your Node.js application for consistent deployment across environments.

Dockerfile
FROM node:18-alpine

WORKDIR /usr/src/app

# Copy dependencies
COPY package*.json ./
RUN npm ci --only=production

# Copy code
COPY . .

# Security: Run as non-root
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
USER nodejs

EXPOSE 3000

CMD ["node", "server.js"]

Testing with Jest

app.test.js
const request = require('supertest');
const app = require('./app');

describe('User API', () => {
    test('GET /api/users - should return all users', async () => {
        const response = await request(app)
            .get('/api/users')
            .expect(200);
            
        expect(response.body).toHaveLength(2);
        expect(response.body[0]).toHaveProperty('name');
    });

    test('POST /api/users - should create user', async () => {
        const userData = { name: 'New User', email: 'new@test.com' };
        
        const response = await request(app)
            .post(span class="syntax-string">'/api/users')
            .send(userData)
            .expect(201);
            
        expect(response.body.name).toBe(userData.name);
    });
});