pug_dart 2.0.1 copy "pug_dart: ^2.0.1" to clipboard
pug_dart: ^2.0.1 copied to clipboard

Native Dart Pug template renderer with a safe expression engine.

pug_dart #

Native Dart Pug renderer with a safe expression engine.

Version 2 is a Node-free native Dart rewrite of pug_dart: templates stay as Pug, but rendering happens in Dart. Compatibility is tracked with committed golden fixtures generated from pinned upstream pug@3.0.4.

If you need the original Node-backed behavior, pin pug_dart to the latest compatible 1.x release.

Migrating From 1.x #

pug_dart 2.0.0 is a breaking rewrite. The package no longer starts a persistent Node.js process, installs npm dependencies at runtime, exposes the old singleton lifecycle API, or evaluates arbitrary JavaScript inside templates.

Most applications should migrate by:

  • Replacing singleton calls with the top-level render, renderFile, compile, or compileFile APIs.
  • Passing precomputed values through locals.
  • Moving template-only JavaScript helpers into explicit Dart helpers or filters.
  • Using PugCompatibility.nodeMigration during migration when templates only need common safe JavaScript habits such as local aliases, JSON.stringify, Math.*, numeric formatting, joins, includes, and simple template literals.
  • Pinning pug_dart: ^1.2.1 if the application needs the old Node-backed runtime or full JavaScript expression compatibility.

Status #

This is an early native implementation. It already supports:

  • Pug-like API: render, renderFile, compile, compileFile
  • Tags, shorthand ids/classes, attributes, boolean attributes, &attributes
  • Escaped and unescaped interpolation
  • if, else if, else, unless, each, guarded while
  • include, extends, block, append, prepend
  • Mixins with arguments, defaults, attributes, and block bodies
  • Dot text blocks for script./style. style content
  • pretty output formatting for supported HTML trees
  • Source-spanned parse/render diagnostics and wrapped file-loading diagnostics
  • Custom filters and explicit Dart helpers

It intentionally does not evaluate arbitrary JavaScript. Unsupported JS-only expressions fail with UnsupportedFeatureException; precompute those values in Dart, expose an explicit helper, or use the migration preset for the documented safe subset.

Compatibility Matrix #

Compatibility is measured against upstream pug@3.0.4 with committed golden fixtures. The project targets Pug syntax and rendering behavior, while replacing JavaScript evaluation with a safe Dart expression subset.

Pug language feature Status Notes
Tags Supported Includes nested tags, self-closing tags, void tags, implicit div, and block expansion such as a: img.
Attributes Supported Includes multiline attributes, quoted names, boolean attributes, class arrays/maps, style maps, unescaped attributes, and &attributes.
Attribute interpolation Partially supported Pug 3 removed legacy #{} attribute interpolation. Use expression attributes such as href='/' + url. Simple ES template strings are supported only when simpleTemplateLiterals or PugCompatibility.nodeMigration is enabled.
Text Supported Includes inline text, piped text, dot text blocks, and text interpolation.
Comments Supported Includes buffered and unbuffered comments, including indented comment blocks.
Doctypes Supported Includes Pug's documented doctype shortcuts.
Buffered code Supported subset = and != work with the safe expression evaluator.
Unbuffered code Supported opt-in subset - var/let/const name = expression can be enabled with allowLocalAssignments or PugCompatibility.nodeMigration. Other JavaScript statements such as loops, functions, imports, and mutation are intentionally rejected.
Conditionals Supported Includes if, else if, else, and unless.
Case Supported Includes case, when, and default for simple branch values. JavaScript fall-through semantics are not supported.
Iteration Supported Includes array/list iteration, map/object iteration, index/key variables, and else branches.
Includes Supported Pug files resolve relative to the current file; missing files throw PugIOException. Raw text includes and filtered includes are not implemented.
Inheritance Supported Includes extends, block, append, and prepend.
Mixins Supported subset Includes arguments, defaults, call attributes, nested calls, and block bodies. Rest args and advanced JavaScript argument expressions are out of scope.
Filters Dart-native only Custom Dart filters are supported through PugOptions.filters. JSTransformer filters are out of scope.
Interpolation Supported subset Escaped #{...} and unescaped !{...} work with safe expressions.
Pretty output Supported PugOptions(pretty: true) formats supported HTML output and is covered by upstream golden tests.
Caching Basic Parsed templates are cached by resolved path within a renderer instance. Dependency-aware invalidation is not implemented.
Browser compilation Out of scope This package is a Dart VM/server-side renderer.

Safe Expressions #

The native evaluator supports literals, lists, maps, property and index lookup, arithmetic, comparison, ternary expressions, JavaScript-like truthiness, && and || operand value semantics, and explicit Dart helpers.

Out of scope by design:

  • Arbitrary JavaScript evaluation
  • JavaScript statements and mutation
  • Implicit globals such as JSON, Math, Date, and moment
  • JavaScript methods such as .toUpperCase() except for the documented toString() case covered by the compatibility fixtures and the documented nodeMigration methods
  • General ES template string semantics beyond simple ${...} interpolation
  • JSTransformer filters such as :markdown-it, :babel, :scss, and filtered includes
  • Raw text includes for non-Pug files
  • Full Pug.js compile/runtime API compatibility beyond the Pug-like facade

Usage #

For Pug syntax, use the official language reference: https://pugjs.org/language/attributes.html. This README focuses on how to render Pug from Dart.

Render an inline template #

import 'package:pug_dart/pug_dart.dart' as pug;

final html = await pug.render('p Hello #{name}', {'name': 'Dart'});

Render a file #

import 'package:pug_dart/pug_dart.dart' as pug;

final html = await pug.renderFile('views/product.pug', {
  'product': {
    'name': 'Spiced Rum',
    'price': 6499,
    'inStock': true,
  },
});

Relative include and extends paths are resolved from the current template file. Use basedir when your templates use project-root-relative paths.

final html = await pug.renderFile(
  'views/pages/home.pug',
  {'title': 'Home'},
  pug.PugOptions(basedir: 'views'),
);

Reuse a compiled template #

Use compile or compileFile when rendering the same template repeatedly with different locals.

final template = pug.compileFile('views/product-card.pug');

final first = template.render({'name': 'Spiced Rum'});
final second = template.render({'name': 'White Rum'});

Pass explicit Dart helpers #

JavaScript globals and arbitrary JavaScript calls are intentionally unavailable. Precompute values in Dart, or expose the small helper surface your templates need.

final template = pug.compile('p= money(cents)', pug.PugOptions(
  helpers: {
    'money': (args) => '\$${((args.first as num) / 100).toStringAsFixed(2)}',
  },
));

final html = template.render({'cents': 1299});

Use the Node migration preset #

PugCompatibility.nodeMigration keeps rendering native and deterministic, but enables a small compatibility layer for common Pug.js templates:

final html = await pug.renderFile(
  'views/product.pug',
  {'product': product},
  const pug.PugOptions(
    compatibility: pug.PugCompatibility.nodeMigration,
  ),
);

The preset enables:

  • restricted unbuffered assignments such as - const price = product.price || 0
  • JSON.stringify(value), Number(value), and String(value)
  • Math.round/floor/ceil/min/max
  • numeric .toFixed(n), .length, simple .join(', '), and .includes(value)
  • simple backtick interpolation such as:
a(href=`/products/${product.slug}`)

You can enable the assignment and template-literal pieces independently with allowLocalAssignments and simpleTemplateLiterals.

Register custom filters #

Filters are Dart functions. This keeps the runtime Node-free and avoids pulling in JSTransformer packages.

final html = await pug.render(
  '''
:upper
  rendered by a dart filter
''',
  const {},
  pug.PugOptions(
    filters: {
      'upper': (text, attrs) => text.toUpperCase(),
    },
  ),
);

Pretty output #

By default, output follows Pug's compact HTML style. Enable pretty when you want formatted HTML.

final html = await pug.renderFile(
  'views/email.pug',
  {'name': 'Dart'},
  const pug.PugOptions(pretty: true),
);

Custom loading #

Provide a PugTemplateLoader when templates come from memory, a database, an asset bundle, or another virtual filesystem.

class MapTemplateLoader implements pug.PugTemplateLoader {
  MapTemplateLoader(this.templates);

  final Map<String, String> templates;

  @override
  String resolve(String path, {String? from}) => path;

  @override
  String load(String path, {String? from}) {
    final source = templates[path];
    if (source == null) {
      throw pug.PugIOException('Missing template "$path"');
    }
    return source;
  }
}

final html = await pug.renderFile(
  'page.pug',
  {'title': 'Virtual templates'},
  pug.PugOptions(
    loader: MapTemplateLoader({
      'page.pug': 'include partial.pug\np= title',
      'partial.pug': 'h1 Loaded from memory',
    }),
  ),
);

Golden Fixtures #

Fixture cases live under test/fixtures/<feature>/<case>/:

  • template.pug
  • locals.json
  • options.json
  • expected.html

Regenerate expected HTML from pinned upstream Pug:

dart run tool/generate_goldens.dart

The generator installs pug@3.0.4 through npm when needed. Normal Dart tests do not require Node.

The test/fixtures/docs/ tree mirrors examples from Pug's language reference. Examples that require arbitrary JavaScript evaluation or JSTransformer packages are covered by negative tests in test/language_reference_unsupported_test.dart because this package intentionally requires precomputed Dart locals or explicit Dart helpers/filters instead.

CLI #

dart run pug_dart:pug-dart render path/to/template.pug
dart run pug_dart:pug-dart compile-check path/to/template.pug
dart run pug_dart:pug-dart golden:update

Quality Gates #

dart format --set-exit-if-changed .
dart analyze --fatal-infos --fatal-warnings
dart test
dart pub publish --dry-run
0
likes
150
points
182
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Native Dart Pug template renderer with a safe expression engine.

Repository (GitHub)
View/report issues

Topics

#templating #html #pug #server-side #templates

License

MIT (license)

Dependencies

path

More

Packages that depend on pug_dart