> ## Documentation Index
> Fetch the complete documentation index at: https://docs.compozy.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Template engine

> The template engine in Compozy uses Jinja2-style syntax with JavaScript expressions, allowing you to reference and manipulate data throughout your workflows.

## Introduction

The template engine is a core feature of Compozy that allows you to:

* Reference data from various workflow components
* Perform dynamic calculations and transformations
* Access environment variables and configuration
* Handle conditional logic inline

Compozy uses [Jinja2](https://jinja.palletsprojects.com/)-style syntax combined with [Deno](https://deno.land/) for JavaScript evaluation, providing:

* Simple expressions using `{{ ... }}` for single-line JavaScript
* Complex logic using `$exec: |` for multiline JavaScript code

<Note>
  Since we use Deno runtime, all JavaScript code in templates follows modern ECMAScript standards and has access to Deno's built-in security features.
</Note>

## Template Syntax

### Simple Expressions

For basic operations, use the `{{ ... }}` syntax. These expressions should be concise and focus on a single operation:

```yaml theme={"dark"}
# Basic variable access
name: "{{ user.name }}"

# Simple calculations
total: "{{ price * quantity }}"

# Conditional values
status: "{{ isActive ? 'running' : 'stopped' }}"
```

### Multiline Code

For complex operations that require multiple lines or intermediate variables, use the `$exec: |` syntax:

```yaml theme={"dark"}
description:
  $exec: |
    const { title, author, date } = metadata;
    const formattedDate = new Date(date).toLocaleDateString();
    return `${title} by ${author} (${formattedDate})`;
```

## Working with Objects and Arrays

<CodeGroup>
  ```yaml Object Operations theme={"dark"}
  # Property access
  value: "{{ object.nested.property }}"

  # Optional chaining
  value: "{{ object?.nested?.property }}"

  # Default values
  value: "{{ object.property ?? 'default' }}"
  ```

  ```yaml Array Operations theme={"dark"}
  # Array methods
  items: "{{ array.map(item => item.value) }}"
  filtered: "{{ array.filter(item => item.score > 0.5) }}"

  # Complex transformations
  result:
    $exec: |
      const processed = array
        .filter(item => item.isValid)
        .map(item => item.value);
      return processed.reduce((sum, val) => sum + val, 0);
  ```
</CodeGroup>

## Built-in Functions

Compozy includes several popular libraries for common operations. Here are some examples:

<CodeGroup>
  ```yaml String & Array theme={"dark"}
  # Lodash array utilities
  chunks: "{{ _.chunk(array, 2) }}"

  # String manipulation
  slug: "{{ v.slugify(title) }}"
  ```

  ```yaml Dates & Numbers theme={"dark"}
  # Date formatting
  date: "{{ dayjs().format('YYYY-MM-DD') }}"

  # Number formatting
  price: "{{ numeral(1234.567).format('$0,0.00') }}"
  ```
</CodeGroup>

For a complete reference of available functions, see [Template Functions](/core/template-engine/template-functions).

## Custom Dependencies

You can extend the template engine with additional libraries. All custom dependencies are automatically namespaced under the `$` object:

```yaml theme={"dark"}
---
name: "My Document"
template-dependencies:
  - package: "npm:mathjs@11.8.0"
    name: math
---

# Access custom dependencies through the $ object
result: "{{ $.math.evaluate('2x + 3y', { x: 4, y: 2 }) }}"
```

Learn more about adding custom dependencies in [Custom Dependencies](/core/base-structure/custom-dependencies).

## Best Practices

<Steps>
  <Step title="Keep Expressions Simple">
    Use simple expressions for basic operations:

    ```yaml theme={"dark"}
    status: "{{ isActive && isValid }}"
    ```

    Move complex logic to multiline blocks:

    ```yaml theme={"dark"}
    status:
      $exec: |
        if (!isActive) return 'inactive';
        if (!isValid) return 'invalid';
        return 'ready';
    ```
  </Step>

  <Step title="Use Optional Chaining">
    Always use optional chaining for nested properties:

    ```yaml theme={"dark"}
    value: "{{ response?.data?.items ?? [] }}"
    ```
  </Step>

  <Step title="Handle Errors">
    Implement proper error handling in complex operations:

    ```yaml theme={"dark"}
    result:
      $exec: |
        try {
          return processData(input);
        } catch (error) {
          return { error: error.message };
        }
    ```
  </Step>

  <Step title="Type Safety">
    Use explicit type conversions:

    ```yaml theme={"dark"}
    count: "{{ Number(value) }}"
    flag: "{{ Boolean(value) }}"
    ```
  </Step>
</Steps>

## Next Steps

<CardGroup cols={2}>
  <Card title="Template Functions" icon="function" href="/core/template-engine/template-functions">
    Explore built-in utility functions
  </Card>

  <Card title="Custom Dependencies" icon="puzzle" href="/core/base-structure/custom-dependencies">
    Learn about adding custom libraries
  </Card>
</CardGroup>

## References

* [Jinja2 Template Engine](https://jinja.palletsprojects.com/) - The template syntax inspiration
* [Deno Runtime](https://deno.land/) - The JavaScript runtime used for expression evaluation
* [Lodash Documentation](https://lodash.com/docs) - Utility library documentation
* [Day.js Documentation](https://day.js.org/) - Date manipulation library
* [Voca Documentation](https://vocajs.com/) - String manipulation library
* [Numeral.js Documentation](http://numeraljs.com/) - Number formatting library
