zig-pug
v4.1.2
Published
High-performance Pug template engine powered by Zig and mujs. Native N-API addon with ES5.1 JavaScript support, full UTF-8 (emoji, accents), Builder API for dynamic data construction, comprehensive C/C++ API, and fast compilation. Compatible with Node.js
Maintainers
Readme
zig-pug
High-performance Pug template engine powered by Zig and mujs.
Features
- ✅ Pug syntax - Tags, attributes, classes, IDs
- ✅ JavaScript expressions - ES5.1 interpolation powered by mujs
- ✅ Full UTF-8 support - Emoji 🎉, accents (á é ñ ü), all Unicode
- ✅ Documentation comments -
//!for file metadata (ignored by parser) - ✅ Conditionals - if/else/unless
- ✅ Mixins - Reusable components
- ✅ Dual package - CommonJS (
require) and ES Modules (import) - ✅ TypeScript support - Full type definitions included
- ✅ Bun.js compatible - 2-5x faster than Node.js
- ✅ Structured errors - Detailed error messages with line numbers, hints, and context
- ✅ Output formatting - Minify, pretty-print, or format modes
- ⚡ Native performance - Written in Zig, compiled to native code
- 🔋 Zero dependencies - Only Zig and embedded mujs
- 🌍 i18n ready - Spanish, Portuguese, French, German, and more
Installation
npm install zig-pugRequirements:
- Node.js >= 14.0.0
- C/C++ compiler (GCC, Clang, or MSVC)
- Python (for node-gyp)
The addon will compile automatically during installation.
Quick Start
Simple API
CommonJS (Node.js):
const zigpug = require('zig-pug');
const html = zigpug.compile('p Hello #{name}!', { name: 'World' });
console.log(html);
// <p>Hello World!</p>ES Modules (Node.js, Bun):
import { compile } from 'zig-pug';
const html = compile('p Hello #{name}!', { name: 'World' });
console.log(html);
// <p>Hello World!</p>Object-Oriented API
CommonJS (Node.js):
const { PugCompiler } = require('zig-pug');
const compiler = new PugCompiler();
compiler
.set('title', 'My Page')
.set('version', 1.5)
.setBool('isDev', false);
const html = compiler.compile('h1 #{title}');
console.log(html);
// <h1>My Page</h1>ES Modules (Node.js, Bun):
import { PugCompiler } from 'zig-pug';
const compiler = new PugCompiler();
compiler
.set('title', 'My Page')
.set('version', 1.5)
.setBool('isDev', false);
const html = compiler.compile('h1 #{title}');
console.log(html);
// <h1>My Page</h1>Output Formatting
zig-pug supports multiple output modes to suit different use cases:
Default (Minified)
By default, HTML is minified for production use:
const compiler = new PugCompiler();
const html = compiler.compile('div\n h1 Hello\n p World');
// Output: <div><h1>Hello</h1><p>World</p></div>Pretty Mode (Development)
Pretty-print with indentation and HTML comments for debugging:
const compiler = new PugCompiler({ pretty: true });
const html = compiler.compile('div\n h1 Hello\n p World');
// Output:
// <div>
// <h1>Hello</h1>
// <p>World</p>
// </div>Format Mode (Readable)
Pretty-print without comments for readable production output:
const compiler = new PugCompiler({ format: true });
const html = compiler.compile('div\n h1 Hello\n p World');
// Output: formatted HTML without commentsMinify Mode (Explicit)
Explicitly minify to ensure smallest file size:
const compiler = new PugCompiler({ minify: true });
const html = compiler.compile('div\n h1 Hello\n p World');
// Output: <div><h1>Hello</h1><p>World</p></div>Override Options at Compile Time
The hybrid approach allows you to set default options in the constructor and override them per compilation:
// Create compiler with minify by default
const compiler = new PugCompiler({ minify: true });
compiler.set('title', 'Hello');
// Production build (uses default minify)
const prod = compiler.compile('h1= title');
// Debug build (overrides with pretty)
const debug = compiler.compile('h1= title', { pretty: true });
// Readable build (overrides with format)
const readable = compiler.compile('h1= title', { format: true });Express Integration
const express = require('express');
const zigpug = require('zig-pug');
const fs = require('fs');
const app = express();
// Load template once at startup
const homeTemplate = fs.readFileSync('./views/home.pug', 'utf-8');
app.get('/', (req, res) => {
const html = zigpug.compile(homeTemplate, {
title: 'Home',
user: req.user
});
res.send(html);
});
app.listen(3000);Bun.js Support
zig-pug works seamlessly with Bun, the ultra-fast JavaScript runtime:
bun install zig-pug
bun run app.jsPerformance: Bun is 2-5x faster than Node.js for template compilation.
See examples/bun/ for complete examples.
TypeScript Support
zig-pug includes full TypeScript definitions for enhanced development experience with IntelliSense and type safety.
Basic Usage
import { compile, PugCompiler, ZigPugCompilationError } from 'zig-pug';
// Simple compilation with type inference
const html: string = compile('p Hello #{name}', { name: 'TypeScript' });
// Using PugCompiler class with formatting options
const compiler: PugCompiler = new PugCompiler({ pretty: true });
compiler
.setString('title', 'My Page')
.setNumber('count', 42)
.setBool('active', true);
const result: string = compiler.compile('h1= title');Error Handling with Types
try {
const html = compile(template, variables);
} catch (error) {
const err = error as ZigPugCompilationError;
if (err.compilationErrors) {
const { errorCount, errors } = err.compilationErrors;
errors.forEach(e => {
console.error(`Line ${e.line}: ${e.message}`);
if (e.detail) console.error(` Detail: ${e.detail}`);
if (e.hint) console.error(` Hint: ${e.hint}`);
});
}
}Available Types
PugCompiler- Main compiler classPugVariables- Type for template variablesCompilationOptions- Formatting options (pretty, format, minify)CompilationErrorInfo- Individual error informationCompilationErrors- Collection of compilation errorsZigPugCompilationError- Extended Error with compilation detailsErrorType- Error type classification enum
See examples/nodejs/08-typescript-example.ts for complete TypeScript examples.
Pug Syntax
Tags and Attributes
div.container
h1#title Hello World
p.text(data-id="123") Content
a(href="/" target="_blank") LinkJavaScript Interpolation
p Hello #{name}!
p Age: #{age + 1}
p Email: #{email.toLowerCase()}
p Status: #{age >= 18 ? 'Adult' : 'Minor'}
p Max: #{Math.max(10, 20)}Supported JavaScript (ES5.1):
- String methods:
toLowerCase(),toUpperCase(),split(), etc. - Math:
Math.max(),Math.min(),Math.random(), etc. - Operators:
+,-,*,/,%,&&,||,?: - Object/Array access:
obj.prop,arr[0],arr.length
Conditionals
if isLoggedIn
p Welcome back!
else
p Please log in
unless isAdmin
p Access deniedMixins
mixin button(text)
button.btn= text
+button('Click me')
+button('Submit')UTF-8 & Unicode Support
Full support for international characters, emoji, and symbols:
//! File: index.pug
//! Author: Carlos
doctype html
html(lang="es")
head
title #{titulo}
body
h1 ¡Bienvenido! 🎉
section.español
p.información Información sobre José y María
p#descripción Este párrafo tiene ID con acento
section.português
h2 Programação em português
p Características: ã, õ, ç
section.français
h2 Génération française
p Avec é, è, ê, ç
footer
p © 2025 - Creado con zig-pug 🚀Supported everywhere:
- ✅ Text content:
p José, María, Ángel - ✅ Class names:
.información .português - ✅ ID attributes:
#descripción #größe - ✅ Comments:
// útil para depuración - ✅ Emoji:
h1 Hello 🎉 🚀 ✨ - ✅ Symbols:
p © ™ € £ ¥
Documentation Comments
Use //! for file metadata that won't appear in output:
//! Template: homepage.pug
//! Author: John Doe
//! Version: 1.0
//! Description: Main landing page
doctype html
html
body
// Regular comment (appears in --pretty mode)
//- Code comment (never appears)| Syntax | Name | In HTML? | Use Case |
|--------|------|----------|----------|
| //! | Documentation | ❌ Never | File metadata, notes |
| // | Buffered | ✅ Dev mode | Development debugging |
| //- | Unbuffered | ❌ Never | Code comments |
API Reference
compile(template, data, options)
Compile a template with data and formatting options.
Parameters:
template(string) - Pug template sourcedata(object) - Variables to interpolateoptions(object) - Formatting options (optional)pretty(boolean) - Enable pretty-print with commentsformat(boolean) - Enable pretty-print without commentsminify(boolean) - Enable HTML minificationincludeComments(boolean) - Include HTML comments
Returns: (string) Compiled HTML
const html = zigpug.compile(
'p Hello #{name}!',
{ name: 'Alice' },
{ pretty: true }
);PugCompiler
Reusable compiler with state and formatting options.
const { PugCompiler } = require('zig-pug');
const compiler = new PugCompiler({ pretty: true });
compiler.set('key', 'value'); // String/Number
compiler.setBool('flag', true); // Boolean
const html = compiler.compile(template);Constructor Options:
pretty(boolean) - Enable pretty-print with indentation and commentsformat(boolean) - Enable pretty-print without commentsminify(boolean) - Enable HTML minificationincludeComments(boolean) - Include HTML comments
Methods:
set(key, value)- Set string, number, array, or object variable (auto-detects type)setString(key, value)- Set string variablesetNumber(key, value)- Set number variablesetBool(key, value)- Set boolean variablesetArray(key, value)- Set array variablesetObject(key, value)- Set object variablesetVariables(object)- Set multiple variables from an objectcompile(template, options)- Compile template with current variablesrender(template, variables, options)- Compile template with variables in one call
version()
Get zig-pug version.
console.log(zigpug.version()); // "0.4.0"Platform Support
Supported Platforms
- ✅ Linux (x64, ARM64)
- ✅ macOS (x64, Apple Silicon)
- ✅ Windows (x64)
- ✅ Bun.js (all platforms)
Termux/Android
The addon compiles on Termux but cannot be loaded due to Android namespace restrictions. Use the standalone CLI binary instead:
# Install Zig
pkg install zig
# Clone and build
git clone https://github.com/carlos-sweb/zig-pug
cd zig-pug
zig build
# Use CLI
./zig-out/bin/zig-pug template.pugSee docs/TERMUX.md for details.
Performance
Benchmark
const iterations = 10000;
const start = Date.now();
for (let i = 0; i < iterations; i++) {
zigpug.compile(template, data);
}
const elapsed = Date.now() - start;
console.log(`${iterations} in ${elapsed}ms`);
// ~100-250k ops/sec depending on runtimeTips
- Reuse PugCompiler - Faster than creating new context each time
- Pre-load templates - Read files once at startup
- Use Bun.js - 2-5x faster than Node.js
- Use minify in production - Smaller output, faster rendering
Examples
See the examples directory:
- Node.js:
examples/nodejs/ - Bun.js:
examples/bun/ - Express:
examples/nodejs/05-express-integration.js - TypeScript:
examples/nodejs/08-typescript-example.ts
Documentation
Troubleshooting
Installation fails
Error: node-gyp rebuild fails
Solution: Install build tools:
# Ubuntu/Debian
sudo apt-get install build-essential python3
# macOS
xcode-select --install
# Windows
npm install --global windows-build-toolsModule not found
Error: Cannot find module 'zig-pug'
Solution: Rebuild the addon:
cd node_modules/zig-pug
npm run buildCompilation errors
If you encounter compilation errors, please open an issue with:
- Your OS and version
- Node.js version (
node --version) - Complete error output
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
npm test - Submit a pull request
License
MIT License - see LICENSE for details.
Credits
- Pug - Original inspiration
- Zig - Programming language
- mujs - Embedded JavaScript engine
- Artifex Software - Creators of mujs
Links
- GitHub: https://github.com/carlos-sweb/zig-pug
- npm: https://www.npmjs.com/package/zig-pug
- Issues: https://github.com/carlos-sweb/zig-pug/issues
- Documentation: https://github.com/carlos-sweb/zig-pug#readme
Made with ❤️ using Zig 0.15.2 and mujs
