Express.js Basics
Set up Express.js applications and understand the basic structure and configuration
50 minā¢By Priygop Teamā¢Last updated: Feb 2026
Introduction to Express.js
Express.js is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. It simplifies the process of building web applications and APIs by providing a clean, simple API for handling HTTP requests and responses.
Setting Up Express.js
Example
// Install Express.js
npm install express
// Basic Express.js server
const express = require('express');
const app = express();
const port = 3000;
// Middleware for parsing JSON
app.use(express.json());
// Middleware for parsing URL-encoded bodies
app.use(express.urlencoded({ extended: true }));
// Basic route
app.get('/', (req, res) => {
res.send('Hello World!');
});
// Start server
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
// Express.js with ES modules
import express from 'express';
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});Express.js Application Structure
- app.js - Main application file with server setup
- routes/ - Directory for route handlers
- middleware/ - Custom middleware functions
- controllers/ - Business logic handlers
- models/ - Data models and database schemas
- config/ - Configuration files
- public/ - Static files (CSS, JS, images)
- views/ - Template files for rendering
Express.js vs Other Frameworks
- vs Koa.js: Express is more mature with larger ecosystem, Koa uses async/await
- vs Fastify: Express is simpler to learn, Fastify is faster but more complex
- vs Hapi.js: Express is more lightweight, Hapi has built-in features but heavier
- vs NestJS: Express is more flexible, NestJS is opinionated with TypeScript
- vs Sails.js: Express is minimal, Sails provides more structure out of the box
Express.js Core Features
Example
// Express.js core features demonstration
const express = require('express');
const app = express();
// 1. Middleware support
app.use((req, res, next) => {
console.log('Request received:', req.method, req.url);
next(); // Pass control to next middleware
});
// 2. Route parameters
app.get('/users/:id', (req, res) => {
res.json({ userId: req.params.id });
});
// 3. Query parameters
app.get('/search', (req, res) => {
res.json({ query: req.query.q, page: req.query.page });
});
// 4. Request body parsing
app.post('/users', express.json(), (req, res) => {
res.json({ message: 'User created', user: req.body });
});
// 5. Static file serving
app.use('/static', express.static('public'));
// 6. Template engine support
app.set('view engine', 'ejs');
app.get('/home', (req, res) => {
res.render('home', { title: 'Home Page' });
});
// 7. Error handling
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Something went wrong!' });
});
// 8. 404 handling
app.use((req, res) => {
res.status(404).json({ error: 'Route not found' });
});Express.js Best Practices
- Use environment variables: Store configuration in .env files
- Implement proper error handling: Use try-catch and error middleware
- Use middleware for common tasks: Logging, authentication, validation
- Organize routes: Separate route files for better maintainability
- Use HTTPS in production: Secure your application with SSL certificates
- Implement rate limiting: Prevent abuse and DoS attacks
- Use helmet for security: Set security-related HTTP headers
- Validate input data: Always validate and sanitize user input
Mini-Project: Express.js Starter App
Example
// Complete Express.js starter application
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
const rateLimit = require('express-rate-limit');
require('dotenv').config();
const app = express();
const PORT = process.env.PORT || 3000;
// security middleware
app.use(helmet());
app.use(cors());
// Rate limiting
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
app.use(limiter);
// Logging middleware
app.use(morgan('combined'));
// Body parsing middleware
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));
// Custom middleware for request timing
app.use((req, res, next) => {
req.startTime = Date.now();
next();
});
// Routes
app.get('/', (req, res) => {
res.json({
message: 'Welcome to Express.js Starter App',
version: '1.0.0',
timestamp: new Date().toISOString(),
uptime: process.uptime()
});
});
// Health check endpoint
app.get('/health', (req, res) => {
res.json({
status: 'healthy',
timestamp: new Date().toISOString(),
memory: process.memoryUsage(),
uptime: process.uptime()
});
});
// API routes
app.get('/api/users', (req, res) => {
const users = [
{ id: 1, name: 'John Doe', email: 'john@example.com' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }
];
res.json(users);
});
app.post('/api/users', (req, res) => {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({ error: 'Name and email are required' });
}
const newUser = {
id: Date.now(),
name,
email,
createdAt: new Date().toISOString()
};
res.status(201).json(newUser);
});
// Error handling middleware
app.use((err, req, res, next) => {
console.error('Error:', err);
res.status(500).json({
error: 'Internal Server Error',
message: process.env.NODE_ENV === 'development' ? err.message : 'Something went wrong'
});
});
// 404 handler
app.use((req, res) => {
res.status(404).json({ error: 'Route not found' });
});
// Graceful shutdown
process.on('SIGTERM', () => {
console.log('SIGTERM received, shutting down gracefully');
process.exit(0);
});
process.on('SIGINT', () => {
console.log('SIGINT received, shutting down gracefully');
process.exit(0);
});
// Start server
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
console.log(`Environment: ${process.env.NODE_ENV || 'development'}`);
});
module.exports = app;