templjs: Meta-Templating System

May 12, 2026 ยท View on GitHub

codecov CodeRabbit Pull Request Reviews

templjs is a declarative, schema-aware meta-templating system for transforming structured data into structured and unstructured text outputs.

Think of it as XSLT-style transformation power with Jinja2/Handlebars authoring ergonomics, plus base-language tooling support and extensible, validated input/output pipelines.

Elevator Pitch

Write one template definition, validate the data contract early, and generate consistent outputs in formats like Markdown, HTML, JSON, YAML, TOML, and XML.

What templjs Is

  • A TypeScript-native successor to the original Temple concept
  • A parser/AST-driven template engine for structured-data transformations
  • A schema-aware system for validating input data and query paths
  • A monorepo with core runtime, CLI, Volar integration, and VS Code extension
  • An extensible architecture intended to support multiple syntax themes and adapters

What templjs Is Not

  • Not a finished 1.0 runtime yet
  • Not currently a drop-in replacement for full Jinja2/Handlebars/XSLT feature sets
  • Not limited to one output format or one editor integration strategy

Current Status

Early development (active).

Implemented today in @templjs/core:

  • Tokenizer with configurable delimiters
  • Parser that builds a typed AST
  • Renderer internals with control-flow and filters
  • JSON Schema validation and query-path validation helpers

In progress across the repo:

  • Output-format config beyond .templjs.json JSON files
  • Output validation pipeline end-to-end
  • Multi-syntax themes/adapters (v1.1+)

Feature Matrix

AreaCapabilityStatusNotes
CoreConfigurable delimiter tokenizationImplementedtokenize() supports custom statement/expression/comment delimiters
CoreAST parser (text, expressions, if/for/set/block)ImplementedTyped AST and parser tests are present
CoreRenderer internals (control flow + filters)Implementedrender() public API available; further stabilization in progress
CoreJSON Schema input validationImplementedSchemaValidator with Ajv
CoreQuery-path validation + fuzzy suggestionsImplementedSchema-derived path checks with typo suggestions
CoreOutput validation pipelinePlannedIn architecture/PRD, not yet end-to-end in runtime
CLIrender / validate / init commandsImplementedJSON/YAML/TOML/XML input; .templjs.json; --watch supported
IDEVolar language pluginImplementedVirtual mapping, diagnostics, completions, hover, definitions
IDEVS Code extension + .tmpl supportImplementedPreferred .tmpl; host-first template suffixes are supported
ExtensibilityMulti-syntax themes/adapters (Jinja2/Handlebars/etc.)Plannedv1.0 focuses on one syntax style; architecture allows expansion
CI/CDLint/type-check/test/build workflowsImplementedGitHub Actions pipelines configured

Monorepo Structure

Quick Start

For full setup, first render, and VS Code authoring guidance, see Getting Started.

Monorepo prerequisites:

  • Node.js >=22.12.0 <23 || >=24.0.0 <25
  • pnpm 8.15.0

Repository setup:

pnpm install
pnpm test
pnpm build

Published packages:

npm install @templjs/core
npm install -D @templjs/cli

VS Code extension:

Useful monorepo commands:

pnpm lint
pnpm format:check
pnpm type-check
pnpm graph

Documentation

Template Syntax (Current)

Current defaults support Jinja2-style block/comment delimiters plus expression tags:

  • Statements: {% ... %}
  • Expressions: {{ ... }}
  • Comments: {# ... #}

Example:

# Report
{% if user %}
User: {{ user.name | upper }}
{% endif %}

{% for item in items %}
- {{ item.title }}
{% endfor %}

Delimiters are configurable to avoid collisions with host/base languages.

Validation Model

templjs treats validation as a first-class concern.

  • Input data can be validated with JSON Schema (Ajv-based)
  • Query paths are checked against schema-derived valid paths
  • Fuzzy suggestions are available for typoed paths
  • Output validation is part of the intended end-to-end pipeline design

Base-Language Support

The VS Code/Volar architecture is designed to preserve native tooling for base formats (Markdown, JSON, YAML, HTML) while overlaying template semantics.

Current extension targets commonly use the .tmpl suffix:

  • .yaml.tmpl / .yml.tmpl
  • .json.tmpl
  • .md.tmpl
  • .html.tmpl

Compatibility suffixes remain fully supported for host-first naming patterns such as .md.templ, .json.templ, .yaml.templ, and .html.templ (alongside .tmpl/.tpl variants).

For troubleshooting language features, see VS Code triage logs for quick setup and symptom-specific checks for go-to-definition, hover, and IntelliSense duplicate entries.

Example: Parse + Validate

import { tokenize, parse, SchemaValidator } from '@templjs/core';

const template = 'Hello {{ user.name }}';
const tokens = tokenize(template);
const ast = parse(tokens);

const validator = new SchemaValidator({
  type: 'object',
  properties: {
    user: {
      type: 'object',
      properties: { name: { type: 'string' } },
      required: ['name'],
    },
  },
  required: ['user'],
});

const dataResult = validator.validate({ user: { name: 'Ada' } });
const pathResult = validator.validateQueryPath('user.name');

console.log(ast.errors, dataResult.valid, pathResult.valid);

Architecture and Roadmap References

Contributing

  • Fork and create a feature branch
  • Run pnpm test, pnpm lint, and pnpm build before opening a PR
  • Follow Conventional Commits for commit messages
  • Document architectural changes in [docs-adr]
  • For parser and semantic-analysis changes: keep syntax decisions in parser/grammar logic, model binding behavior declaratively from node kinds, and reserve imperative binder code for runtime-dependent edge cases only

License

Apache-2.0