v0.5 (Latest)

Full language specification for OpenUI Lang v0.5 - reactive state, queries, mutations, and built-in functions.

OpenUI Lang v0.5 extends the v0.1 specification with reactive state, data fetching, and built-in functions. See the Evolution Guide to understand how the language evolved from static UI generation to interactive apps.

Syntax Overview

The language consists of assignment statements - one per line.

identifier = Expression

Three types of statements:

StatementSyntaxExample
Componentname = Component(args...)header = CardHeader("Title")
State declaration$name = defaultValue$days = "7"
Data statementname = Query(...) / name = Mutation(...)data = Query("tool", {}, {rows: []})

Expressions & Types

TypeSyntaxExample
Component callType(arg1, arg2)Header("Title", "Subtitle")
Built-in call@Name(args)@Count(data.rows)
String"text""Hello"
Number123, 12.5, -542
Booleantrue / falsetrue
Nullnullnull
Array[a, b, c]["Jan", "Feb"]
Object{key: val}{sql: "SELECT *"}
ReferenceidentifiermyHeader
State ref$identifier$days
Member accessa.b.cdata.rows.title
Ternarycond ? a : b$show ? form : null
Binary opsa + b, a == b"" + $days + " days"

Operators

CategoryOperators
Arithmetic+, -, *, /, %
Comparison==, !=, >, <, >=, <=
Logical&&, ||
Unary!, -

Member access and array pluck

data.rows.title on an array extracts the title field from every element - column pluck.

data = Query("list", {}, {rows: []})
tbl = Table([Col("Title", data.rows.title)])   // plucks title from each row
kpi = TextContent("" + data.total)              // access a single field

Core Rules

  1. One statement per line: identifier = Expression
  2. Root entry point: root = Root([children]). If missing, nothing renders. The root component name comes from your library definition.
  3. Top-down generation: Layout → Components → Data for progressive streaming.
  4. Positional arguments: Mapped to props by Zod schema key order.
  5. Forward references allowed: root = Stack([chart]) can appear before chart = ... is defined.
  6. Positional only: Write Stack([children], "row", "l") NOT Stack([children], direction: "row", gap: "l").

Reactive State ($variables)

Declare with $name = default:

$days = "7"
$title = ""
$showEdit = false

Two-way binding: passing $days to Select("days", $days, [...]) binds the variable to the input. User changes → variable updates → all expressions referencing it re-evaluate.

Built-in Functions

All built-in functions use the @ prefix. Using bare names (Count(...)) is not supported - only @Count(...).

Data builtins

FunctionSignature
@Count@Count(array) → number
@Sum@Sum(numbers[]) → number
@Avg@Avg(numbers[]) → number
@Min@Min(numbers[]) → number
@Max@Max(numbers[]) → number
@First@First(array) → element
@Last@Last(array) → element
@Filter@Filter(array, field, op, value) → filtered array. Operators: ==, !=, >, <, >=, <=, contains
@Sort@Sort(array, field, direction?) → sorted array
@Round@Round(number, decimals?) → number
@Abs@Abs(number) → number
@Floor@Floor(number) → number
@Ceil@Ceil(number) → number

Iteration

@Each(array, varName, template) - render template for each element. Loop variable is only available inline.

Action steps (inside Action([...]))

StepDescription
@Run(ref)Execute a Mutation or re-fetch a Query
@Set($var, value)Set a $variable to a value
@Reset($var1, $var2)Restore $variables to declared defaults
@ToAssistant("msg")Send message to the LLM
@OpenUrl("url")Open URL in new tab

Query and Mutation

Query (read data)

data = Query("tool_name", {arg: value}, {rows: []}, 30)
PositionTypeDescription
1stringTool name
2objectArguments (can reference $variables)
3objectDefaults (renders before data arrives)
4number (optional)Refresh interval in seconds

Queries execute on load. When $variables in args change, the query re-fetches automatically.

Mutation (write data)

result = Mutation("tool_name", {title: $title})

Mutations do NOT execute on load. Triggered via @Run(result) inside an Action.

Action composition

submitBtn = Button("Create", Action([@Run(mutation), @Run(query), @Reset($title)]))

Steps execute in order. If @Run(mutation) fails, remaining steps are skipped.

Component Resolution

Positional arguments map to named props via Zod schema key order. See v0.1 spec for the full mapping logic.

Prompt Feature Flags

The system prompt is generated with feature flags that control which language features the LLM is instructed to use. See System Prompts for configuration.

FlagWhat it enablesDefault
toolCallsQuery(), Mutation(), @Run, tool workflow rulestrue if tools provided
bindings$variables, @Set, @Reset, reactive filterstrue if toolCalls is true
editModeIncremental editing (LLM outputs only changed statements)false
inlineModeText + fenced code responses (LLM can answer without generating UI)false

Streaming & Hoisting

Forward references are allowed. See v0.1 spec for details.

On this page