agentsclimarketplace

Json render ui

Skill oaustegard/claude-skills/plugins/data-and-visualization/skills/json-render-ui

My collection of Claude skills

Install
npx -y skills add oaustegard/claude-skills --skill json-render-ui

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

What its author says it does

Copied from the file, not written here

Generate guardrailed UI from natural language. Emits constrained JSON that a Preact runtime renders. Use when the request is for a dashboard with metrics, charts, or tables; an admin panel; a data visualization interface; or a form-based application.

SKILL.md

7.7 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it

JSON Render UI

Overview

Transform natural language UI requests into working dashboards and applications. Claude acts as the translation layer (prompt → JSON), the skill provides the rendering runtime (JSON → UI).

Architecture:

User prompt → Claude (constrained by catalog) → UITree JSON → Preact renderer → UI

Output Format

Claude emits a UITree structure:

{
  "root": "main",
  "elements": {
    "main": {
      "key": "main",
      "type": "Grid",
      "props": { "columns": 2, "gap": "md" },
      "children": ["metric1", "metric2"]
    },
    "metric1": {
      "key": "metric1",
      "type": "Metric",
      "props": {
        "label": "Revenue",
        "valuePath": "/revenue",
        "format": "currency"
      }
    },
    "metric2": {
      "key": "metric2",
      "type": "Metric",
      "props": {
        "label": "Growth",
        "valuePath": "/growth",
        "format": "percent"
      }
    }
  },
  "data": {
    "revenue": 125000,
    "growth": 0.15
  }
}

Component Catalog

Claude can ONLY use these components. This is the guardrail.

Layout Components

ComponentPropsChildrenDescription
Cardtitle?, description?, padding?: sm|md|lgYesContainer with optional header
Gridcolumns?: 1-4, gap?: sm|md|lgYesCSS grid layout
Stackdirection?: horizontal|vertical, gap?: sm|md|lg, align?: start|center|end|stretchYesFlexbox stack

Data Display

ComponentPropsChildrenDescription
Metriclabel, valuePath, format?: number|currency|percent, trend?: up|down|neutral, trendValue?NoSingle KPI display
Charttype: bar|line|pie|area, dataPath, title?, height?NoData visualization
TabledataPath, columns: [{key, label, format?: text|currency|date|badge}]NoTabular data
ListdataPath, emptyMessage?YesRendered list from array

Interactive

ComponentPropsChildrenDescription
Buttonlabel, action, variant?: primary|secondary|danger|ghost, size?: sm|md|lg, disabled?NoClickable action
Selectlabel?, bindPath, options: [{value, label}], placeholder?NoDropdown select
DatePickerlabel?, bindPath, placeholder?NoDate input

Typography

ComponentPropsChildrenDescription
Headingtext, level?: h1|h2|h3|h4NoSection heading
Textcontent, variant?: body|caption|label, color?: default|muted|success|warning|dangerNoText paragraph

Status

ComponentPropsChildrenDescription
Badgetext, variant?: default|success|warning|danger|infoNoStatus indicator
Alerttype: info|success|warning|error, title, message?, dismissible?NoNotification banner

Special

ComponentPropsChildrenDescription
Dividerlabel?NoVisual separator
Emptytitle, description?, action?, actionLabel?NoEmpty state

Data Binding

Props ending in Path (e.g., valuePath, dataPath, bindPath) reference the data model using JSON Pointer syntax:

  • /revenuedata.revenue
  • /users/0/namedata.users[0].name
  • /filters/dateRangedata.filters.dateRange

Visibility Conditions

Any element can have a visible property:

{
  "type": "Alert",
  "props": { "type": "error", "title": "Error" },
  "visible": { "path": "/hasError" }
}

Visibility expressions:

  • true / false — Static
  • { "path": "/some/path" } — Truthy check
  • { "and": [...] } — All conditions true
  • { "or": [...] } — Any condition true
  • { "not": {...} } — Negation
  • { "eq": [a, b] } — Equality

Generating Output

Step 1: Emit UITree JSON

Analyze the user's request and emit a UITree structure. Include sample data that matches the schema.

Step 2: Create Artifact

Create an HTML artifact that:

  1. Embeds the UITree JSON
  2. Renders the UI

Start from assets/template.html, which already carries the embedded renderer — there is no separate renderer.js to inline.

Constraints

DO:

  • Use only catalog components
  • Provide realistic sample data
  • Use semantic component choices (Metric for KPIs, Table for tabular data)
  • Keep trees flat (no deep nesting beyond 3 levels)

DO NOT:

  • Invent new component types
  • Use arbitrary HTML/CSS
  • Omit required props
  • Create deeply nested structures

Example

User: "Create a sales dashboard with revenue, orders, and a chart showing monthly trends"

Claude outputs:

{
  "root": "dashboard",
  "elements": {
    "dashboard": {
      "key": "dashboard",
      "type": "Stack",
      "props": { "direction": "vertical", "gap": "lg" },
      "children": ["header", "metrics", "chartCard"]
    },
    "header": {
      "key": "header",
      "type": "Heading",
      "props": { "text": "Sales Dashboard", "level": "h1" }
    },
    "metrics": {
      "key": "metrics",
      "type": "Grid",
      "props": { "columns": 3, "gap": "md" },
      "children": ["revenue", "orders", "avgOrder"]
    },
    "revenue": {
      "key": "revenue",
      "type": "Card",
      "props": { "padding": "md" },
      "children": ["revenueMetric"]
    },
    "revenueMetric": {
      "key": "revenueMetric",
      "type": "Metric",
      "props": {
        "label": "Total Revenue",
        "valuePath": "/revenue",
        "format": "currency",
        "trend": "up",
        "trendValue": "12%"
      }
    },
    "orders": {
      "key": "orders",
      "type": "Card",
      "props": { "padding": "md" },
      "children": ["ordersMetric"]
    },
    "ordersMetric": {
      "key": "ordersMetric",
      "type": "Metric",
      "props": {
        "label": "Orders",
        "valuePath": "/orders",
        "format": "number"
      }
    },
    "avgOrder": {
      "key": "avgOrder",
      "type": "Card",
      "props": { "padding": "md" },
      "children": ["avgMetric"]
    },
    "avgMetric": {
      "key": "avgMetric",
      "type": "Metric",
      "props": {
        "label": "Avg Order Value",
        "valuePath": "/avgOrderValue",
        "format": "currency"
      }
    },
    "chartCard": {
      "key": "chartCard",
      "type": "Card",
      "props": { "title": "Monthly Trends", "padding": "md" },
      "children": ["chart"]
    },
    "chart": {
      "key": "chart",
      "type": "Chart",
      "props": {
        "type": "line",
        "dataPath": "/monthlyData",
        "height": 300
      }
    }
  },
  "data": {
    "revenue": 284500,
    "orders": 1247,
    "avgOrderValue": 228,
    "monthlyData": [
      { "month": "Jan", "value": 18000 },
      { "month": "Feb", "value": 22000 },
      { "month": "Mar", "value": 28000 },
      { "month": "Apr", "value": 24000 },
      { "month": "May", "value": 32000 }
    ]
  }
}

Then wrap in the artifact template from assets/template.html.

Files

  • assets/template.html — Complete artifact template with embedded renderer
  • assets/catalog.json — Machine-readable component schemas
  • references/uitree-format.md — Detailed UITree specification

What ships with it: 4 files

33.3 KB alongside SKILL.md

assets/

references/

Keep looking

Skills are one crate of 327,069. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.