DEV Community

Yuuichi Eguchi
Yuuichi Eguchi

Posted on

Constela v0.8.0: 5 New Features for AI-Powered UI Development

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'?
Enter fullscreen mode Exit fullscreen mode

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"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

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" } }
  ]
}
Enter fullscreen mode Exit fullscreen mode

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'))])
});
Enter fullscreen mode Exit fullscreen mode

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 --json flag 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/
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
{
  "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 }
}
Enter fullscreen mode Exit fullscreen mode

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" } }
          ]
        }
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

No JavaScript/TypeScript written. State management, event handling, and conditional styling — all in pure JSON.

Installation

npm install @constela/start
Enter fullscreen mode Exit fullscreen mode

Summary

Constela v0.8.0 adds:

  1. Error suggestions - "Did you mean?" for easy fixes
  2. Style System - CVA-like variant management
  3. Builder API - TypeScript API for AI tools
  4. CLI enhancements - validate, inspect, --json, --watch, --verbose, --debug
  5. AI integration - Structured error output

If you're interested in building UI with pure JSON, give it a try!

Links:

Top comments (0)