Introduction
Constela is a compiler-first UI language. You write UI in pure JSON — no JavaScript/TypeScript required. The compiler validates and optimizes it, then it runs in the browser.
With v0.8.0, we've shipped major updates designed for AI-powered UI development. Here are the 5 new features.
1. "Did you mean?" Error Suggestions
When you make a typo, Constela now suggests the correct name:
Error [UNDEFINED_STATE] at /view/children/0/value/name
Undefined state reference: 'count'
Did you mean 'counter'?
It uses Levenshtein distance to find similar names. This makes it easier for AI to automatically fix compile-time errors.
2. Style System - CVA-like Style Management
We've introduced a style system similar to CVA (Class Variance Authority).
Define style presets
{
"styles": {
"button": {
"base": "px-4 py-2 rounded font-medium transition-colors",
"variants": {
"variant": {
"primary": "bg-blue-500 text-white hover:bg-blue-600",
"secondary": "bg-gray-200 text-gray-800 hover:bg-gray-300"
},
"size": {
"sm": "text-sm h-8",
"md": "text-base h-10",
"lg": "text-lg h-12"
}
},
"defaultVariants": {
"variant": "primary",
"size": "md"
}
}
}
}
Reference styles in views
{
"kind": "element",
"tag": "button",
"props": {
"className": {
"expr": "style",
"name": "button",
"variants": {
"variant": { "expr": "state", "name": "buttonVariant" }
}
}
},
"children": [
{ "kind": "text", "value": { "expr": "lit", "value": "Click me" } }
]
}
Key points:
- Dynamic variant switching via state
- Compile-time validation of style/variant names
- Works with existing Tailwind CSS classes
3. @constela/builder - Write in TypeScript Too
For those who prefer TypeScript over writing JSON directly, we've added a Builder API.
Counter App Example
import {
createProgram, numberField, action, increment,
button, text, state, onClick
} from '@constela/builder';
const counter = createProgram({
state: { count: numberField(0) },
actions: [action('increment', [increment('count')])],
view: button({ onClick: onClick('increment') }, [text(state('count'))])
});
40+ Builder Functions
Covers all DSL elements:
| Category | Functions |
|---|---|
| Expression |
lit, state, variable, bin, cond, get, add, eq, and, or, etc. |
| State |
numberField, stringField, booleanField, listField, objectField
|
| Action |
action, set, update, increment, push, fetch, navigate, etc. |
| View |
element, div, button, text, ifNode, each, component, slot
|
| Event |
onClick, onInput, onChange, onSubmit
|
Same Benefits as JSON
Even when written in TypeScript, it gets converted to JSON. That means:
- Compile-time error detection - Errors if you reference undefined state or actions
- "Did you mean?" suggestions - Typos get corrected with helpful hints
-
Structured error output - AI integration with
--jsonflag works seamlessly
4. CLI Enhancements
validate command
Fast validation without full compilation:
# Single file
constela validate app.json
# Entire directory
constela validate --all src/routes/
inspect command
Visualize program structure:
$ constela inspect app.json
State (2 fields):
count: number = 0
items: list = []
Actions (2):
increment: update count +1
addItem: push to items
View Tree:
element<div>
text: state.count
element<button> onClick=increment
New flags
| Flag | Description |
|---|---|
--json |
JSON output (for AI tooling) |
--watch |
Watch and recompile on changes |
--verbose |
Show timing for each pass |
--debug |
Internal debug info |
--watch for faster development
constela compile app.json --watch
Automatically recompiles when you save the file.
--verbose for detailed output
$ constela compile app.json --verbose
[1/3] Validating schema... OK (2ms)
[2/3] Analyzing semantics... OK (1ms)
[3/3] Transforming AST... OK (0ms)
Summary:
States: 2
Actions: 3
View nodes: 12
Compilation successful (5ms total)
5. Designed for AI/LLM Integration
This update is built with "AI-generated UI" in mind:
| Feature | Benefit for AI |
|---|---|
--json output |
Structured error information |
| Error suggestions | Easy to identify fixes |
| Style System | Consistent, reusable styles |
| JSON DSL | Easy format for AI to generate |
When AI-generated JSON has errors:
$ constela compile app.json --json
{
"success": false,
"errors": [{
"code": "UNDEFINED_STATE",
"message": "Undefined state reference: 'count'",
"path": "/view/children/0/value/name",
"suggestion": "Did you mean 'counter'?",
"context": { "availableNames": ["counter", "items"] }
}],
"diagnostics": { "duration": 5 }
}
Feed this back to your LLM for automatic fixes.
Complete Todo List Example
You can build a complete todo list app with pure JSON:
{
"version": "1.0",
"styles": {
"todoItem": {
"base": "flex items-center gap-2 p-2",
"variants": {
"done": {
"true": "opacity-50 line-through",
"false": ""
}
}
}
},
"state": {
"todos": { "type": "list", "initial": [] },
"newTodo": { "type": "string", "initial": "" }
},
"actions": [
{
"name": "setNewTodo",
"steps": [
{ "do": "set", "target": "newTodo", "value": { "expr": "var", "name": "value" } }
]
},
{
"name": "addTodo",
"steps": [
{
"do": "update",
"target": "todos",
"operation": "push",
"value": { "expr": "lit", "value": { "text": "", "done": false } }
},
{ "do": "set", "target": "newTodo", "value": { "expr": "lit", "value": "" } }
]
}
],
"view": {
"kind": "element",
"tag": "div",
"props": { "className": { "expr": "lit", "value": "p-4 max-w-md mx-auto" } },
"children": [
{
"kind": "element",
"tag": "div",
"props": { "className": { "expr": "lit", "value": "flex gap-2 mb-4" } },
"children": [
{
"kind": "element",
"tag": "input",
"props": {
"type": { "expr": "lit", "value": "text" },
"value": { "expr": "state", "name": "newTodo" },
"placeholder": { "expr": "lit", "value": "Add a todo..." },
"className": { "expr": "lit", "value": "flex-1 border rounded px-2 py-1" },
"onInput": { "event": "input", "action": "setNewTodo", "payload": { "expr": "var", "name": "value" } }
}
},
{
"kind": "element",
"tag": "button",
"props": {
"className": { "expr": "style", "name": "button" },
"onClick": { "event": "click", "action": "addTodo" }
},
"children": [
{ "kind": "text", "value": { "expr": "lit", "value": "Add" } }
]
}
]
},
{
"kind": "each",
"items": { "expr": "state", "name": "todos" },
"as": "todo",
"index": "i",
"body": {
"kind": "element",
"tag": "div",
"props": {
"className": {
"expr": "style",
"name": "todoItem",
"variants": {
"done": { "expr": "get", "base": { "expr": "var", "name": "todo" }, "path": "done" }
}
}
},
"children": [
{ "kind": "text", "value": { "expr": "get", "base": { "expr": "var", "name": "todo" }, "path": "text" } }
]
}
}
]
}
}
No JavaScript/TypeScript written. State management, event handling, and conditional styling — all in pure JSON.
Installation
npm install @constela/start
Summary
Constela v0.8.0 adds:
- Error suggestions - "Did you mean?" for easy fixes
- Style System - CVA-like variant management
- Builder API - TypeScript API for AI tools
- CLI enhancements - validate, inspect, --json, --watch, --verbose, --debug
- AI integration - Structured error output
If you're interested in building UI with pure JSON, give it a try!
Links:
Top comments (0)