# Pug: Indentation-Based HTML Template Engine for Node.js

> Pug is a Node.js template engine that replaces HTML's angle-bracket syntax with indentation-based structure, formerly known as Jade, distributed as the `pug` npm package with a monorepo of twelve separate sub-packages covering lexing, parsing, code generation, and runtime.

**pugjs/pug** — Pug – robust, elegant, feature rich template engine for Node.js

- Repository: https://github.com/pugjs/pug
- Website: https://pugjs.org
- Stars: 21,837 · Forks: 1,935
- Language: JavaScript
- License: not declared
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/pugjs-pug

## What Pug Is and Who It Is For

Pug is a template engine for Node.js that takes a concise indentation-based syntax and compiles it to HTML. Instead of writing opening and closing angle-bracket tags, you write a tag name at the start of a line and indent its children underneath it. Whitespace is structural; two spaces or a tab of indentation make an element a child of the element on the line above.

The primary audience is Node.js developers building server-rendered web applications. Pug integrates with Express as a view engine and has adapters for Laravel, Symfony, Rails, and several other frameworks listed in the README. Teams that already use a whitespace-sensitive tool like HAML (for Ruby) or Slim will find Pug's philosophy familiar.

Pug was formerly known as Jade. The name changed at version 2 due to a trademark conflict, and all new versions have been published under the `pug` npm package name since then. The old `jade` package name is still held by the project but no longer receives updates.

## How Pug's Syntax Works

Pug removes most of the punctuation from HTML. A `div` with an id and a class is written as `#container.col` instead of `<div id="container" class="col">`. Attributes go in parentheses after the tag name. Text content sits on the same line as the tag or on indented lines below it.

The README gives a clear demonstration. The template:

```pug
doctype html
html(lang="en")
  head
    title= pageTitle
    script(type='text/javascript').
      if (foo) bar(1 + 5);
  body
    h1 Pug - node template engine
    #container.col
      if youAreUsingPug
        p You are amazing
      else
        p Get on it!
```

produces the equivalent HTML with all opening and closing tags, doctype declaration, and attribute quoting. The `=` after `title` means the tag's text content comes from the `pageTitle` variable rather than being literal text. A dot after a tag name (as in `script.`) means the entire indented block is raw text content rather than further template syntax.

Control flow (if, else, each, while) is supported natively without extra template syntax characters. Variables are passed in through a locals object when rendering.

## Installing Pug and Using the Command Line

Install Pug as a Node.js package:

```bash
$ npm install pug
```

For command-line compilation, install the CLI globally:

```bash
$ npm install pug-cli -g
```

Then compile a template file from the command line:

```bash
$ pug --help
```

To pre-compile a template for browser use, which converts the template to a standalone JavaScript function:

```bash
$ pug --client --no-debug filename.pug
```

This produces `filename.js` containing the compiled template function. Pre-compiling for the browser avoids sending the Pug runtime to the client. The README notes that the latest browser build of the runtime is available for download from pugjs.org/js/pug.js, but it only supports recent browsers and is a large file, making pre-compilation the preferred approach for production.

## Using Pug Programmatically in Node.js

Pug exposes three primary functions through its API:

```js
var pug = require('pug');

// compile
var fn = pug.compile('string of pug', options);
var html = fn(locals);

// render
var html = pug.render('string of pug', merge(options, locals));

// renderFile
var html = pug.renderFile('filename.pug', merge(options, locals));
```

`pug.compile` takes a Pug string and returns a function that accepts locals. Call that function repeatedly with different locals to render the same template multiple times without recompiling. `pug.render` compiles and renders in one step. `pug.renderFile` reads a file from disk, compiles it, and renders it with the provided locals.

Common options include `filename` (required when using includes), `compileDebug` (false removes debug instrumentation for smaller output), and `pretty` (false by default; enabling it adds indentation whitespace to the HTML output). The full API reference is at pugjs.org/api/reference.html.

## The Monorepo Structure and Sub-Packages

The Pug repository is a monorepo containing twelve separate npm packages. The root package.json is private and marked as a monorepo; the individual packages live in the packages/ directory. The sub-packages cover each stage of the compilation pipeline:

pug-lexer converts the Pug source string into tokens. pug-parser converts the token stream into an abstract syntax tree. pug-linker resolves includes and extends. pug-load handles file loading. pug-filters processes filter blocks. pug-code-gen converts the AST into a JavaScript function string. pug-runtime provides the helper functions called by the generated code at render time. pug-error standardizes error objects. pug-attrs handles attribute generation. pug-walk provides tree traversal utilities. pug-strip-comments removes comment nodes.

This separation means downstream tools can use only the stages they need. A syntax highlighter might use pug-lexer without needing pug-code-gen. The test suite uses Jest, configured in the root package.json.

## Limitations: Maintenance Status and Ecosystem Fit

The last release was pug@3.0.4, published on 2026-03-13, which is more than six months before September 2026. The README does not document a planned 4.0 release or a roadmap.

Whitespace-significant syntax is Pug's core feature and its main limitation. Any indentation error silently changes the structure of the generated HTML rather than producing an obvious error. Mixing tabs and spaces, which many editors do by default, causes incorrect output. Teams that expect HTML templates to be self-contained and readable without a tool to render them may find Pug's syntax opaque.

Pug does not include a way to embed Pug templates in non-Node.js backends without one of the ports listed in the README. PHP, Java, Python, and Ruby ports exist but may lag behind the reference implementation. The PHP and Java ports are the most prominently listed in the README.

The `compileDebug` option defaults to true, which includes line-number mappings in the compiled output. This is useful for debugging but increases the size of the compiled function. Turn it off for production builds.

## Pug vs Handlebars: Syntax Tradeoffs

Handlebars is the most commonly compared alternative to Pug for Node.js template rendering. Handlebars keeps HTML as the base language and adds a thin layer of `{{ }}` delimiters for variable interpolation and block helpers. The output HTML structure is directly visible in the Handlebars template, which makes the template readable without running it.

Pug replaces HTML syntax entirely. The output structure is inferred from indentation, which produces more concise templates at the cost of immediate readability for anyone unfamiliar with the syntax. A Pug template file looks nothing like its HTML output.

Handlebars is deliberately logic-minimal; it discourages embedding application logic in templates. Pug supports conditionals, loops, and includes directly in templates without a separate helper registration step. Both are MIT licensed and available on npm.

## Conclusion

Pug suits teams that value concise template syntax and use Node.js with a framework that integrates Pug's view engine, such as Express. It is the wrong choice for projects where template files are edited by people unfamiliar with significant-whitespace syntax or where non-JavaScript backend developers need to read the templates. The last release was pug@3.0.4 on 2026-03-13, which is more than six months before September 2026. Run `npm install pug` to get that release, but plan for the possibility that issues will be addressed slowly. Check that your framework adapter is compatible with pug@3 before upgrading from pug@2.

## FAQ

### Why use Pug instead of HTML?

Pug reduces the amount of text needed to write HTML: no closing tags, shorter attribute syntax, and a built-in include system for partials. It also supports variables, conditionals, and loops directly in the template. The trade-off is that the output HTML is not directly visible in the template source.

### What is Pug in Node.js development?

In Node.js development, Pug is a template engine used to generate HTML on the server. It integrates with Express and other frameworks as a view engine, taking a Pug file and a locals object as inputs and producing the rendered HTML string as output.

### How do you install Pug?

Run `npm install pug` in your Node.js project. For command-line compilation, install the CLI globally with `npm install pug-cli -g`. The last release is pug@3.0.4.

## Sources

- [Issues](https://github.com/pugjs/pug/issues)
- [Project website](https://pugjs.org)
- [pugjs/pug on GitHub](https://github.com/pugjs/pug)
- [README](https://github.com/pugjs/pug/blob/master/README.md)
- [Releases](https://github.com/pugjs/pug/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/pugjs-pug
