- Express.js Basics
- Express.js HOME
- Express.js Introduction
- Express.js Installation
- Express.js Basic App
- Express.js Routing
- Basics Routing
- Route Parameters
- Handling Query Strings
- Router Middleware
- Middleware
- What is Middleware?
- Application-Level Middleware
- Router-Level Middleware
- Built-In Middleware
- Error-Handling Middleware
- Third-Party Middleware
- Express.js HTTP
- Handling GET Requests
- Handling POST Requests
- Handling PUT Requests
- Handling DELETE Requests
- Templating Engines
- Using Templating Engines
- Setting Up EJS
- Setting Up Handlebars
- Setting Up Pug
- Request/Response
- Request Object
- Response Object
- Handling JSON Data
- Handling Form Data
- Static Files
- Serving Static Files
- Setting Up Static Folders
- Managing Assets
- Express.js Advanced
- Middleware Stack
- CORS in Express.js
- JWT Authentication
- Session Handling
- File Uploads
- Error Handling
- Databases
- Express.js with MongoDB
- MongoDB CRUD Operations
- Express.js with MySQL
- MySQL CRUD Operations
- Deployment
- Deploying Express.js Apps to Heroku
- Deploying Express.js Apps to AWS
- Deploying Express.js Apps to Vercel
Express.js Setting Up Pug
Pug (formerly known as Jade) is a high-performance templating engine for Node.js. It is widely loved by Express developers because it transforms the verbose, bracket-heavy syntax of standard HTML into a clean, indented format. By using Pug, you can write significantly less code while maintaining better readability.
Key Features of Pug
- Concise Syntax: Pug relies on indentation rather than closing tags (like </div>). This reduces "tag soup" and makes the structure of your page obvious at a glance.
- Dynamic Content: It bridges the gap between your JavaScript logic and your HTML, allowing you to inject variables directly into the view.
- Template Inheritance: This is a powerful feature that lets you define a "master layout" (with your head, navbar, and footer) and simply swap out the content for different pages.
- Partials: You can break your code into small, manageable chunks—like a separate file for a sidebar—and include them wherever needed.
Steps to Set Up Pug in Express.js
Step 1: Install Pug
First, you need to add the Pug package to your project dependencies. Open your terminal in your project root and run:
npm install pug
Step 2: Set Pug as the View Engine
Express needs to know which engine to use to process your templates. You configure this in your main server file (usually app.js or server.js):
const express = require('express');
const path = require('path');
const app = express();
// Set Pug as the view engine
app.set('view engine', 'pug');
// Tell Express where your template files are located
app.set('views', path.join(__dirname, 'views'));
path.join(__dirname, 'views') instead of a hardcoded string like './views'. This ensures your application finds the folder correctly regardless of which directory you start the node process from.
Step 3: Create the Views Folder
Create a folder named views in your project root. This is where Express will look for your templates by default.
Step 4: Create Your First Pug Template
Inside the views folder, create a file named index.pug. Notice how we use indentation instead of brackets:
doctype html
html
head
title= title
body
h1 Welcome to #{title}!
p This page was rendered using the Pug engine.
title= title and #{title}. Use tag= variable for escaping attributes/content entirely, and #{variable} for "interpolation" (mixing text and variables together).
Step 5: Render Views in Express Routes
Now, tell your route to "render" the file. Express will automatically look in the views folder and append the .pug extension.
app.get('/', (req, res) => {
// We pass an object containing our dynamic data
res.render('index', { title: 'My Express Application' });
});
Step 6: Run the Application
Start your server:
node app.js
Navigate to http://localhost:3000. You’ll see that Pug has compiled your shorthand code into standard HTML for the browser to read.
Using Template Inheritance in Pug
Template inheritance allows you to build a "skeleton" for your site so you don't have to rewrite the same HTML boilerplate on every single page.
Create a Layout Template (layout.pug)
The block content keyword acts as a placeholder where child pages will "inject" their specific code.
doctype html
html
head
title My Website
link(rel="stylesheet", href="/css/style.css")
body
header
nav
a(href="/") Home
a(href="/about") About
main
block content
footer
p © 2026 My Website
Extend the Layout (index.pug)
Now, your actual pages only need to focus on their unique content:
extends layout
block content
h2 Welcome to the Homepage!
p This content is being injected into the main layout template.
Passing Data and Logic to Pug
Pug isn't just for static text; you can pass complex objects and even use JavaScript logic like loops and conditionals.
Example: Rendering a List
app.get('/users', (req, res) => {
const users = ['Alice', 'Bob', 'Charlie'];
res.render('users', { userList: users });
});
In views/users.pug, you can loop through the array easily:
extends layout
block content
h1 User Directory
ul
each user in userList
li= user
else
li No users found.
else block inside an each loop in Pug is incredibly useful—it runs automatically if the array is empty.
Using Partials in Pug
Partials are perfect for UI components like buttons, contact forms, or navigation bars that appear on multiple pages but aren't necessarily part of the main layout.
Create a Partial (views/includes/nav.pug):
nav.main-navigation
ul
li: h3 Navigation
li: a(href="/") Home
li: a(href="/contact") Contact
Include the Partial:
body
include includes/nav
h1 Main Page Content
Using Helpers in Pug
Sometimes you need to format data (like dates or currency) before displaying it. You can pass functions from your route directly into the view.
app.get('/profile', (req, res) => {
const helpers = {
shout: (text) => text.toUpperCase()
};
res.render('profile', { name: 'John Doe', ...helpers });
});
In views/profile.pug:
h1 User Profile
p User Name: #{shout(name)}
app.locals. For example: app.locals.formatPrice = (num) => '$' + num.toFixed(2);. This makes the function available in all Pug templates without passing it manually in every route.
Summary
Pug is a powerful ally for Express.js developers, offering a "write less, do more" approach to HTML. By mastering indentation, template inheritance, and partials, you can build modular, maintainable front-ends with very little overhead. Whether you are building a simple blog or a complex dashboard, Pug's clean syntax helps you stay focused on your application logic rather than wrestling with closing HTML tags.