Basic structure
Every TemplateDX template is a.mdx file with optional frontmatter and a mix of Markdown and JSX:
Frontmatter
Frontmatter is optional metadata at the top of your file:Variables
Access dynamic data using curly braces:?. and . behave identically).
Learn more about variables →
Expressions
Evaluate expressions inline: arithmetic, comparison, and logical operators, property access, and registered filter calls:props.name.toUpperCase()) and the ternary operator (a ? b : c) aren’t supported. Use a filter or an <If> tag instead.
Learn more about expressions →
Control flow
Conditionals
Use<If>, <ElseIf>, and <Else> tags:
== / !=); strict equality (=== / !==) isn’t in the evaluator’s operator table and throws at render time. See Expressions for the full operator list.
Loops
Use<ForEach> to iterate over arrays:
Filters
Transform data with built-in filters. TemplateDX ships 10 filters:abs, capitalize, dump, join, lower, replace, round, truncate, upper, urlencode.
Components
Create reusable template components:Raw output
Use<Raw> to emit the enclosed content as literal source text; expressions inside <Raw> aren’t evaluated. The plugin re-serializes its children through Markdown, so you get exactly what you wrote.
\{props.variableName} (literal text, not the value of props.variableName). TemplateDX re-serializes the Raw content through remark-stringify, which backslash-escapes { and <, so braces and angle brackets appear escaped in the output.
XML tags
TemplateDX preserves lowercase XML tags as-is in the output, making them ideal for prompt engineering patterns like<examples>, <context>, and <instructions>. A fixed allow-list of HTML tags (per supported-tags.ts) also passes through unchanged. TemplateDX evaluates expressions inside these tags normally.
stringify step indents nested elements by two spaces, so passthrough output isn’t byte-identical to your source. Keep that in mind for whitespace-sensitive prompts.
XML tags support attributes and nesting:
TemplateDX treats lowercase tags as XML passthrough, along with a fixed allow-list of HTML tags. The allow-list check is case-insensitive, so PascalCase forms of allow-listed HTML elements (
<Table>, <Code>) also pass through. The only PascalCase tags TemplateDX registers as built-ins are If, ElseIf, Else, ForEach, and Raw. Tags like <User>, <System>, and <Assistant> are AgentMark message tags layered on top of TemplateDX, not engine built-ins. A PascalCase tag that’s not on the HTML allow-list must be a registered TagPlugin or an imported component, or bundling throws Unsupported tag '<TagName>'. TemplateDX still evaluates variables and expressions inside passthrough tags normally.Comments
Use JSX-style comments:Fragments
Use fragments to group elements without adding markup:Markdown support
TemplateDX supports all standard Markdown:Whitespace
TemplateDX preserves whitespace in your templates:Escaping literal braces
To keep{ or } out of expression evaluation, wrap the content in <Raw>:
stringify step, which always escapes { at the start of text content. There is no way to emit an unescaped literal { through stringify.
Type safety
See Type safety for the canonical flow:agentmark generate-types emits AgentmarkTypes from your prompt schemas. That’s the codegen pipeline AgentMark actually uses at runtime.
TemplateDX itself doesn’t evaluate JSDoc or TypeScript types; the bundler strips comments at bundle time (removeComments, bundler.ts:163-170).
Best practices
- Use descriptive variable names. Prefer
props.customerNameoverprops.n. - Keep templates modular. Break large templates into components.
- Generate types. Run
agentmark generate-typesand pass the result tocreateAgentMark<AgentmarkTypes>()for compile-time prop validation. - Use conditionals wisely. Make prompts adapt to context.
- Use filters. Transform data at the template level instead of reshaping it in your application code.
Complete example
Here’s a full example combining multiple features:Next steps
- Variables - Learn about variable access
- Expressions - JavaScript expressions
- Tags - Control flow and special operations
- Filters - Data transformation
- Components - Reusable templates