pug
A high-performance, whitespace-sensitive HTML template engine for Node.js, formerly known as Jade.
Repository Health
Technical Analysis
Pug (formerly Jade) is a template engine for Node.js and browsers that compiles a clean, indentation-based, whitespace-sensitive syntax into HTML. Rather than writing angle-bracket markup by hand, developers write terse block-structured templates with implicit tag nesting, inline JavaScript expressions, mixins, and template inheritance via extends/block/include.
Under the hood, Pug is a small compiler pipeline: source text is lexed into tokens, stripped of comments, parsed into an AST, resolved for include/extends relationships, passed through pluggable filters, linked, and finally compiled into a JavaScript function that renders to a string at runtime. This lets Pug precompile templates once and re-render them very quickly, which is why it has been a long-standing default view engine for Express applications.
The project ships as a monorepo of a dozen focused packages (pug-lexer, pug-parser, pug-code-gen, pug-runtime, pug-filters, pug-linker, pug-load, and others) under the pug umbrella package, each independently versioned and publishable, which lets tooling authors and porters to other languages reuse individual compiler stages without pulling in the whole engine.
What You Get
- A terse, indentation-based templating syntax that eliminates closing tags and HTML boilerplate
- A compiler pipeline (lex, parse, filter, link, code-gen) split into independently reusable npm packages
- Template inheritance and composition via
extends,block,include, and mixins - Compiled output as cacheable JavaScript functions for high-performance repeated rendering
- First-class Express integration through the
pug.__expressview-engine hook - A pluggable filter system for embedding other languages (Markdown, CoffeeScript, Stylus, etc.) inside templates
Common Use Cases
- Server-rendered HTML views in Express.js applications
- Precompiling templates to client-side JavaScript for browser rendering
- Generating static HTML output from build scripts or static site generators
- Embedding templated partials and layouts across multi-page Node.js apps
- Porting Pug’s syntax and semantics to template engines in other languages (PHP, Java, Python, Ruby, C#)
Under The Hood
Architecture
Pug is organized as a compiler pipeline, visible directly in packages/pug/lib/index.js: a template string is lexed by pug-lexer into tokens, stripped of comments by pug-strip-comments, parsed into an AST by pug-parser, resolved for include/extends relationships by pug-load, run through the pluggable filter system in pug-filters, resolved for inheritance by pug-linker, and finally turned into JavaScript source by pug-code-gen, which pug-runtime executes at render time. Each stage exposes pre*/post* plugin hooks (preLex, postParse, preCodeGen, etc.) so third-party plugins can rewrite tokens, AST, or generated code without forking the core. The whole engine ships as a Yarn/lerna-style monorepo of a dozen single-purpose packages under packages/, each independently versioned, so consumers or porters can depend on just the lexer or parser rather than the full engine — a design that clearly separates parsing concerns from code generation and lets other-language ports (pug-php, jade4j) reuse the same conceptual stages.
Tech Stack
The project is plain CommonJS JavaScript targeting Node.js, with no runtime framework dependency of its own — pug-runtime is a small helper library (attribute rendering, class/style merging, iteration helpers) that compiled templates call into. Build tooling is Yarn workspaces plus wsrun for staged cross-package builds, TypeScript (via tsconfig.json, strict: true) is used only for the scripts/ build tooling rather than the packages themselves, and jest (with custom snapshot serializers for filenames, Prettier-formatted output, and buffers) drives the test suite. Prettier enforces formatting (yarn prettier:check gates CI), and GitHub Actions (.github/workflows/test.yml) runs the suite across Node 10/12/14 before rollingversions publishes each changed package independently to npm.
Code Quality
Each pug-* package carries its own test/ directory, and the core pug package’s test/cases folder holds hundreds of paired .pug/.html fixture files exercising syntax edge cases, plus dedicated suites for error reporting (error.reporting.test.js), plugins (plugins.test.js), and ES2015 output. This fixture-driven, snapshot-style testing catches regressions in generated HTML precisely but leans on golden-file comparison rather than fine-grained unit assertions, and there is no noImplicitAny-style strict typing across the JS source itself (types exist only as hand-authored .d.ts files, not enforced by a type checker over the implementation). Error handling is explicit and structured via the dedicated pug-error package, which attaches file/line/column context to thrown errors rather than swallowing them. CI enforces formatting and test passage but the project has had long gaps between releases, visible in the development_activity/maintenance_consistency health scores.
What Makes It Unique Pug’s distinguishing choice is committing fully to significant-whitespace syntax for HTML rather than the angle-bracket-with-optional-shorthand approach used by Handlebars, EJS, or Nunjucks — closer in spirit to Haml, which the README credits directly as its influence. Its second distinguishing trait is architectural: splitting the compiler into a dozen independently publishable packages was unusually granular for a template engine in its era, and it’s what has let entirely separate implementations (PHP, Java, Python, Ruby, C#) reuse the “Pug syntax” as a portable specification rather than a single-language library. Neither trait is groundbreaking in isolation today — many modern engines compile to functions and cache them — but the combination of terse syntax plus a genuinely modular, porting-friendly compiler pipeline is what has kept Pug in wide use well past its Jade-era peak.
Used by 8 apps in this directory
Bigcapital
Invoicing Finance
Self-hostable double-entry accounting platform with invoicing, inventory, multi-currency, and real-time financial reporting for small and medium businesses.
CourseLit
Ecommerce · Blogging
Open-source, self-hosted LMS for selling online courses, digital downloads, and building communities on your own branded website.
overleaf
Collaboration · Productivity
Open-source, real-time collaborative LaTeX editor with sandboxed compilation and full TeXLive support for self-hosted academic and research teams.
overleaf
Collaboration · Productivity
Open-source, real-time collaborative LaTeX editor with sandboxed compilation and full TeXLive support for self-hosted academic and research teams.
PeerTube
Social Media
A federated, ActivityPub-based video hosting platform built by Framasoft — self-hostable instances interconnect into a network with no vendor lock-in, P2P-assisted streaming, and no ads.
VoidAuth
Security · Authentication
Self-hosted SSO with OIDC, LDAP, passkeys, and proxy auth for your entire self-hosted stack
Wiki.js
Knowledge Management · Collaboration
A modern, self-hosted wiki platform built on Node.js with a rich plugin ecosystem for authentication, search, storage, and rendering that adapts to any team's infrastructure.
Worklenz
Project Management · Product Management · Collaboration
All-in-one open source project management for teams who want full control — plan projects, track tasks, manage resources, and monitor finances without the SaaS lock-in.