| name | claw2ui |
| description | Generate interactive web pages (dashboards, charts, tables, reports) and serve them via public URL. Use this skill when the user explicitly asks for data visualization, dashboards, analytics reports, comparison tables, status pages, or web-based content. Also triggers for: "draw me a chart", "make a dashboard", "show me a table", "generate a report", "visualize this data", "render this as a page", "publish a page", "claw2ui". If the response would benefit from charts, sortable tables, or rich layout, **suggest** using Claw2UI and wait for user confirmation before publishing. Chinese triggers: "做个仪表盘", "画个图表", "做个报表", "生成一个页面", "做个dashboard", "数据可视化", "做个网页", "展示数据", "做个表格", "做个图", "发布一个页面", "做个看板". Additional English triggers: "create a webpage", "show analytics", "build a status page", "make a chart", "data overview", "show me stats", "create a board", "render a page", "comparison chart", "trend analysis", "pie chart", "bar chart", "line chart", "KPI dashboard", "metrics overview", "weekly report", "monthly report". |
| license | MIT |
| metadata | {"openclaw":{"emoji":"📊","requires":{"bins":"[Truncated]","optionalBins":"[Truncated]"},"install":["[Truncated]","[Truncated]"],"sideEffects":["Writes ~/.claw2ui.json (server URL and API token for authentication)","Publishes page content to a public URL (default: https://0xsegfaulted-claw2ui.hf.space)","Requires explicit user confirmation before every publish"],"permissions":["network: POST page content to Claw2UI server API","filesystem: write ~/.claw2ui.json (auth token), /tmp/*.ts (temp spec files)"]}} |
Claw2UI - Agent-to-UI Bridge
Generate interactive web pages from TypeScript DSL specs and serve them via a public URL. Pages include Tailwind CSS, Alpine.js, and Chart.js out of the box, with pluggable themes, type checking, and mobile-responsive layouts.
Source: GitHub · npm · HF Space · License: MIT
Data Safety & User Confirmation
Every published page is accessible via a public URL. Never publish without explicit user approval.
- Always confirm with the user before publishing — describe what will be published and wait for explicit "yes"/"go ahead". Silent publishing is never acceptable
- Never include secrets, credentials, API keys, tokens, PII, or internal endpoints in page content
- Sanitize all user-provided data before embedding — the
html component is sanitized server-side, but avoid passing raw untrusted input to other components
- Use TTL for ephemeral or sensitive data so pages auto-expire:
--ttl 3600000 (1 hour)
- Review content before publishing — check that no sensitive information leaks through table rows, stat values, or chart labels
Setup
Claw2UI uses the public server at https://0xsegfaulted-claw2ui.hf.space by default. No local server needed.
npm install -g claw2ui
claw2ui register --server https://0xsegfaulted-claw2ui.hf.space
Self-hosting: To run your own Claw2UI server (local, Docker, or HF Space), see the self-hosting guide.
Workflow
Step 1: Ensure Connection
claw2ui register --server https://0xsegfaulted-claw2ui.hf.space
Step 2: Write a TypeScript DSL Spec
Write a .ts file. Always wrap content in a container. The file is type-checked automatically.
cat > /tmp/claw2ui_page.ts << 'SPECEOF'
import { page, container, header, row, stat, card, chart, dataset } from "claw2ui/dsl"
export default page("Page Title", [
container(
header("Title", "Description"),
row(3,
stat("Metric 1", "100", { change: 5.2, icon: "trending_up" }),
stat("Metric 2", "200"),
stat("Metric 3", "300"),
),
card("Trend",
chart("line", {
labels: ["Jan", "Feb", "Mar"],
datasets: [dataset("Value", [10, 20, 15], { borderColor: "#3b82f6", tension: 0.3 })],
}),
),
),
], { style: "anthropic" })
SPECEOF
Step 3: Confirm with User
Before publishing, tell the user what will be published and confirm they want to proceed. The page will be accessible via a public URL. Example:
"I've prepared a dashboard with [summary of content]. Ready to publish it to a public URL? (Use --ttl 3600000 for auto-expiry in 1 hour.)"
Step 4: Publish
Only after user confirmation:
claw2ui publish --spec-file /tmp/claw2ui_page.ts --title "Dashboard"
claw2ui publish --spec-file /tmp/claw2ui_page.ts --title "Dashboard" --ttl 3600000
claw2ui publish --spec-file /tmp/claw2ui_page.ts --title "Dashboard" --no-check
Outputs the public URL.
Step 5: Share the URL
Include the URL in your response to the user.
CLI Commands
claw2ui register --server <url>
claw2ui init --server <url> --token <t>
claw2ui publish --spec-file <file.ts> --title "Title"
claw2ui publish --spec-file <file.ts> --no-check
claw2ui publish --spec-file <file.json> --title "Title"
claw2ui publish --html "<h1>Hi</h1>" --title "Test"
claw2ui publish --spec-file <file> --style anthropic
claw2ui publish --spec-file <file> --ttl 3600000
claw2ui themes
claw2ui list
claw2ui delete <page-id>
claw2ui status
DSL Function Reference
All functions are imported from "claw2ui/dsl".
Page Entry
page(title, components[], opts?)
Layout (accept ...children)
container(...children)
row(cols, ...children)
column(span, ...children)
card(title, ...children)
list(direction, ...children)
modal(title, ...children)
Special Containers
tabs(
tab("id", "Label", ...children),
tab("id2", "Label 2", ...children),
)
accordion(
section("Title", ...children),
section("Title 2", ...children),
)
Data Display
stat(label, value, opts?)
chart(chartType, data, opts?)
table(columns, rows, opts?)
Helpers (for chart/table)
dataset(label, data[], opts?)
col(key, label?, format?)
badge(key, label, badgeMap)
months(n)
Input
button(label, variant?)
textField(label?, opts?)
select(label, options)
checkbox(label, value?)
choicePicker(label, options, opts?)
slider(label, opts?)
dateTimeInput(label, opts?)
Media & Text
markdown(content)
text(content, opts?)
code(content, language?)
html(content)
icon(name, size?)
image(src, alt?)
video(url, poster?)
audioPlayer(url, description?)
divider()
spacer(size?)
Navigation
header(title, subtitle?)
link(href, label?, target?)
Available Themes (style field)
| Theme | Description |
|---|
anthropic | (default) Warm editorial aesthetic — Newsreader serif headings, terracotta accents, cream backgrounds |
classic | Original Tailwind look — blue accents, system fonts, gray surfaces |
Best Practices
Always use TypeScript DSL, not JSON
The DSL is type-checked, uses ~60% fewer tokens, and supports logic. JSON specs are still supported but considered legacy.
Use loops and conditionals
const metrics = [
{ label: "CPU", value: "42%", icon: "monitor" },
{ label: "Memory", value: "6.2 GB", icon: "memory" },
{ label: "Disk", value: "120 MB/s", icon: "storage" },
]
row(3, ...metrics.map(m => stat(m.label, m.value, { icon: m.icon })))
container(
header("Report"),
data.length > 0
? card("Trend", chart("line", chartData))
: text("No data available"),
)
container(
header("Dashboard"),
showMetrics && row(3, stat("A", "1"), stat("B", ), (, )),
(, (cols, rows)),
)
Prefer col() / badge() / dataset() helpers
table(
[col("name", "Name"), col("rev", "Revenue", "currency"), badge("status", "Status", { Active: "success" })],
rows,
)
table(
[{ key: "name", label: "Name" }, { key: "rev", label: "Revenue", format: "currency" }, { key: "status", label: "Status", format: "badge", badgeMap: { Active: "success" } }],
rows,
)
Use markdown() for rich text
card("About",
markdown(`
## Features
- **Fast** — sub-second rendering
- **Secure** — sanitized HTML output
- **Responsive** — mobile-first layouts
> Built with Claw2UI
`),
)
Use months() for chart labels
chart("bar", {
labels: months(6),
datasets: [dataset("Revenue", [100, 200, 150, 300, 250, 400])],
})
Design Patterns
Dashboard
import { page, container, header, row, stat, card, chart, table, col, badge, dataset } from "claw2ui/dsl"
export default page("Dashboard", [
container(
header("Dashboard", "Overview"),
row(3,
stat("Revenue", "$1.2M", { change: 15.3, icon: "payments" }),
stat("Orders", "8,432", { change: 8.1, icon: "shopping_cart" }),
stat("Customers", "2,847", { change: -2.5, icon: "group" }),
),
card("Trend",
chart("line", {
labels: months(6),
datasets: [dataset("Revenue", [320, 410, 380, 450, 480, 520], {
borderColor: "#3b82f6", tension: , : ,
: ,
})],
}, { : }),
),
(,
(
[(, ), (, , ), (, , { : , : })],
[
{ : , : , : },
{ : , : , : },
{ : , : , : },
],
),
),
),
], { : })
Report with Tabs
import { page, container, header, row, stat, card, chart, table, tabs, tab, text, markdown, col, dataset, months } from "claw2ui/dsl"
export default page("Monthly Report", [
container(
header("Monthly Report", "March 2026"),
tabs(
tab("overview", "Overview",
row(3,
stat("Users", "12,847", { change: 18.5, icon: "group" }),
stat("Revenue", "$89K", { change: 24.3, icon: "payments" }),
stat("Churn", "3.2%", { change: -1.1, icon: "trending_down" }),
),
card("Growth",
chart("line", {
labels: months(6),
datasets: [
dataset("Users", [8000, 9200, 10100, , , ], { : }),
(, [, , , , , ], { : , : }),
],
}),
),
),
(, ,
(
[(, ), (, ), (, , )],
[
{ : , : , : },
{ : , : , : },
{ : , : , : },
],
),
),
(, ,
(),
),
),
),
], { : })
Comparison
import { page, container, header, row, card, stat, text, table, col } from "claw2ui/dsl"
export default page("Plan Comparison", [
container(
header("Plan Comparison", "Choose the right plan"),
row(3,
card("Starter",
stat("Price", "$9/mo"),
text("5 users, 10 GB storage"),
),
card("Pro",
stat("Price", "$29/mo", { icon: "star" }),
text("25 users, 100 GB storage"),
),
card("Enterprise",
stat("Price", "Custom", { icon: "business" }),
text("Unlimited users, 1 TB storage"),
),
),
card("Feature Matrix",
table(
[col("feature", "Feature"), col("starter", "Starter"), col("pro", ), (, )],
[
{ : , : , : , : },
{ : , : , : , : },
{ : , : , : , : },
],
),
),
),
], { : })