Components
A .rylae file contains one or more components. The first component is the entry point for rylae build and rylae render.
Supported prop types are String, Text, Bool, Boolean, Int, Decimal, Handler, VTI entity names, and list forms such as [User].
Props without defaults are required. Props can declare a default expression with =, which makes the prop optional for component callers:
component Name(prop: Type, items: [Type]) { <div>{prop.field}</div>}State and Events
Components can declare typed local state before markup:
State initializers are type-checked. Event attributes use on:event={handler} syntax and require a Handler-typed expression. Event attributes are retained in IR and omitted from static HTML output.
component Toggle(label: String, onPress: Handler) { state enabled: Bool = true <button disabled={enabled} on:click={onPress}>{label}</button>}Lifecycle Effects
Components can declare an on mount effect block before markup:
Effect body expressions are type-checked against the component scope and emitted in IR. Static HTML rendering does not execute lifecycle effects. The JavaScript target schedules mount effect expressions with queueMicrotask when available.
component Profile(user: User) { on mount { user.email } <p>{user.name}</p>}Computed Values
Components can declare typed local computed values before markup. let and computed are equivalent declaration forms:
Computed values are type-checked against their declared type, can reference props, state, and earlier computed values, and are available to markup expressions.
component UserBadge(user: User) { let display: String = user.name computed visible: Bool = user.deleted_at is null <span>{display}</span>}Markup
Elements use HTML-like tags, string attributes, boolean attributes, expression attributes, text nodes, and interpolation:
Conditional class bindings use class:name={condition}. The condition must be Bool; the class is emitted only when the expression evaluates to true.
Expression attributes such as disabled={enabled} or data-id={user.id} are rendered only when the value is not null or false.
component Rows(users: [User]) { <> <h2>Users</h2> for user in users { <p>{user.name}</p> } </>}Expressions
Version 0.4 supports:
Path expressions are checked against props and loop bindings. Entity field access is resolved through the VTI schema.
- paths: user.name
- booleans: true, false
- strings: "friend"
- null
- null checks: user.deleted_at is null, user.deleted_at is not null
Control Flow
if requires a boolean condition:
for requires a list iterable:
Loops can include a stable key expression after the iterable:
if user.deleted_at is not null { <span>archived</span>}IR
rylae build emits deterministic JSON with component props, prop required/default metadata, lifecycle effects, markup nodes, state, computed values, component calls, fragments, keyed loops, slot placeholders, component-call children, attribute values, binding source text, and resolved binding types. The format identifier is rylae.component.ir.v0.4.
JavaScript Output
rylae build FILE.rylae --target js emits a framework-agnostic vanilla JavaScript module for the first component:
The generated function validates required props at runtime, applies default prop values, evaluates state and computed declarations, renders fragments without wrapper nodes, and preserves keyed loop metadata in the emitted loop body.
export function renderGreeting(props = {}) { // returns an HTML string}Download
Rylae is in active development and has no public downloads or releases yet.
No public download artifacts are available yet for this language.
Looking for everything in one place? See the downloads index.
