Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Installing and building

Pug is an npm package with functions for Node.js. You write templates in .pug files, and a short script calls Pug and writes finished .html files. You need Node.js 20 or newer.

Installing

Create a folder for the site and install Pug in it as a development dependency:

mkdir cafe
cd cafe
npm init -y
npm pkg set type=module
npm install --save-dev pug

npm init -y creates package.json, and npm pkg set type=module turns on ES modules in the project so you can write import instead of require.

Project structure

Templates live in src/, finished pages go to dist/:

cafe/
├── build.js        ← build script
├── dist/
│   └── index.html  ← created by Pug
├── src/
│   └── index.pug   ← edited by you
└── package.json

Create the file src/index.pug:

h1 Morning Café
p Fresh coffee every day from 8:00.

Two lines, two tags: a heading and a paragraph with text.

The build script

Create the file build.js in the project root:

// build.js
import { mkdirSync, writeFileSync } from "node:fs";
import pug from "pug";
 
const html = pug.renderFile("src/index.pug", { pretty: true });
 
mkdirSync("dist", { recursive: true });
writeFileSync("dist/index.html", html);
console.log("Done: dist/index.html");

pug.renderFile() reads the template and returns a string of HTML. The second argument holds options: pretty: true adds line breaks and indentation so the result is easy to read. Without it, Pug writes the whole page on one line — the browser does not care, and the file is smaller.

Running it

node build.js

The terminal prints "Done: dist/index.html", and the file contains this HTML:

<h1>Morning Café</h1>
<p>Fresh coffee every day from 8:00.</p>

Open dist/index.html in the browser and you will see the heading and the paragraph.

To avoid typing the whole command, add it to package.json and run npm run build:

{
  "scripts": {
    "build": "node build.js"
  }
}

Node.js watch mode helps rebuild pages after every edit: node --watch-path=src build.js runs the script again whenever anything in the src/ folder changes.

What about pug-cli?

Older guides run Pug with the pug command from the pug-cli package. That package has not been updated for a long time and uses Pug 2 inside, so this course uses its own script: it runs Pug 3 and is easy to extend once there are several pages.

Common mistake

An edit in src/index.pug does not show up in the browser, because the browser opens dist/index.html, which does not change by itself. After every template edit run npm run build, or keep watch mode running.

Thanks for reading!

Donate to the site — we work hard for you.