TemplateDX combines Markdown and JSX to create powerful, type-safe templates for LLM prompts. This page provides a comprehensive overview of the syntax.
Basic Structure
Every TemplateDX template is a .mdx file with optional frontmatter and a mix of Markdown and JSX:
---
title: My Prompt Template
description: A brief description
---
# Your prompt content here
You are a helpful assistant specializing in {props.domain}.
<If condition={props.showInstructions}>
## Instructions
{props.instructions}
</If>
Frontmatter
Frontmatter is optional metadata at the top of your file:
---
title: Customer Support Prompt
description: Template for customer support interactions
version: 1.0
---
Variables
Access dynamic data using curly braces:
{props.userName} // Simple variable
{props.user.email} // Nested property
{props.items[0]} // Array access
{props.user?.name} // Optional chaining
Learn more about variables →
Expressions
Evaluate JavaScript expressions inline:
{props.score >= 90 ? "Excellent" : "Good"}
{props.items.length}
{props.name.toUpperCase()}
{props.tags.join(", ")}
Learn more about expressions →
Control Flow
Conditionals
Use <If>, <ElseIf>, and <Else> tags:
<If condition={props.userType === "premium"}>
You have access to premium features.
</If>
<ElseIf condition={props.userType === "standard"}>
You have access to standard features.
</ElseIf>
<Else>
You have access to basic features.
</Else>
Loops
Use <ForEach> to iterate over arrays:
<ForEach arr={props.items}>
{(item, index) => (
<>
{index + 1}. {item.name} - {item.description}
</>
)}
</ForEach>
Learn more about control flow →
Filters
Transform data with built-in filters:
{upper(props.status)} // ACTIVE
{lower(props.email)} // user@example.com
{capitalize(props.name)} // John Smith
{truncate(props.content, 100)} // Truncate to 100 chars
{join(props.tags, ", ")} // tag1, tag2, tag3
Learn more about filters →
Components
Create reusable template components:
import SystemRole from './system-role.mdx';
import Examples from './examples.mdx';
<SystemRole role="expert" domain={props.domain} />
## Task
{props.taskDescription}
<Examples data={props.examples} />
Learn more about components →
Raw Output
Use <Raw> to output text without interpolation:
<Raw>
{props.variableName}
</Raw>
Output: {props.variableName} (literal text)
Lowercase XML tags are preserved as-is in the output, making them ideal for prompt engineering patterns like <examples>, <context>, and <instructions>:
<User>
<examples>
<example>What is 2+2? The answer is 4.</example>
<example>What is 3+3? The answer is 6.</example>
</examples>
Now answer: What is {props.a}+{props.b}?
</User>
Output:
<examples>
<example>What is 2+2? The answer is 4.</example>
<example>What is 3+3? The answer is 6.</example>
</examples>
Now answer: What is 5+5?
XML tags support attributes and nesting:
<User>
<context type="system">You are an expert assistant.</context>
<instructions>
<rule>Be concise</rule>
<rule>Cite sources</rule>
</instructions>
</User>
Only lowercase tags are treated as XML passthrough. PascalCase tags like <User>, <System>, and <ForEach> are reserved for TemplateDX built-in tags and components. Variables and expressions inside XML tags are still evaluated normally.
Use JSX-style comments:
{/* This is a comment */}
{/**
* Multi-line comment
* for documentation
*/}
Fragments
Use fragments to group elements without adding markup:
<>
First line
Second line
</>
Markdown Support
TemplateDX supports all standard Markdown:
# Heading 1
## Heading 2
**Bold text**
*Italic text*
- Bullet list
- Item 2
1. Numbered list
2. Item 2
[Link text](https://example.com)
`inline code`
\`\`\`javascript
// Code block
const x = 10;
\`\`\`
Whitespace
TemplateDX preserves whitespace in your templates:
Line 1
Line 2
Paragraph with blank line above
Escaping
Escape curly braces with backslash:
\{this will appear literally\}
Type Safety
Add TypeScript types via JSDoc comments:
{/**
* @typedef Props
* @property {string} userName - The user's name
* @property {string} email - The user's email
* @property {boolean} isPremium - Premium user flag
*/}
Learn more about type safety →
Best Practices
- Use descriptive variable names:
props.customerName instead of props.n
- Keep templates modular: Break large templates into components
- Add type definitions: Document your props with TypeScript
- Use conditionals wisely: Make prompts adapt to context
- Leverage filters: Transform data at the template level
Complete Example
Here’s a full example combining multiple features:
---
title: Product Review Analysis
---
{/**
* @typedef Props
* @property {string} productName
* @property {Array<{author: string, rating: number, comment: string}>} reviews
* @property {string} analysisType
*/}
# Product Review Analysis for {props.productName}
You are an expert product analyst. Analyze the following customer reviews and provide insights.
## Reviews ({props.reviews.length} total)
<ForEach arr={props.reviews}>
{(review, index) => (
<>
### Review {index + 1}
**Rating**: {review.rating}/5
**Author**: {capitalize(review.author)}
"{truncate(review.comment, 200)}"
---
</>
)}
</ForEach>
## Analysis Instructions
<If condition={props.analysisType === "sentiment"}>
Focus on overall sentiment and emotional tone in the reviews.
</If>
<ElseIf condition={props.analysisType === "features"}>
Identify the most mentioned product features and customer opinions about them.
</ElseIf>
<Else>
Provide a comprehensive analysis covering sentiment, features, and improvement suggestions.
</Else>
Please provide your analysis in a structured format.
Next Steps