Getting Started
Installation & Setup
# Install Node.js from official website
# https://nodejs.org
# Check Node.js version
node --version
# Check npm version
npm --version
# Initialize a new Node.js project
npm init
# Initialize with default values
npm init -y
# https://nodejs.org
# Check Node.js version
node --version
# Check npm version
npm --version
# Initialize a new Node.js project
npm init
# Initialize with default values
npm init -y
Note: Node.js comes with npm (Node Package Manager) included. Always verify your installation with the version commands.
Basic HTTP Server
// Import the http module
const http = require('http');
// Create a server
const server = http.createServer((req, res) => {
// Set response header
res.writeHead(200, {'Content-Type': 'text/plain'});
// Send response
res.end('Hello, Node.js!');
});
// Listen on port 3000
server.listen(3000, () => {
console.log('Server running at http://localhost:3000/');
});
const http = require('http');
// Create a server
const server = http.createServer((req, res) => {
// Set response header
res.writeHead(200, {'Content-Type': 'text/plain'});
// Send response
res.end('Hello, Node.js!');
});
// Listen on port 3000
server.listen(3000, () => {
console.log('Server running at http://localhost:3000/');
});
Core Modules
File System (fs)
// Import fs module
const fs = require('fs');
// Read file (async)
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
// Read file (sync)
const data = fs.readFileSync('file.txt', 'utf8');
// Write file (async)
fs.writeFile('file.txt', 'Hello World', (err) => {
if (err) throw err;
console.log('File written!');
});
// Append to file
fs.appendFile('file.txt', 'New data', (err) => {
if (err) throw err;
console.log('Data appended!');
});
const fs = require('fs');
// Read file (async)
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
// Read file (sync)
const data = fs.readFileSync('file.txt', 'utf8');
// Write file (async)
fs.writeFile('file.txt', 'Hello World', (err) => {
if (err) throw err;
console.log('File written!');
});
// Append to file
fs.appendFile('file.txt', 'New data', (err) => {
if (err) throw err;
console.log('Data appended!');
});
Path Module
// Import path module
const path = require('path');
// Get directory name
const dirName = path.dirname('/path/to/file.txt');
// Get file extension
const ext = path.extname('index.html'); // .html
// Join path segments
const fullPath = path.join('/foo', 'bar', 'baz/asdf');
// Resolve absolute path
const absPath = path.resolve('file.txt');
// Get base name
const base = path.basename('/path/to/file.txt'); // file.txt
// Parse path
const parsed = path.parse('/path/to/file.txt');
// Returns: { root: '/', dir: '/path/to', base: 'file.txt', ext: '.txt', name: 'file' }
const path = require('path');
// Get directory name
const dirName = path.dirname('/path/to/file.txt');
// Get file extension
const ext = path.extname('index.html'); // .html
// Join path segments
const fullPath = path.join('/foo', 'bar', 'baz/asdf');
// Resolve absolute path
const absPath = path.resolve('file.txt');
// Get base name
const base = path.basename('/path/to/file.txt'); // file.txt
// Parse path
const parsed = path.parse('/path/to/file.txt');
// Returns: { root: '/', dir: '/path/to', base: 'file.txt', ext: '.txt', name: 'file' }
Events Module
// Import events module
const EventEmitter = require('events');
// Create custom event emitter
class MyEmitter extends EventEmitter {}
// Create instance
const myEmitter = new MyEmitter();
// Register event listener
myEmitter.on('event', () => {
console.log('An event occurred!');
});
// Emit event
myEmitter.emit('event');
// Event with parameters
myEmitter.on('data', (data) => {
console.log(`Received data: ${data}`);
});
myEmitter.emit('data', 'Hello World');
const EventEmitter = require('events');
// Create custom event emitter
class MyEmitter extends EventEmitter {}
// Create instance
const myEmitter = new MyEmitter();
// Register event listener
myEmitter.on('event', () => {
console.log('An event occurred!');
});
// Emit event
myEmitter.emit('event');
// Event with parameters
myEmitter.on('data', (data) => {
console.log(`Received data: ${data}`);
});
myEmitter.emit('data', 'Hello World');
OS Module
// Import os module
const os = require('os');
// Get OS platform
const platform = os.platform(); // 'darwin', 'win32', 'linux'
// Get CPU architecture
const arch = os.arch(); // 'x64', 'arm'
// Get total system memory
const totalMem = os.totalmem();
// Get free system memory
const freeMem = os.freemem();
// Get system uptime
const uptime = os.uptime();
// Get user info
const userInfo = os.userInfo();
// Get network interfaces
const network = os.networkInterfaces();
// Get home directory
const homedir = os.homedir();
// Get temp directory
const tmpdir = os.tmpdir();
const os = require('os');
// Get OS platform
const platform = os.platform(); // 'darwin', 'win32', 'linux'
// Get CPU architecture
const arch = os.arch(); // 'x64', 'arm'
// Get total system memory
const totalMem = os.totalmem();
// Get free system memory
const freeMem = os.freemem();
// Get system uptime
const uptime = os.uptime();
// Get user info
const userInfo = os.userInfo();
// Get network interfaces
const network = os.networkInterfaces();
// Get home directory
const homedir = os.homedir();
// Get temp directory
const tmpdir = os.tmpdir();
NPM & Packages
NPM Basics
# Install a package locally
npm install package-name
# Install a specific version
npm install package-name@version
# Install as dev dependency
npm install --save-dev package-name
# Install globally
npm install -g package-name
# Update a package
npm update package-name
# Uninstall a package
npm uninstall package-name
# List installed packages
npm list
# List outdated packages
npm outdated
# Run scripts defined in package.json
npm run script-name
npm install package-name
# Install a specific version
npm install package-name@version
# Install as dev dependency
npm install --save-dev package-name
# Install globally
npm install -g package-name
# Update a package
npm update package-name
# Uninstall a package
npm uninstall package-name
# List installed packages
npm list
# List outdated packages
npm outdated
# Run scripts defined in package.json
npm run script-name
Package.json
{
"name": "my-app",
"version": "1.0.0",
"description": "My Node.js application",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"test": "jest"
},
"keywords": ["nodejs", "javascript"],
"author": "Your Name",
"license": "MIT",
"dependencies": {
"express": "^4.18.2",
"mongoose": "^7.0.3"
},
"devDependencies": {
"nodemon": "^2.0.22",
"jest": "^29.5.0"
},
"engines": {
"node": ">=14.0.0"
}
}
"name": "my-app",
"version": "1.0.0",
"description": "My Node.js application",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"test": "jest"
},
"keywords": ["nodejs", "javascript"],
"author": "Your Name",
"license": "MIT",
"dependencies": {
"express": "^4.18.2",
"mongoose": "^7.0.3"
},
"devDependencies": {
"nodemon": "^2.0.22",
"jest": "^29.5.0"
},
"engines": {
"node": ">=14.0.0"
}
}
Express.js Framework
Basic Express Server
// Install Express
// npm install express
// Import Express
const express = require('express');
const app = express();
const port = 3000;
// Basic route
app.get('/', (req, res) => {
res.send('Hello World!');
});
// Route with parameters
app.get('/users/:id', (req, res) => {
res.send(`User ID: ${req.params.id}`);
});
// Start server
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
// npm install express
// Import Express
const express = require('express');
const app = express();
const port = 3000;
// Basic route
app.get('/', (req, res) => {
res.send('Hello World!');
});
// Route with parameters
app.get('/users/:id', (req, res) => {
res.send(`User ID: ${req.params.id}`);
});
// Start server
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
Middleware
// Built-in middleware
app.use(express.json()); // Parse JSON bodies
app.use(express.urlencoded({ extended: true })); // Parse URL-encoded bodies
// Custom middleware
app.use((req, res, next) => {
console.log(`${req.method} ${req.path}`);
next(); // Pass control to next middleware
});
// Error handling middleware
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
// Third-party middleware (install first)
// npm install cors morgan helmet
const cors = require('cors');
const morgan = require('morgan');
const helmet = require('helmet');
app.use(cors()); // Enable CORS
app.use(morgan('combined')); // HTTP request logger
app.use(helmet()); // Security headers
app.use(express.json()); // Parse JSON bodies
app.use(express.urlencoded({ extended: true })); // Parse URL-encoded bodies
// Custom middleware
app.use((req, res, next) => {
console.log(`${req.method} ${req.path}`);
next(); // Pass control to next middleware
});
// Error handling middleware
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
// Third-party middleware (install first)
// npm install cors morgan helmet
const cors = require('cors');
const morgan = require('morgan');
const helmet = require('helmet');
app.use(cors()); // Enable CORS
app.use(morgan('combined')); // HTTP request logger
app.use(helmet()); // Security headers
Routing
// Different HTTP methods
app.get('/resource', (req, res) => {
// Handle GET request
res.send('GET request');
});
app.post('/resource', (req, res) => {
// Handle POST request
res.send('POST request');
});
app.put('/resource/:id', (req, res) => {
// Handle PUT request
res.send(`PUT request for ID ${req.params.id}`);
});
app.delete('/resource/:id', (req, res) => {
// Handle DELETE request
res.send(`DELETE request for ID ${req.params.id}`);
});
// Route chaining
app.route('/book')
.get((req, res) => { res.send('Get a book'); })
.post((req, res) => { res.send('Add a book'); })
.put((req, res) => { res.send('Update the book'); });
// Router module (create in separate file)
const router = express.Router();
router.get('/', (req, res) => {
res.send('Router home');
});
// Mount the router
app.use('/route', router);
app.get('/resource', (req, res) => {
// Handle GET request
res.send('GET request');
});
app.post('/resource', (req, res) => {
// Handle POST request
res.send('POST request');
});
app.put('/resource/:id', (req, res) => {
// Handle PUT request
res.send(`PUT request for ID ${req.params.id}`);
});
app.delete('/resource/:id', (req, res) => {
// Handle DELETE request
res.send(`DELETE request for ID ${req.params.id}`);
});
// Route chaining
app.route('/book')
.get((req, res) => { res.send('Get a book'); })
.post((req, res) => { res.send('Add a book'); })
.put((req, res) => { res.send('Update the book'); });
// Router module (create in separate file)
const router = express.Router();
router.get('/', (req, res) => {
res.send('Router home');
});
// Mount the router
app.use('/route', router);
Template Engines
// Set EJS as template engine
// npm install ejs
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
// Render a view
app.get('/', (req, res) => {
res.render('index', {
title: 'Home Page',
message: 'Hello EJS!'
});
});
// Using Pug (formerly Jade)
// npm install pug
app.set('view engine', 'pug');
// Using Handlebars
// npm install express-handlebars
const exphbs = require('express-handlebars');
app.engine('handlebars', exphbs());
app.set('view engine', 'handlebars');
// Serve static files
app.use(express.static('public'));
// Multiple static directories
app.use(express.static('public'));
app.use(express.static('uploads'));
// npm install ejs
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
// Render a view
app.get('/', (req, res) => {
res.render('index', {
title: 'Home Page',
message: 'Hello EJS!'
});
});
// Using Pug (formerly Jade)
// npm install pug
app.set('view engine', 'pug');
// Using Handlebars
// npm install express-handlebars
const exphbs = require('express-handlebars');
app.engine('handlebars', exphbs());
app.set('view engine', 'handlebars');
// Serve static files
app.use(express.static('public'));
// Multiple static directories
app.use(express.static('public'));
app.use(express.static('uploads'));
Database Integration
MongoDB with Mongoose
// Install Mongoose
// npm install mongoose
// Connect to MongoDB
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/mydatabase', {
useNewUrlParser: true,
useUnifiedTopology: true
});
// Define a schema
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
email: {
type: String,
required: true,
unique: true
},
age: {
type: Number,
min: 18
},
createdAt: {
type: Date,
default: Date.now
}
});
// Create a model
const User = mongoose.model('User', userSchema);
// Create a new user
const newUser = new User({
name: 'John Doe',
email: 'john@example.com',
age: 25
});
newUser.save((err, user) => {
if (err) return console.error(err);
console.log('User saved:', user);
});
// Find users
User.find({ age: { $gte: 21 } }, (err, users) => {
if (err) return console.error(err);
console.log('Users:', users);
});
// npm install mongoose
// Connect to MongoDB
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/mydatabase', {
useNewUrlParser: true,
useUnifiedTopology: true
});
// Define a schema
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
email: {
type: String,
required: true,
unique: true
},
age: {
type: Number,
min: 18
},
createdAt: {
type: Date,
default: Date.now
}
});
// Create a model
const User = mongoose.model('User', userSchema);
// Create a new user
const newUser = new User({
name: 'John Doe',
email: 'john@example.com',
age: 25
});
newUser.save((err, user) => {
if (err) return console.error(err);
console.log('User saved:', user);
});
// Find users
User.find({ age: { $gte: 21 } }, (err, users) => {
if (err) return console.error(err);
console.log('Users:', users);
});
MySQL with Sequelize
// Install Sequelize and MySQL2
// npm install sequelize mysql2
// Connect to database
const Sequelize = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'mysql',
logging: false // Disable SQL logging in console
});
// Define a model
const User = sequelize.define('User', {
name: {
type: Sequelize.STRING,
allowNull: false
},
email: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
validate: {
isEmail: true
}
},
age: {
type: Sequelize.INTEGER,
validate: {
min: 18
}
}
}, {
timestamps: true // Adds createdAt and updatedAt fields
});
// Sync model with database
sequelize.sync({ force: false }) // Set force: true to drop tables and recreate
.then(() => {
console.log('Database & tables created!');
});
// Create a new user
User.create({
name: 'Jane Doe',
email: 'jane@example.com',
age: 28
}).then(user => {
console.log('User created:', user.toJSON());
}).catch(err => {
console.error('Error creating user:', err);
});
// Find all users
User.findAll().then(users => {
console.log('All users:', users);
});
// npm install sequelize mysql2
// Connect to database
const Sequelize = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'mysql',
logging: false // Disable SQL logging in console
});
// Define a model
const User = sequelize.define('User', {
name: {
type: Sequelize.STRING,
allowNull: false
},
email: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
validate: {
isEmail: true
}
},
age: {
type: Sequelize.INTEGER,
validate: {
min: 18
}
}
}, {
timestamps: true // Adds createdAt and updatedAt fields
});
// Sync model with database
sequelize.sync({ force: false }) // Set force: true to drop tables and recreate
.then(() => {
console.log('Database & tables created!');
});
// Create a new user
User.create({
name: 'Jane Doe',
email: 'jane@example.com',
age: 28
}).then(user => {
console.log('User created:', user.toJSON());
}).catch(err => {
console.error('Error creating user:', err);
});
// Find all users
User.findAll().then(users => {
console.log('All users:', users);
});
Error Handling
Try-Catch & Async/Await
// Using try-catch with async/await
app.get('/user/:id', async (req, res, next) => {
try {
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
res.json(user);
} catch (err) {
next(err); // Pass to error handling middleware
}
});
// Using promises
app.get('/users', (req, res, next) => {
User.findAll()
.then(users => {
res.json(users);
})
.catch(err => {
next(err);
});
});
// Using a wrapper function to avoid try-catch repetition
const asyncHandler = fn => (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
// Usage
app.get('/user/:id', asyncHandler(async (req, res) => {
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
res.json(user);
}));
app.get('/user/:id', async (req, res, next) => {
try {
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
res.json(user);
} catch (err) {
next(err); // Pass to error handling middleware
}
});
// Using promises
app.get('/users', (req, res, next) => {
User.findAll()
.then(users => {
res.json(users);
})
.catch(err => {
next(err);
});
});
// Using a wrapper function to avoid try-catch repetition
const asyncHandler = fn => (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
// Usage
app.get('/user/:id', asyncHandler(async (req, res) => {
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
res.json(user);
}));
Custom Error Classes
// Custom error class
class AppError extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';
this.isOperational = true;
Error.captureStackTrace(this, this.constructor);
}
}
// Usage in route handlers
app.get('/protected', (req, res, next) => {
const token = req.headers.authorization;
if (!token) {
return next(new AppError('Access token required', 401));
}
// Continue processing...
res.json({ message: 'Access granted' });
});
// Global error handling middleware
app.use((err, req, res, next) => {
err.statusCode = err.statusCode || 500;
err.status = err.status || 'error';
if (process.env.NODE_ENV === 'development') {
res.status(err.statusCode).json({
status: err.status,
error: err,
message: err.message,
stack: err.stack
});
} else {
// Production: send minimal information
res.status(err.statusCode).json({
status: err.status,
message: err.isOperational ? err.message : 'Something went wrong!'
});
}
});
class AppError extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';
this.isOperational = true;
Error.captureStackTrace(this, this.constructor);
}
}
// Usage in route handlers
app.get('/protected', (req, res, next) => {
const token = req.headers.authorization;
if (!token) {
return next(new AppError('Access token required', 401));
}
// Continue processing...
res.json({ message: 'Access granted' });
});
// Global error handling middleware
app.use((err, req, res, next) => {
err.statusCode = err.statusCode || 500;
err.status = err.status || 'error';
if (process.env.NODE_ENV === 'development') {
res.status(err.statusCode).json({
status: err.status,
error: err,
message: err.message,
stack: err.stack
});
} else {
// Production: send minimal information
res.status(err.statusCode).json({
status: err.status,
message: err.isOperational ? err.message : 'Something went wrong!'
});
}
});
Deployment & Production
Environment Variables
// Install dotenv for local development
// npm install dotenv
// Create a .env file in root directory
// DB_HOST=localhost
// DB_USER=root
// DB_PASS=password
// JWT_SECRET=your-secret-key
// NODE_ENV=development
// Load environment variables
if (process.env.NODE_ENV !== 'production') {
require('dotenv').config();
}
// Access environment variables
const port = process.env.PORT || 3000;
const dbHost = process.env.DB_HOST;
const jwtSecret = process.env.JWT_SECRET;
// Use in application
mongoose.connect(`mongodb://${process.env.DB_HOST}/mydatabase`, {
useNewUrlParser: true,
useUnifiedTopology: true
});
app.listen(process.env.PORT || 3000, () => {
console.log(`Server running on port ${process.env.PORT || 3000}`);
});
// npm install dotenv
// Create a .env file in root directory
// DB_HOST=localhost
// DB_USER=root
// DB_PASS=password
// JWT_SECRET=your-secret-key
// NODE_ENV=development
// Load environment variables
if (process.env.NODE_ENV !== 'production') {
require('dotenv').config();
}
// Access environment variables
const port = process.env.PORT || 3000;
const dbHost = process.env.DB_HOST;
const jwtSecret = process.env.JWT_SECRET;
// Use in application
mongoose.connect(`mongodb://${process.env.DB_HOST}/mydatabase`, {
useNewUrlParser: true,
useUnifiedTopology: true
});
app.listen(process.env.PORT || 3000, () => {
console.log(`Server running on port ${process.env.PORT || 3000}`);
});
Process Managers
# Install PM2 globally
npm install -g pm2
# Start application with PM2
pm2 start app.js
# Start with name
pm2 start app.js --name "my-app"
# Monitor application
pm2 monit
# List all processes
pm2 list
# Stop process
pm2 stop my-app
# Restart process
pm2 restart my-app
# Delete process
pm2 delete my-app
# Startup script generation
pm2 startup
# Save current processes
pm2 save
# Cluster mode (utilize all CPUs)
pm2 start app.js -i max
# Using environment variables
pm2 start app.js --env production
npm install -g pm2
# Start application with PM2
pm2 start app.js
# Start with name
pm2 start app.js --name "my-app"
# Monitor application
pm2 monit
# List all processes
pm2 list
# Stop process
pm2 stop my-app
# Restart process
pm2 restart my-app
# Delete process
pm2 delete my-app
# Startup script generation
pm2 startup
# Save current processes
pm2 save
# Cluster mode (utilize all CPUs)
pm2 start app.js -i max
# Using environment variables
pm2 start app.js --env production