Pug (formerly known as Jade) is a template engine with a terse, indentation-based syntax, no closing tags, no angle brackets, that many developers find faster to write once they're used to it. This lesson covers its core syntax.
Pug Syntax Basics
Pug uses indentation to represent HTML nesting, eliminating closing tags entirely. Tag names are written plainly (div, h1, p), classes and IDs use CSS-style shorthand (.card, #main), and dynamic values are interpolated with #{}.
Because there's no angle-bracket noise, Pug templates are often noticeably shorter than the equivalent HTML or EJS.
//- views/profile.pug
doctype html
html
body
h1 Hello, #{name}!
if isAdmin
p You have admin access.
Indentation alone defines nesting, h1 and if are siblings inside body; p is nested inside the if block.
Pug Syntax Reference
tag tag with no content
tag Text tag with plain text content
tag#id.class tag with id and class shorthand
#{variable} interpolation inside text
if condition
...
each item in items
...
Indentation is significant, mixing tabs and spaces inconsistently will break rendering.
#{} interpolates a value inside plain text; use !{} for unescaped output (careful with user data).
if/else/each map directly onto Pug's own control-flow keywords, no explicit <% %>-style delimiters needed.
Install with npm install pug, and set app.set('view engine', 'pug').
Pug Cheatsheet
Common Pug patterns for markup, data, and control flow.
Task
Syntax
Tag with class
div.card
Tag with id
div#main
Interpolation
p Hello #{name}
Attribute
a(href='/about') About
Conditional
if loggedIn / else
Loop
each item in items
Include
include partials/header
Looping and Attributes
Attributes are written in parentheses after the tag name, and each loops directly over an array passed from your route handler.
ul
each product in products
li
a(href=`/products/${product.id}`)= product.name
span= ` - $${product.price}`
Layout Inheritance With extends and block
Pug supports a powerful inheritance model: a base layout defines named blocks, and child templates extend that layout and fill in only the blocks they need to customize.
//- views/layout.pug
doctype html
html
head
title= title
body
block content
//- views/home.pug
extends layout
block content
h1 Welcome Home
Common Mistakes
Mixing tabs and spaces for indentation, which Pug treats as a syntax error.
Forgetting that Pug has no closing tags, so misplaced indentation silently changes nesting.
Using !{} for user-supplied content, bypassing escaping and risking XSS.
Writing overly complex logic in a template instead of preparing data beforehand in the route handler.
Key Takeaways
Pug uses indentation instead of closing tags for a terse, concise syntax.
if/each are Pug's native control-flow keywords, no extra delimiters needed.
extends/block provide a layout inheritance system for shared page structure.
Pro Tip
Configure your editor to insert spaces (not tabs) consistently before working with Pug, indentation-based syntax errors are notoriously confusing to debug when whitespace characters are mixed.
You now know Pug's syntax. Next, learn the mustache-style Handlebars syntax in the Handlebars lesson.