Skip to content

Pug Templating with Express

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.
  • #{} interpolates escaped values; !{} outputs raw, unescaped HTML.
  • 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.