Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/elfrask/cls/llms.txt

Use this file to discover all available pages before exploring further.

CMX is the native markup syntax built into CLS, inspired by JSX and HTML. It lets you describe tree-shaped data structures — UI components, documents, configuration hierarchies — directly inside .clsx source files without any transpilation step or external dependency. A CMX expression evaluates to a first-class CLS value called a CmxValue, which your code can inspect, transform, pass to functions, and store like any other value. CMX is not a templating engine: it produces data, not strings.

Syntax Overview

CMX elements look like HTML tags embedded in CLS code. You can use them anywhere an expression is expected.
var sep = <Separador />;
var btn = <Button name="ok" />;

Tag Forms

SyntaxDescription
<Name attr="val">Opening tag — begins a block with children.
</Name>Closing tag — ends the block opened by <Name>.
<Name attr="val" />Self-closing tag — no children.

Attribute Forms

SyntaxValue type
attr="literal"String literal — always a String value.
attr={expression}Any CLS expression — evaluated at runtime.

Lowercase Tags → String tag

When the tag name starts with a lowercase letter, CLS stores the tag name as a plain String in the .tag field. Evaluating the element builds a CmxValue with three fields:
FieldTypeContents
.tagValue (a String)The tag name string as written in source.
.propsRecord<String, Value>All attributes as key-value pairs.
.childrenArray<Value>Child elements and text nodes, in order.
var el = <button label="Click me" count={42} />;

print(el.tag);           # → "button"
print(el.props.label);   # → "Click me"
print(el.props.count);   # → 42
print(el.children);      # → []

Uppercase Tags → Reference Stored in .tag

When the tag name starts with an uppercase letter, CLS performs a scope lookup and stores whatever value the name resolves to (a function, class, variable, etc.) directly in the .tag field — without calling it. If no variable with that name exists, .tag falls back to the tag name string.
function App(props) {
    print("App called with title:", props.title);
};

var el = <App title="Hello" />;

# .tag holds the App function reference — it was NOT called
print(el.props.title);   # → "Hello"
el.tag(el.props);        # call it yourself if needed
This design makes CMX agnostic: it never executes anything. The CMX expression always produces a CmxValue data structure; what happens to .tag (whether it is called, rendered, or inspected) is entirely up to your code.
<App title="Hello" /> does not call App. It creates a CmxValue whose .tag field holds the App function reference. Your framework layer decides when and how to call it.

Text Children and Nested Elements

Text content between tags becomes a String value in the children array. Nested elements become CmxValue values recursively.
var page = (
    <div>
        Texto plano
        <span>anidado</span>
    </div>
);

print(page.tag);              # → "div"
print(page.children[0]);      # → "Texto plano"
print(page.children[1].tag);  # → "span"
print(page.children[1].children[0]); # → "anidado"

Expression Interpolation in Children

Wrap any CLS expression in { } to embed it as a child value:
var content = "Dynamic content";

var body = <Body>{ content }</Body>;

print(body.children[0]);   # → "Dynamic content"
The expression inside { } is evaluated at the point the CMX element is constructed, so you can use variables, function calls, arithmetic — anything that produces a value.

Complex Example

Here is a realistic component tree that combines string attributes, expression attributes, and nested elements. Because uppercase tags store function references in .tag rather than calling them, the tree is pure data until your code acts on it:
function Header(props) {
    return <header title={props.title} />;
};

function Body(props) {
    return <body content={props.content} />;
};

var title = "My Page";
var content = "Welcome to CLS!";

var ui = (
    <App theme="dark" padding={16}>
        <Header title={title} />
        <Body content={content} />
    </App>
);

# Inspect the tree — nothing has been called yet
print(ui.props.theme);                    # → "dark"
print(ui.props.padding);                  # → 16
# .tag of a child holds the function reference
print(ui.children[0].props.title);        # → "My Page"
# Call the function references yourself:
var headerEl = ui.children[0];
var rendered = headerEl.tag(headerEl.props);  # calls Header({title: "My Page"})
print(rendered.tag);                          # → "header"
print(rendered.props.title);                  # → "My Page"

Event Handler Pattern

Because expression attributes accept any CLS value, the idiomatic way to attach a callback is to pass an arrow function:
# Correct: the function is stored in the prop and called later
var btn = <Button click={() -> { print("clicked") }} />;
print(btn.props.click);   # → <function>

# Calling the stored handler:
btn.props.click();        # → "clicked"
Avoid passing a direct function call as an attribute value — click={print("hi")} — because the call executes immediately when the element is constructed, and the void result gets stored as the prop value instead of a callable function.

Implementation Notes

CMX processing is integrated directly into the CLS compiler pipeline:
1

Lexer

The lexer recognises <TagName …> token sequences and emits dedicated markup tokens, distinguishing them from comparison operators and generics.
2

Parser

parse_cmx_element consumes the markup tokens and builds a Expression::Cmx AST node containing the tag name, a list of attribute pairs, and a list of child expressions.
3

Interpreter

evaluate_cmx walks the Expression::Cmx node. It evaluates all attribute expressions and child expressions, then constructs and returns a CmxValue. For lowercase tags the .tag field is a String; for uppercase tags the interpreter performs a scope lookup and stores the resolved value (function, class, variable) directly in .tag — without calling it.
4

VS Code extension

The syntax-highlighting grammar in the VS Code extension detects CMX contexts and applies distinct token colours to tags, attribute names, and attribute values — visually separating markup from surrounding CLS code.

CmxValue Field Summary

FieldAccessDescription
.tagel.tagValue: a String for lowercase tags; the resolved scope value (function, class, etc.) for uppercase tags.
.propsel.props.attrNameRecord of all attribute key/value pairs.
.childrenel.children[i]Ordered array of child strings and CmxValues.
var el = <card title="CLS" count={3}><item /><item /></card>;

print(el.tag);              # → "card"
print(el.props.title);      # → "CLS"
print(el.props.count);      # → 3
print(len(el.children));    # → 2
print(el.children[0].tag);  # → "item"

Build docs developers (and LLMs) love