Express setup, routers, error handling, security headers, and REST shapes are ready for backend spikes and interviews. Walk the Express roadmap when you want exercises that connect each snippet here into a complete service mindset.

Express.js learning roadmap — Routing, middleware, and API design as a structured Node journey.

Getting Started

Installation & Setup

# Create a new directory and initialize npm
mkdir my-express-app
cd my-express-app
npm init -y

# Install Express
npm install express

# Install nodemon for development (optional)
npm install --save-dev nodemon

# Basic package.json scripts
"scripts": {
  "start": "node app.js",
  "dev": "nodemon app.js"
}
Note: Nodemon automatically restarts your application when file changes are detected, which is helpful during development.

Basic Express Server

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

// Basic route
app.get('/', (req, res) => {
  res.send('Hello World!');
});

// Start server
app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});
Note: The order of middleware and routes is important in Express. They are executed in the order they are defined.

Routing

Basic Routing

// GET method route
app.get('/', (req, res) => {
  res.send('GET request to homepage');
});

// POST method route
app.post('/', (req, res) => {
  res.send('POST request to homepage');
});

// PUT method route
app.put('/user', (req, res) => {
  res.send('PUT request to /user');
});

// DELETE method route
app.delete('/user', (req, res) => {
  res.send('DELETE request to /user');
});

// ALL method route (matches all HTTP verbs)
app.all('/secret', (req, res) => {
  res.send('Accessing the secret section');
});

Route Parameters

// Route with parameters
app.get('/users/:userId', (req, res) => {
  res.send(`User ID: ${req.params.userId}`);
});

// Multiple route parameters
app.get('/users/:userId/books/:bookId', (req, res) => {
  res.send(`User ${req.params.userId}, Book ${req.params.bookId}`);
});

// Route with regex pattern
app.get('/product/:id(\\d+)', (req, res) => {
  // Only matches if id is a number
  res.send(`Product ID: ${req.params.id}`);
});

// Optional parameter
app.get('/archive/:year?/:month?/:day?', (req, res) => {
  const { year, month, day } = req.params;
  if (year) res.send(`Archive for: ${year}-${month || 'XX'}-${day || 'XX'}`);
  else res.send('Full archive');
});

// Query string parameters
app.get('/search', (req, res) => {
  const { q, page } = req.query;
  res.send(`Search for: ${q}, Page: ${page || 1}`);
});

Route Handlers

// Single callback function
app.get('/example', (req, res) => {
  res.send('Hello from example!');
});

// Multiple callback functions
app.get('/example', (req, res, next) => {
  console.log('First callback');
  next();
}, (req, res) => {
  res.send('Hello from second callback!');
});

// Array of callback functions
const cb1 = (req, res, next) => {
  console.log('CB1');
  next();
};

const cb2 = (req, res, next) => {
  console.log('CB2');
  next();
};

const cb3 = (req, res) => {
  res.send('Hello from CB3!');
};

app.get('/example', [cb1, cb2, cb3]);

// Combination of functions and arrays
app.get('/example', [cb1, cb2], (req, res) => {
  res.send('Combination of arrays and functions');
});

Router Object

// birds.js - Router module
const express = require('express');
const router = express.Router();

// Middleware specific to this router
router.use((req, res, next) => {
  console.log('Time: ', Date.now());
  next();
});

// Define routes
router.get('/', (req, res) => {
  res.send('Birds home page');
});

router.get('/about', (req, res) => {
  res.send('About birds');
});

// Route with parameter
router.get('/:birdId', (req, res) => {
  res.send(`Bird ID: ${req.params.birdId}`);
});

module.exports = router;

// app.js - Using the router
const birds = require('./birds');

// Mount the router
app.use('/birds', birds);

Middleware

Application Middleware

// Application-level middleware (no mount path)
app.use((req, res, next) => {
  console.log('Time:', Date.now());
  next();
});

// Application-level middleware (with mount path)
app.use('/user/:id', (req, res, next) => {
  console.log('Request Type:', req.method);
  next();
});

// Multiple middleware functions
app.use('/user/:id', (req, res, next) => {
  console.log('Request URL:', req.originalUrl);
  next();
}, (req, res, next) => {
  console.log('Request Type:', req.method);
  next();
});

// Built-in middleware
app.use(express.json()); // Parse JSON bodies
app.use(express.urlencoded({ extended: true })); // Parse URL-encoded bodies
app.use(express.static('public')); // Serve static files

// Third-party middleware
const cookieParser = require('cookie-parser');
app.use(cookieParser());

const helmet = require('helmet');
app.use(helmet());

const cors = require('cors');
app.use(cors());

Router Middleware

// Router-level middleware
const router = express.Router();

// Middleware for all requests to this router
router.use((req, res, next) => {
  console.log('Router middleware executed');
  next();
});

// Middleware for specific path
router.use('/admin', (req, res, next) => {
  // Check authentication
  if (req.headers.authorization) {
    next();
  } else {
    res.status(401).send('Unauthorized');
  }
});

// Error-handling middleware
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

// 404 handler (should be last)
app.use((req, res, next) => {
  res.status(404).send('Sorry, cannot find that!');
});

// Custom middleware example
const requestTime = (req, res, next) => {
  req.requestTime = Date.now();
  next();
};

app.use(requestTime);

app.get('/', (req, res) => {
  res.send(`Requested at: ${req.requestTime}`);
});

Request & Response

Request Object

// Common request properties
app.get('/user', (req, res) => {
  console.log(req.baseUrl); // Base URL
  console.log(req.body); // Request body (needs body-parser)
  console.log(req.cookies); // Cookies (needs cookie-parser)
  console.log(req.hostname); // Hostname
  console.log(req.ip); // Client IP
  console.log(req.method); // HTTP method
  console.log(req.params); // Route parameters
  console.log(req.path); // Path portion of URL
  console.log(req.protocol); // Request protocol
  console.log(req.query); // Query string parameters
  console.log(req.secure); // Boolean for HTTPS
  console.log(req.url); // URL
  console.log(req.xhr); // Boolean for XMLHttpRequest

  res.send('Check console for request details');
});

// Accessing headers
app.get('/headers', (req, res) => {
  console.log(req.headers); // All headers
  console.log(req.get('Content-Type')); // Specific header
  res.send('Headers logged');
});

Response Object

// Sending responses
app.get('/send', (req, res) => {
  res.send('Hello World!'); // Send string
  res.send({ message: 'Hello' }); // Send JSON
  res.send('<p>Some html</p>'); // Send HTML
  res.send(Buffer.from('hello')); // Send buffer
});

// Setting status codes
app.get('/status', (req, res) => {
  res.status(201).send('Created'); // Set status and send
  res.sendStatus(200); // Send just the status code
});

// Setting headers
app.get('/headers', (req, res) => {
  res.set('Content-Type', 'text/plain');
  res.set({
    'Content-Type': 'text/plain',
    'X-Custom-Header': 'value'
  });
  res.send('Headers set');
});

// Redirects
app.get('/redirect', (req, res) => {
  res.redirect('/new-path'); // Default 302
  res.redirect(301, '/permanent'); // 301 redirect
  res.redirect('https://example.com'); // External redirect
});

// Sending files
app.get('/file', (req, res) => {
  res.sendFile('/absolute/path/to/file.pdf');
});

// JSON responses
app.get('/json', (req, res) => {
  res.json({ user: 'tobi' }); // Content-Type: application/json
  res.jsonp({ user: 'tobi' }); // JSON with padding for JSONP
});

Templates & Views

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!',
    users: ['Alice', 'Bob', 'Charlie']
  });
});

// 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');

// Using Mustache
// npm install mustache-express
const mustacheExpress = require('mustache-express');
app.engine('mustache', mustacheExpress());
app.set('view engine', 'mustache');

// Serve static files
app.use(express.static('public'));

// Multiple static directories
app.use(express.static('public'));
app.use(express.static('uploads'));

// Virtual path prefix
app.use('/static', express.static('public'));

EJS Templates

<!-- views/index.ejs -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title><%= title %></title>
  <link rel="stylesheet" href="/css/style.css">
</head>
<body>
  <h1><%= message %></h1>
  
  <!-- JavaScript execution -->
  <% const date = new Date(); %>
  <p>Current date: <%= date.toLocaleDateString() %></p>
  
  <!-- Conditionals -->
  <% if (users.length > 0) { %>
    <ul>
      <% users.forEach(function(user) { %>
        <li><%= user %></li>
      <% }); %>
    </ul>
  <% } else { %>
    <p>No users found</p>
  <% } %>
  
  <!-- Includes -->
  <%- include('partials/footer') %>
</body>
</html>

<!-- views/partials/footer.ejs -->
<footer>
  <p>© 2023 My App</p>
</footer>

// Route to render the template
app.get('/', (req, res) => {
  res.render('index', {
    title: 'Home Page',
    message: 'Welcome to my app!',
    users: ['Alice', 'Bob', 'Charlie']
  });
});

Error Handling

Basic Error Handling

// Basic error-handling middleware
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

// Catching errors in routes
app.get('/error', (req, res, next) => {
  try {
    // Some operation that might fail
    throw new Error('Something went wrong!');
  } catch (err) {
    next(err); // Pass to error handler
  }
});

// Async error handling
app.get('/async-error', async (req, res, next) => {
  try {
    const data = await someAsyncOperation();
    res.json(data);
  } catch (err) {
    next(err);
  }
});

// 404 handler (should be last route)
app.use((req, res, next) => {
  res.status(404).send('Sorry, cannot find that!');
});

// 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);
  }
}

Advanced Error Handling

// 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') {
    // Development: send detailed error
    res.status(err.statusCode).json({
      status: err.status,
      error: err,
      message: err.message,
      stack: err.stack
    });
  } else {
    // Production: send minimal information
    const errorDetails = {
      status: err.status,
      message: err.isOperational ? err.message : 'Something went wrong!'
    };

    // Log error for monitoring
    console.error('ERROR 💥', err);

    res.status(err.statusCode).json(errorDetails);
  }
});

// Async error wrapper (avoid try-catch blocks)
const catchAsync = fn => {
  return (req, res, next) => {
    fn(req, res, next).catch(next);
  };
};

// Usage with async/await
app.get('/user/:id', catchAsync(async (req, res, next) => {
  const user = await User.findById(req.params.id);
  if (!user) {
    return next(new AppError('No user found with that ID', 404));
  }
  res.status(200).json({
    status: 'success',
    data: { user }
  });
}));

// Handle unhandled rejections
process.on('unhandledRejection', err => {
  console.log('UNHANDLED REJECTION! 💥 Shutting down...');
  console.log(err.name, err.message);
  server.close(() => {
    process.exit(1);
  });
});

// Handle uncaught exceptions
process.on('uncaughtException', err => {
  console.log('UNCAUGHT EXCEPTION! 💥 Shutting down...');
  console.log(err.name, err.message);
  process.exit(1);
});

REST API Development

Basic REST API

// Simple REST API for a resource
const express = require('express');
const app = express();

// Middleware to parse JSON bodies
app.use(express.json());

// In-memory "database"
let users = [
  { id: 1, name: 'John Doe', email: 'john@example.com' },
  { id: 2, name: 'Jane Smith', email: 'jane@example.com' }
];

// GET all users
app.get('/api/users', (req, res) => {
  res.json({
    status: 'success',
    results: users.length,
    data: { users }
  });
});

// GET single user
app.get('/api/users/:id', (req, res) => {
  const user = users.find(u => u.id === parseInt(req.params.id));
  if (!user) {
    return res.status(404).json({
      status: 'fail',
      message: 'User not found'
    });
  }
  res.json({
    status: 'success',
    data: { user }
  });
});

// POST create new user
app.post('/api/users', (req, res) => {
  const newId = users[users.length - 1].id + 1;
  const newUser = { id: newId, ...req.body };
  users.push(newUser);

  res.status(201).json({
    status: 'success',
    data: { user: newUser }
  });
});

// PATCH update user
app.patch('/api/users/:id', (req, res) => {
  const user = users.find(u => u.id === parseInt(req.params.id));
  if (!user) {
    return res.status(404).json({ message: 'User not found' });
  }

  // Update user properties
  Object.assign(user, req.body);

  res.json({
    status: 'success',
    data: { user }
  });
});

// DELETE user
app.delete('/api/users/:id', (req, res) => {
  const index = users.findIndex(u => u.id === parseInt(req.params.id));
  if (index === -1) {
    return res.status(404).json({ message: 'User not found' });
  }

  users.splice(index, 1);

  res.status(204).json({
    status: 'success',
    data: null
  });
});

API Best Practices

// API versioning
app.use('/api/v1/users', userRouter);
app.use('/api/v2/users', userRouterV2);

// Rate limiting
// npm install express-rate-limit
const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // Limit each IP to 100 requests per windowMs
  message: 'Too many requests from this IP, please try again later.'
});

app.use('/api', limiter);

// Data sanitization
// npm install express-mongo-sanitize
const mongoSanitize = require('express-mongo-sanitize');

app.use(mongoSanitize()); // Prevent NoSQL injection

// XSS protection
// npm install xss-clean
const xss = require('xss-clean');

app.use(xss()); // Prevent XSS attacks

// CORS
// npm install cors
const cors = require('cors');

app.use(cors()); // Enable all CORS requests

// Or configure CORS
app.use(cors({
  origin: 'https://yourdomain.com',
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization']
}));

// Helmet for security headers
// npm install helmet
const helmet = require('helmet');

app.use(helmet()); // Set various HTTP headers for security

// Compression
// npm install compression
const compression = require('compression');

app.use(compression()); // Compress responses

// Parameter pollution protection
// npm install hpp
const hpp = require('hpp');

app.use(hpp()); // Protect against HTTP Parameter Pollution attacks
Quick reference guide

Comprehensive Express.js Backend Cheatsheet Reference

This Express.js Backend cheatsheet on Nikhil Learn Hub collects syntax, commands, and practical snippets for quick revision. Explore Express.js routing, middleware, APIs, server setup, and backend development concepts with easy examples.

Use the reference cards and examples above during coding sessions; return here instead of scattered searches when you need dependable reminders. Follow the Express.js learning roadmap when you want structured lessons beyond one-page lookups.

Quick lookup coverage

  • Syntax, commands, and API signatures
  • Copy-ready examples and common patterns
  • Terminology for coursework and interviews
  • Cross-links to the matching learning roadmap

How to study with this sheet

  • Production debugging and tuning reminders
  • Security, performance, or scale cautions
  • Integration with adjacent stacks on this site
  • Deeper study through tutorials and roadmaps

Who Should Use This Cheatsheet

Students, self-taught developers, and professionals who need fast Express.js Backend lookups during labs, debugging, or interview revision should keep this page bookmarked.