json-render-ui — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited json-render-ui (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
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 → UIClaude 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
}
}Claude can ONLY use these components. This is the guardrail.
| Component | Props | Children | Description | ||||||
|---|---|---|---|---|---|---|---|---|---|
Card | title?, description?, `padding?: sm\ | md\ | lg` | Yes | Container with optional header | ||||
Grid | columns?: 1-4, `gap?: sm\ | md\ | lg` | Yes | CSS grid layout | ||||
Stack | `direction?: horizontal\ | vertical, gap?: sm\ | md\ | lg, align?: start\ | center\ | end\ | stretch` | Yes | Flexbox stack |
| Component | Props | Children | Description | ||||
|---|---|---|---|---|---|---|---|
Metric | label, valuePath, `format?: number\ | currency\ | percent, trend?: up\ | down\ | neutral, trendValue?` | No | Single KPI display |
Chart | `type: bar\ | line\ | pie\ | area, dataPath, title?, height?` | No | Data visualization | |
Table | dataPath, `columns: [{key, label, format?: text\ | currency\ | date\ | badge}]` | No | Tabular data | |
List | dataPath, emptyMessage? | Yes | Rendered list from array |
| Component | Props | Children | Description | |||||
|---|---|---|---|---|---|---|---|---|
Button | label, action, `variant?: primary\ | secondary\ | danger\ | ghost, size?: sm\ | md\ | lg, disabled?` | No | Clickable action |
Select | label?, bindPath, options: [{value, label}], placeholder? | No | Dropdown select | |||||
DatePicker | label?, bindPath, placeholder? | No | Date input |
| Component | Props | Children | Description | ||||||
|---|---|---|---|---|---|---|---|---|---|
Heading | text, `level?: h1\ | h2\ | h3\ | h4` | No | Section heading | |||
Text | content, `variant?: body\ | caption\ | label, color?: default\ | muted\ | success\ | warning\ | danger` | No | Text paragraph |
| Component | Props | Children | Description | ||||
|---|---|---|---|---|---|---|---|
Badge | text, `variant?: default\ | success\ | warning\ | danger\ | info` | No | Status indicator |
Alert | `type: info\ | success\ | warning\ | error, title, message?, dismissible?` | No | Notification banner |
| Component | Props | Children | Description |
|---|---|---|---|
Divider | label? | No | Visual separator |
Empty | title, description?, action?, actionLabel? | No | Empty state |
Props ending in Path (e.g., valuePath, dataPath, bindPath) reference the data model using JSON Pointer syntax:
/revenue → data.revenue/users/0/name → data.users[0].name/filters/dateRange → data.filters.dateRangeAny 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] } — EqualityAnalyze the user's request and emit a UITree structure. Include sample data that matches the schema.
Create an HTML artifact that:
assets/renderer.js (inline it)Use the template in assets/template.html.
DO:
DO NOT:
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.
assets/template.html — Complete artifact template with embedded rendererassets/catalog.json — Machine-readable component schemasreferences/uitree-format.md — Detailed UITree specification~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.