Pug (до 2016 года — Jade) — это шаблонизатор и препроцессор HTML для Node.js. Вы пишете разметку без угловых скобок и закрывающих тегов: вложенность задаётся отступами, а данные из приложения подставляются через переменные. Pug компилируется в обычный HTML — на CLI или на лету внутри Express через res.render(). Ниже — полный синтаксис с рабочими примерами, подключение к Express и сравнение с EJS и Handlebars.
Коротко о главном:
- Отступы вместо тегов — меньше символов, чище вложенность.
- Переменные
#{name}, условияif, циклыeach— полноценный JavaScript в шаблоне. - Наследование
extends/blockи миксиныmixinубирают дублирование. - Нативная интеграция с Express:
app.set('view engine', 'pug'). - Минус — чувствительность к пробелам и лишний шаг компиляции.
Что такое Pug и зачем он нужен
По данным expressjs.com.
Pug — самый популярный язык шаблонов в экосистеме Node.js, написанный на JavaScript. По описанию MDN, это «чистый, чувствительный к пробелам синтаксис для написания HTML, испытавший сильное влияние Haml». Идея простая: браузер всё равно получает HTML, но писать вы его будете компактнее. Первое слово в строке — это HTML-элемент, а отступ следующей строки означает вложенность.
Сравните один и тот же фрагмент. HTML:
<div class="container">
<h1>Hello, World</h1>
<p>This is a paragraph.</p>
</div>
Тот же результат на Pug:
.container
h1 Hello, World
p This is a paragraph.
Закрывать теги не нужно — структуру держит отступ. На больших страницах это экономит десятки строк и убирает целый класс ошибок с незакрытыми тегами. Мини-вывод: Pug не заменяет HTML, а даёт над ним более лаконичный слой, который затем компилируется обратно в валидную разметку.

- ПОКАЖЕМ, КАК РАЗВЕРНУТЬ МОДЕЛЬ нейросети DEEPSEEK R1 ПРЯМО НА СВОЁМ КОМПЬЮТЕРЕ
- Где и как применять? Потестируем модель после установки на разных задачах
- Как дообучить модель под себя?
Установка Pug
Нужен установленный Node.js. Дальше ставим пакет через npm:
npm install pug
Для разовой компиляции файла в HTML пригодится CLI-утилита:
npm install -g pug-cli
pug index.pug
После команды рядом с index.pug появится готовый index.html. В реальном приложении файлы чаще компилируются не вручную, а автоматически — через шаблонизацию Express (об этом ниже) или сборщик.
Синтаксис Pug: отступы, теги, атрибуты, интерполяция
Разберём базовые кирпичи по порядку — этого достаточно, чтобы верстать реальные страницы.
Теги и вложенность
Имя тега пишется в начале строки, текст — после пробела. Вложенность — отступом (используйте либо только пробелы, либо только табы, не смешивайте):
ul
li Первый пункт
li Второй пункт
Классы, идентификаторы и div по умолчанию
Классы задаются точкой, id — решёткой. Если перед .class или #id нет имени тега, Pug подставляет div:
a.button.button--primary(href="/") Кнопка
#main.wrapper
p Здесь div#main.wrapper
Атрибуты
Атрибуты перечисляются в скобках через запятую. Значения — обычные JavaScript-выражения, поэтому их можно собирать динамически:
a(href="https://example.com", target="_blank", rel="noopener") Ссылка
input(type="checkbox", checked)
img(src="/img/" + fileName, alt=altText)
Интерполяция и текст
Переменная в тексте подставляется через #{...} (значение экранируется), небезопасный HTML — через !{...}. Буферизованный вывод выражения в тег — знаком =. Блок текста задаётся точкой после тега, а строчная разметка — тег-интерполяцией #[...]:
- var user = "Мир"
h1 Привет, #{user}!
p= "Сумма: " + (2 + 2)
p.
Многострочный
блок текста.
p Нажмите #[strong сюда], чтобы продолжить.
Комментарии
Двойной слэш даёт видимый HTML-комментарий, //- — «немой», который в вывод не попадёт:
// этот комментарий попадёт в HTML
//- а этот останется только в шаблоне
Переменные, условия и циклы
Строка, начинающаяся с -, — это небуферизованный JavaScript (логика без вывода). Строка с = выводит результат выражения. Данные обычно приходят из приложения, но локальные переменные можно объявлять прямо в шаблоне:
- var items = ["Node", "Pug", "Express"]
- var isAdmin = true
Условия читаются как обычный JavaScript, плюс есть удобный инвертированный unless и case/when:
if isAdmin
p Панель администратора
else
p Гостевой режим
unless items.length
p Список пуст
case status
when "ok": p Готово
when "error": p Ошибка
default: p Неизвестно
Массивы и объекты перебираются через each (со вторым параметром-индексом), а while крутит цикл по условию:
ul
each item, index in items
li #{index + 1}. #{item}
- var n = 0
while n < 3
li Строка #{n++}
Мини-вывод: в отличие от «логически бедных» шаблонизаторов, Pug даёт полный JavaScript. Это гибко, но требует дисциплины — тяжёлую логику лучше держать в контроллере, а в шаблоне оставлять только отображение.
Миксины: переиспользуемые блоки
Миксин — это функция, возвращающая кусок разметки. Объявляется через mixin, вызывается через +. Принимает аргументы и может получать вложенный блок:
mixin card(title, text)
.card
h3= title
p= text
+card("Pug", "Шаблонизатор для Node.js")
+card("Express", "Веб-фреймворк")
Миксин с блоком удобен для оболочек — например, обёртки вокруг произвольного содержимого:
mixin panel(header)
.panel
.panel__head= header
.panel__body
block
+panel("Заголовок")
p Любое содержимое внутри панели.
Наследование шаблонов: extends и block
Наследование разбивает сложную страницу на простые файлы. Родительский шаблон описывает общий каркас и объявляет именованные block, а дочерние шаблоны через extends замещают эти блоки. Базовый макет layout.pug:
doctype html
html
head
title Мой сайт
block styles
body
block content
footer © 2026
Дочерняя страница переопределяет только нужные блоки:
extends layout.pug
block content
h1 Главная
p Содержимое страницы.
Блок можно не замещать целиком, а дополнять — block append добавит содержимое в конец, block prepend — в начало. Это удобно для подключения страничных стилей поверх общих:
extends layout.pug
block append styles
link(rel="stylesheet", href="/css/home.css")
Родственный механизм — include: он просто вставляет содержимое другого файла (шапку, подвал, партиал) без логики замещения:
include ./partials/header.pug
Как подключить Pug в Express

Express «из коробки» умеет работать с Pug — генератор приложений Express даже использует его по умолчанию. Настройка занимает две строки. Укажите папку с шаблонами и движок представления:
const express = require('express');
const path = require('path');
const app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
Создайте шаблон views/index.pug. Данные придут из маршрута через переменные:
html
head
title= title
body
h1= message
В маршруте вызовите res.render() — первым аргументом имя шаблона (расширение .pug можно опустить), вторым объект с данными:
app.get('/', (req, res) => {
res.render('index', { title: 'Hey', message: 'Hello there!' });
});
Express скомпилирует шаблон при запросе и отдаст клиенту готовый HTML. Никакого ручного вызова pug в этом сценарии не нужно — компиляция встроена в цикл ответа.
Pug против EJS и Handlebars: что выбрать
Pug — не единственный вариант для Express. Три самых частых конкурента отличаются философией: Pug задаёт собственный синтаксис, EJS встраивает JavaScript прямо в HTML (<% %>), а Handlebars использует «логически бедные» усы {{ }}. Сводка по ключевым критериям:
| Критерий | Pug | EJS | Handlebars |
|---|---|---|---|
| Синтаксис | Свой, на отступах | HTML + вставки JS | HTML + {{ }} |
| Порог входа | Высокий (новый язык) | Низкий (почти чистый HTML) | Низкий |
| Логика в шаблоне | Полный JavaScript | Полный JavaScript | Ограниченная (хелперы) |
| Наследование макетов | Нативно (extends/block) | Через partials/include | Partials + layout-плагины |
| Миксины / переиспользование | mixin | Функции, include | Partials, helpers |
| Валидный HTML на входе | Нет (нужна перекомпиляция) | Да | Да |
| Многословность | Минимальная | Высокая | Средняя |
Практический ориентир. Берите Pug, если цените компактность и активно используете наследование и миксины, а команда готова выучить синтаксис. EJS — когда нужен минимальный порог входа и возможность копировать готовую HTML-вёрстку почти без правок. Handlebars — когда важна строгая изоляция логики от представления (например, шаблоны редактируют не-разработчики).

- ПОКАЖЕМ, КАК РАЗВЕРНУТЬ МОДЕЛЬ нейросети DEEPSEEK R1 ПРЯМО НА СВОЁМ КОМПЬЮТЕРЕ
- Где и как применять? Потестируем модель после установки на разных задачах
- Как дообучить модель под себя?
Недостатки Pug, о которых стоит знать заранее
- Чувствительность к пробелам. MDN прямо отмечает: лишний пробел «не в том месте» может дать невнятную ошибку. На старте это главный источник боли.
- Новый синтаксис. Разработчику, привыкшему к HTML, нужно время на переучивание — и на онбординг новых людей в проект.
- Отдельный шаг компиляции. Браузер не понимает Pug напрямую: код всегда нужно превращать в HTML перед отдачей клиенту.
- Поддержка в IDE слабее. Инструменты вокруг Pug беднее, чем вокруг чистого HTML, — местами страдают автодополнение и отладка.
Мини-вывод: минусы Pug сводятся к цене входа и дополнительному звену в сборке. Если проект живёт долго и в нём много повторяющейся разметки, эта цена окупается за счёт лаконичности и наследования.
Итоговый чек-лист по Pug
- Один тип отступа на весь файл — либо пробелы, либо табы.
- Данные подставляйте через
#{}и=, тяжёлую логику держите в контроллере. - Повторяющиеся куски — в миксины, общий каркас — в
layout.pugсblock. - В Express достаточно
app.set('view engine', 'pug')иres.render(). - Сомневаетесь в пороге входа команды — сравните с EJS по таблице выше.
Pug — зрелый инструмент, который окупается на страницах со сложной и повторяющейся структурой. Освойте синтаксис, наследование и миксины на небольшом проекте, подключите к Express — и дальше решайте по таблице, подходит ли он вашей команде.
- Освой нейросеть Perplexity и узнай, как пользоваться функционалом остальных ИИ в одном
- УЧАСТВОВАТЬ ЗА 0 РУБ.
- Расскажем, как получить подписку
- ПОКАЖЕМ, КАК РАЗВЕРНУТЬ МОДЕЛЬ нейросеть DEEPSEEK R1 ПРЯМО НА СВОЁМ КОМПЬЮТЕРЕ