Language Specification
.wraf v1.0 Beta — Formal reference for the wrafjs DSL.
wrafjs v1.0 is currently in beta. The language spec, control set, and toolchain are stable for experimentation but subject to breaking changes before the final release.
Philosophy
wrafjs is an AI-first language for describing UI wireframes as structured text.
- Token efficiency — no redundant keywords, no decorative syntax
- LLM determinism — one way to express each concept, no equivalent alternatives
- Single-file — one screen per file
- Structure over behavior — describes what is visible, not what it does
File model
A .wraf file contains exactly one root node of type Screen.
Screen {
width: 1440
height: 900
Navbar { title: "My App" }
Row {
Sidebar { }
Column {
Text { text: "Welcome" variant: title }
}
}
}
Rules:
- The root node must be
Screen. widthandheightare required onScreen.- Multiple root nodes is a parse error.
Grammar
File ::= Node
Node ::= Identifier Identifier? "{" Body "}"
Body ::= (Property | Node)*
Property ::= Identifier ":" Value
Value ::= String | Number | Boolean | Enum | Percent
| Token | Symbol | Role |
|---|---|---|
{ } | LBrace / RBrace | Open / close node body |
: | Colon | Separates property name and value |
// | LineComment | Comment to end of line |
/* */ | BlockComment | Multi-line comment |
Lexical rules:
- The language is case-insensitive for node names, labels, and enum values.
- Whitespace (space, tab, newline) is ignored.
- Duplicate properties on the same node are an error.
- A node may have an optional label after its type (
Card MetricsPanel { }) — structural metadata, not rendered.
Value types
| Type | Syntax | Example |
|---|---|---|
| String | "text" | text: "Save" |
| Number | bare integer | width: 360 |
| Boolean | true / false | checked: true |
| Enum | bare identifier | variant: primary |
| Percent | number + % | width: 50% |
- Strings always use double quotes. Single quotes are not valid.
- Enums are never quoted.
variant: "primary"is an error. - Percent values resolve against the parent's available width or height.
Global properties
Valid on any node.
| Property | Type | Description |
|---|---|---|
width | number | percent | Node width |
height | number | percent | Node height |
x | number | Horizontal position relative to parent |
y | number | Vertical position relative to parent |
padding | number | Inner inset |
gap | number | Space between children in auto-layout |
layout | horizontal | vertical | Child flow direction |
growMode | vertical | horizontal | none | Sizing behavior when dimensions are not explicit |
position | enum (9-point) | Floating anchor within parent |
hidden | boolean | Exclude node from render |
disabled | boolean | Apply disabled appearance |
x/y and position are mutually exclusive. If both are declared, x/y takes precedence.
Layout system
Auto-layout
Children without explicit x/y are positioned automatically.
layout: vertical(default) — children stacked top to bottomlayout: horizontal— children stacked left to rightgap— space between consecutive children (default:8)padding— inset from the container edge (default varies by node type)
GrowMode
| Value | Width | Height |
|---|---|---|
vertical (default) | fill — takes all available width | shrink — fits content height |
horizontal | shrink — fits content width | fill — takes all available height |
none | fixed — requires explicit width | fixed — requires explicit height |
Position (9-point anchor)
position floats a node at one of 9 named regions inside its parent's content area, without advancing the auto-layout cursor.
| Left | Center | Right | |
|---|---|---|---|
| Top | topleft | top | topright |
| Middle | left | center | right |
| Bottom | bottomleft | bottomcenter | bottomright |
Requires explicit width and height on the node.
Padding defaults by node
| Node | padding | gap |
|---|---|---|
Screen, Row, Column | 0 | 8 |
Navbar, Tabbar | 8 | 8 |
Sidebar | 12 | 4 |
Card, Form | 16 | 12 |
Modal, Drawer | 24 | 16 |
ScrollView | 16 | 8 |
Menu | 4 | 0 |
| Other | 10 | 8 |
Text system
The variant property sets semantic size and weight on text nodes.
| Variant | Size | Weight |
|---|---|---|
display | 36px | bold |
title | 28px | bold |
heading | 22px | bold |
subheading | 18px | bold |
body | 15px | normal |
caption | 13px | normal |
overline | 11px | bold |
annotation | 11px | normal |
HTML aliases: h1–h6 map to display–caption.
Text properties: text, variant, weight, align, italic, truncate, color.
Controls reference
Quick reference of all nodes and their intrinsic heights.
For per-control properties and examples, see the sidebar sections.
| Node | Intrinsic height | Category |
|---|---|---|
Screen | — (root) | Root |
Row, Column | shrink | Layout |
Card | shrink | Layout |
Modal | shrink | Overlay |
Drawer | fill | Overlay |
ScrollView | shrink | Overlay |
Navbar | 48px | Navigation |
Sidebar | fill | Navigation |
Tabbar / Tab | 48px / 40px | Navigation |
Breadcrumb | 32px | Navigation |
Pagination | 36px | Navigation |
Menu / MenuItem | shrink / 36px | Navigation |
Text, Heading | 36px / 28px | Screen & Sizing |
Label | 24px | — |
Paragraph | dynamic | — |
Badge | 20px | Display Controls |
Avatar | size-dependent | Display Controls |
Icon | 20px | Display Controls |
Image | declare explicitly | Display Controls |
Separator / Divider | 1px | Display Controls |
List / ListItem | shrink / 36–48px | Data Display |
Table / TableRow | shrink / 40px | Data Display |
Skeleton | lines × 20px | Display Controls |
Button | 36px (size-dependent) | Input Controls |
Input / Password / Search | 36px | Input Controls |
TextArea | rows × lineH + 16 | Input Controls |
Select / Dropdown | 36px | Input Controls |
Checkbox / Radio | 24px | Input Controls |
Switch / Toggle | 20px | Input Controls |
Slider | 24px | Input Controls |
FileUpload | 64px | Input Controls |
Form | shrink | Input Controls |
Alert / Toast | 48px | Display Controls |
Tooltip | 32px | Display Controls |
Progress | 8px | Display Controls |
Spinner | size-dependent | Display Controls |
Validation
The validator runs on the AST after parsing and reports:
- Error — invalid node or property; render should not proceed
- Warning — valid but suspicious
| Code | Description |
|---|---|
E001 | Root node is not Screen |
E002 | Screen missing width or height |
E003 | Unknown property for node type |
E004 | Wrong value type (e.g., enum with quotes, string without quotes) |
E005 | Duplicate property on the same node |
W001 | Node has no explicit dimensions and no known intrinsic size |
W002 | Button has declared children |