GitHub - garag-lib/GTPL: GTPL is a TypeScript library for reactive template systems built around Direct DOM and Proxy. Inspired by Vue, Angular AOT, and JSX, it delivers efficient reactive UI updates in a compact 11kB JavaScript package.

GTPL

Reactive template library with direct DOM updates and Proxy-based reactivity.

GTPL is a TypeScript library for reactive template systems built around Direct DOM and Proxy. Inspired by Vue, Angular AOT, and JSX, it delivers efficient reactive UI updates in a compact 11kB JavaScript package.

GTPL provides:

  • A small runtime for reactive rendering.
  • Template compilation in two modes: JIT (runtime) and AOT (precompiled).
  • Built-in directives for conditional rendering, loops, switching, styles, and dynamic attributes.

Interactive examples: https://garag-lib.github.io/GTPL/

Installation

Quick Start (JIT)

import gtpl from '@mpeliz/gtpl';

const { GTpl, jit: { GCode, GCompile } } = gtpl;

const template = `
  <div>
    <h2>Counter: {{ count }}</h2>
    <button onclick="{{ this.count = this.count + 1 }}">+1</button>
    <button onclick="{{ this.count = 0 }}">Reset</button>
  </div>
`;

const root = { count: 0 };
const aot = GCode(template);
const generator = GCompile(aot);

const app = new GTpl({ root, generator });
app.addTo(document.getElementById('app'));

JIT vs AOT

Mode When to use Flow
JIT Dynamic templates generated at runtime template -> GCode -> GCompile -> GTpl
AOT Stable templates compiled during build precompiled code -> GCompile -> GTpl

AOT is recommended for production when templates are known in advance.

Template Syntax

Syntax Meaning
{{ foo }} Read variable
{{ 'hello' }} Constant
{{ foo:format }} Pipe/chained function
{{ return foo + 1 }} Formula expression
onclick="{{ this.count++ }}" Event expression
[value]="{{ foo }}" Two-way bind property

Built-in Directives

Directive Purpose
g-if Render when truthy
g-notif Render when falsy
g-switch / g-case Switch/case rendering
g-for="arr;index;value" List rendering
g-attr Dynamic attributes from object
g-style Dynamic inline styles
g-inner Set innerHTML
g-tpl Reuse named templates
g-bind / g-binds Element/collection references

API Overview

import gtpl from '@mpeliz/gtpl';

const { GTpl, GregisterDirective, jit: { GCode, GCompile } } = gtpl;

Main pieces:

  • GCode(html): parses template HTML into generated code string.
  • GCompile(code): compiles generated code into a render function.
  • new GTpl({ root, generator }): creates reactive instance.
  • instance.addTo(node): mounts rendered nodes.
  • instance.watch(path, cb): subscribes to reactive path changes.
  • instance.refresh(): triggers recomputation.
  • instance.destroy(): removes listeners, bindings, and rendered nodes.
  • GregisterDirective(name, class): register custom directive.

Browser Global Build

If you use the global bundle (dist/gtpl.global.js):

<script src="dist/gtpl.global.js"></script>
<script>
  const { GTpl, jit: { GCode, GCompile } } = gtpl;
</script>

Releases (Precompiled Builds)

When a GitHub Release is published, GitHub Actions runs tests, builds dist/, and uploads precompiled assets (.zip and .tar.gz) to that release automatically:

https://github.com/garag-lib/GTPL/releases

To publish a new release:

# single command flow (tests + build + version bump + commit + push + tag push)
npm run release -- 1.1.4

# then publish release in GitHub UI for that tag (workflow triggers on publish)

Development

Package outputs:

  • dist/gtpl.esm.js
  • dist/gtpl.cjs.js
  • dist/gtpl.global.js
  • dist/gtpl.d.ts

Security Notes

  • g-inner writes directly to innerHTML; use trusted HTML only.
  • JIT compilation executes generated code (GCompile), so compile only trusted template sources.

Attribution

If you use GTPL in a product or publication, a short attribution is appreciated:

Powered by GTPL (https://github.com/garag-lib/GTPL)

For formal attribution details, see NOTICE and CITATION.cff.

License

Apache-2.0