What Is Pug?
Pug is a template engine and HTML preprocessor for Node.js. You write markup with indentation instead of angle brackets and closing tags, and Pug compiles it to HTML. It was originally called Jade and was renamed to Pug in 2016 after a trademark issue. It is open source under the MIT license, and the latest release on GitHub is pug 3.0.4. Pug is used most often as the view engine for Express apps, in email templates and in static site tooling.
Pug Syntax Basics
Nesting comes from indentation, and each line starts with a tag name.
doctype html
html(lang="en")
head
title My Page
body
h1 Welcome to my page
p This is my first Pug file.Pug compiles that to a normal HTML document. Some of the common patterns:
//- A comment that does not reach the output
a(href="/about" class="link") About
div#main.container
p.lead Hellodiv#main.container is shorthand for <div id="main" class="container">. Attributes go in parentheses, and text follows the tag on the same line.
Variables and interpolation
- const user = { name: 'Alex', role: 'admin' }
p Hello, #{user.name}
p= user.role#{} interpolates an escaped value into text, and p= outputs an escaped expression as the element's content. Use !{} or != only for trusted content, since they skip escaping.
Conditionals and loops
if items.length
ul
each item in items
li= item.title
else
p No items yet.Includes, layouts and mixins
This is where Pug cuts repetition.
//- layout.pug
doctype html
html
head
title #{title}
body
include header.pug
block content//- page.pug
extends layout.pug
block content
h1 Dashboard
+button('Save')//- mixins.pug
mixin button(label)
button.btn= labelextends and block give you template inheritance. include pulls in a partial. A mixin is a reusable function that outputs markup.
Installing and Using Pug
npm install pugWith Express, set Pug as the view engine and render a template with data:
import express from 'express';
const app = express();
app.set('view engine', 'pug');
app.set('views', './views');
app.get('/', (req, res) => {
res.render('index', { title: 'Home', items: [] });
});You can also compile templates yourself with the API:
import pug from 'pug';
const html = pug.render('p Hello #{name}', { name: 'Alex' });Benefits of Pug
- Less typing. No closing tags, and shorthand for ids and classes.
- Reusable structure. Includes, inheritance and mixins reduce duplication.
- Real logic. Variables, conditionals and loops live inside the template.
- Escaped output by default, which helps against cross-site scripting.
Downsides of Pug
- Indentation errors can break a whole template.
- A new syntax to learn and review, which is a cost for designers and teams used to HTML.
- It is server-side or build-time. Modern UI frameworks that render from state replace the need for string templates.
- Slower pace of change. It is stable and still receives patch releases, but it is not where most new front-end work happens.
Pug vs Mustache and Other Options
Pug has real logic and its own syntax. Mustache stays logic-less and uses plain HTML with tags, which makes it portable across languages. Handlebars sits in between. Component frameworks like React and Vue replace templates entirely, see my Vue 3 guide. If you are used to jQuery-era front ends, what jQuery is shows where much of this tooling came from.
Pick Pug for server-rendered Express apps, email templates and build-time HTML where you like compact syntax. Pick plain HTML with a lighter engine when your team wants templates to look like the output.
Frequently Asked
What is Pug used for? Generating HTML from compact, indentation-based templates, mostly in Node.js and Express apps.
Is Pug the same as Jade? Yes. Jade was renamed to Pug in 2016.
Is Pug still maintained? Yes, it still gets patch releases. The latest release on GitHub is 3.0.4.
Is Pug good for modern web apps? It works well for server-rendered pages and emails. For interactive UIs most teams choose component frameworks.
How do I use Pug with Express? Install pug, call app.set('view engine', 'pug'), and render templates with res.render('name', data).