DEV Community

Yuuichi Eguchi
Yuuichi Eguchi

Posted on

Introducing AI-Powered UI Generation for Constela

Introduction

Constela is a JSON-first declarative UI framework. With this release, we're adding AI-powered features to supercharge your development workflow:

  • DSL Generator: Generate Constela JSON from natural language prompts
  • Security Validation: Automatically validate generated DSL for safety
  • CLI suggest command: Analyze existing DSL and get improvement suggestions

Installation

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

Features

1. Build-time Component Generation

Use type: "ai" in the data section to generate components at build time:

{
  "version": "1.0",
  "data": {
    "card": {
      "type": "ai",
      "provider": "anthropic",
      "prompt": "A card component with title, description, and action button",
      "output": "component"
    }
  },
  "view": {
    "kind": "component",
    "name": "card",
    "props": {
      "title": { "expr": "lit", "value": "Welcome" },
      "description": { "expr": "lit", "value": "Get started" }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The AI generates a component like:

{
  "kind": "element",
  "tag": "div",
  "props": {
    "className": { "expr": "lit", "value": "card" }
  },
  "children": [
    {
      "kind": "element",
      "tag": "h2",
      "children": [
        { "kind": "text", "value": { "expr": "param", "name": "title" } }
      ]
    },
    {
      "kind": "element",
      "tag": "p",
      "children": [
        { "kind": "text", "value": { "expr": "param", "name": "description" } }
      ]
    },
    {
      "kind": "element",
      "tag": "button",
      "props": {
        "onClick": { "event": "click", "action": "handleAction" }
      },
      "children": [
        { "kind": "text", "value": { "expr": "lit", "value": "Action" } }
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

2. Security Validation

All generated DSL is automatically validated against security rules.

Forbidden Tags (blocked by default):

  • script, iframe, object, embed, form

Forbidden Actions (cannot be whitelisted):

  • import, call, dom

Restricted Actions (require explicit whitelist):

  • fetch

3. CLI suggest Command

Analyze existing DSL files and get AI-powered improvement suggestions:

# Analyze for accessibility issues
constela suggest app.json --aspect accessibility

# Analyze for security (using OpenAI)
constela suggest app.json --aspect security --provider openai

# JSON output for tooling
constela suggest app.json --aspect ux --json
Enter fullscreen mode Exit fullscreen mode

Example output:

=== Suggestions for app.json (accessibility) ===

[HIGH] Missing aria-label on button
   Recommendation: Add aria-label="Submit form" to the button element
   Location: view.children[0].props

[MED] Low color contrast in text
   Recommendation: Increase contrast ratio to meet WCAG AA standards
   Location: view.children[2].props.style

Total: 2 suggestion(s)
Enter fullscreen mode Exit fullscreen mode

4. Runtime Dynamic Generation

Use the generate action step to create DSL in response to user input:

{
  "version": "1.0",
  "state": {
    "userPrompt": { "type": "string", "initial": "" },
    "generatedCard": { "type": "object", "initial": {} }
  },
  "actions": [
    {
      "name": "generateCard",
      "steps": [
        {
          "do": "generate",
          "provider": "anthropic",
          "prompt": { "expr": "state", "name": "userPrompt" },
          "output": "component",
          "result": "generatedCard",
          "onSuccess": [
            {
              "do": "set",
              "target": "card",
              "value": { "expr": "var", "name": "generatedCard" }
            }
          ],
          "onError": [
            {
              "do": "set",
              "target": "error",
              "value": { "expr": "lit", "value": "Generation failed" }
            }
          ]
        }
      ]
    }
  ],
  "view": {
    "kind": "element",
    "tag": "div",
    "children": [
      {
        "kind": "element",
        "tag": "input",
        "props": {
          "type": { "expr": "lit", "value": "text" },
          "value": { "expr": "state", "name": "userPrompt" },
          "onInput": { "event": "input", "action": "updatePrompt" }
        }
      },
      {
        "kind": "element",
        "tag": "button",
        "props": {
          "onClick": { "event": "click", "action": "generateCard" }
        },
        "children": [
          { "kind": "text", "value": { "expr": "lit", "value": "Generate" } }
        ]
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Environment Variables

Create a .env file in your project root and add your API key:

# For Anthropic (Claude)
ANTHROPIC_API_KEY=sk-ant-...

# For OpenAI
OPENAI_API_KEY=sk-...
Enter fullscreen mode Exit fullscreen mode

Make sure .env is in your .gitignore to avoid committing secrets.

How It Works

  1. Prompt Processing: Your natural language description is sent to the AI provider
  2. DSL Generation: The AI generates valid Constela JSON based on the language specification
  3. Security Validation: Generated DSL is validated against security rules
  4. Error Handling: Any validation errors are reported with actionable fixes

Conclusion

With @constela/ai, you can leverage AI to:

  • Generate JSON DSL from natural language
  • Automatically validate security
  • Get improvement suggestions for existing code

Check out the official documentation for more details.


Links:

Top comments (0)