Gen Ui
Generative UI toolkit for OpenCode AI agents — reactive Solid.js widgets (charts, tables, maps, diagrams, 3D), sandboxed iframe rendering, and OpenCode tool/plugin integration.
0
239
近 7 天 10
33.8
生态多维模型
21 天前
2026-09-13
快速安装与配置
opencode.json写入当前项目的 opencode.json,只对这个仓库生效。
opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-gen-ui@1.1.0"]
}写入 ~/.config/opencode/opencode.json,对所有项目生效。
~/.config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-gen-ui@1.1.0"]
}若你要在本地改造这个插件,先装到项目里再从本地路径引用。
shell
pnpm add -D opencode-gen-uiOpenCode 启动时会通过内嵌运行时自动加载 npm 依赖并缓存至本地目录,无需手动在全局环境执行安装。
Rich, interactive, sandboxed Generative UI rendering system for OpenCode AI agents.
opencode-gen-ui enables AI models to dynamically generate and render interactive UI components—from standard KPI cards and data tables to rich 3D scenes, maps, and diagrams—directly within chat applications.
Package layout — read this before importing
The package is split into two halves that resolve very differently:
| Import | Depends on | Works outside OpenCode? |
|---|---|---|
opencode-gen-ui (root) |
solid-js only |
Yes — but see the CSS note below |
opencode-gen-ui/schema |
nothing | Yes, always. Zero dependencies — safe for any Node script, server, or MCP tool that just needs the widget schema types. |
opencode-gen-ui/registry |
nothing | Yes, always. |
opencode-gen-ui/renderer, /dialog-renderer, /ui/catalog/*, /ui/plugins/* |
solid-js + the relevant viz library |
Yes in any Solid + bundler context (Vite, webpack, OpenCode's own build). Not in plain Node with no DOM — these render real UI. The /ui/plugins/leaflet widget also side-imports Leaflet's CSS, which only a bundler can resolve; a plain node --experimental-vm import of it (or of the root barrel, which re-exports it) will throw on that CSS import. |
opencode-gen-ui/tools/browser |
Node's child_process only |
Yes, standalone — no OpenCode required. |
opencode-gen-ui/opencode-plugin, /tools/a2ui, /tools/weather |
opencode/tool/tool (and @opencode-ai/ui/* for the cards) |
No — these only resolve inside a real OpenCode runtime by design. Importing them elsewhere throws a clear "Cannot find package 'opencode'" error rather than silently breaking. |
If you're building something that isn't OpenCode itself (a script, a server, an MCP tool) and you only need the widget schema/types, import opencode-gen-ui/schema — it has no runtime dependencies at all.
✨ Features
- ⚡ Reactive & Lightweight: Built with Solid.js for lightning-fast rendering and minimal overhead.
- 🔒 Sandboxed Execution: Isolated iframe runner ensuring safe script execution for dynamic HTML and 3D visualization widgets.
- 🤖 LLM Tool Support: Built-in
render_uitool definitions powered by Effect TS for seamless AI tool-calling. - 📊 Built-in Widget Catalog: Ready-to-use components including Line Charts, Bar Charts, Metric Cards, Timelines, Progress Indicators, and Data Tables.
- 🔌 Rich Plugin Ecosystem: Out-of-the-box support for popular visualization libraries:
- Mermaid: Flowcharts and sequence diagrams
- Plotly: Multi-series statistical charts
- D3.js: Custom SVG data visualizations
- AG-Grid: High-performance interactive data grids
- Leaflet: Interactive geospatial maps
- Three.js: Interactive 3D graphics and scenes
- 🌐 Standalone browser control tool: Docker-sandboxed browser automation, usable without OpenCode.
📦 Installation
npm install opencode-gen-ui
This installs a compiled dist/ (real .js + .d.ts, not raw TypeScript), so it works with plain Node's module resolution — no bundler required for the OpenCode-independent subpaths.
solid-js and effect are peer dependencies — install them in your project if you don't already have them:
npm install solid-js effect
📁 Repository Structure
gen-ui/
├── schema.ts # Core TypeScript types (WidgetSchema, GenUISchema, DialogSchema) — zero dependencies
├── registry.ts # Widget route resolution — zero dependencies
├── renderer.tsx # Solid.js reactive renderer and sandboxed iframe wrapper
├── dialog-renderer.tsx # Dialog schema renderer
├── opencode-plugin.ts # OpenCode plugin manifest (tools + cards) — OpenCode-only, isolated from the main entry
├── tools/ # Tool execution handlers for AI agents
│ ├── a2ui.ts # Main `render_ui` tool schema & metadata generator (OpenCode-only: imports opencode/tool/tool)
│ ├── browser.ts # Docker-sandboxed browser automation tool (standalone, no OpenCode dependency)
│ └── weather.ts # Weather card tool handler (OpenCode-only)
└── ui/ # UI component catalog and plugin implementations
├── catalog/ # Standard widgets (bar-chart, line-chart, data-table, etc.) — Solid.js only
├── plugins/ # Library plugins (plotly, mermaid, d3, ag-grid, leaflet, threejs) — Solid.js + the viz lib
├── a2ui-card.tsx # A2UI container card (OpenCode-only: imports @opencode-ai/ui)
├── browser-card.tsx # Embedded browser viewer card (OpenCode-only)
└── weather-card.tsx # Live weather status card (OpenCode-only)
The OpenCode-coupled files (tools/a2ui.ts, tools/weather.ts, ui/*-card.tsx, opencode-plugin.ts) are intentionally not re-exported from the package root — only from their own subpaths — so that importing the root package (or the framework-agnostic renderer/catalog) never requires an OpenCode runtime to be present.
🛠️ Usage
1. Rendering UI in Solid.js
import { RenderGenUI } from "opencode-gen-ui/renderer"
const mySchema = {
type: "widget",
widget: "chart",
engine: "chartjs",
props: {
title: "Monthly Revenue Growth",
type: "line",
labels: ["Jan", "Feb", "Mar", "Apr", "May"],
data: [12000, 19000, 25000, 32000, 48000]
}
}
function App() {
return <RenderGenUI schema={mySchema} height={400} />
}
2. Registering the plugin with OpenCode
import plugin from "opencode-gen-ui/opencode-plugin"
// plugin = { name: "opencode-gen-ui", tools: [A2UITool, BrowserTool, WeatherTool], cards: {...} }
// Wire this into OpenCode's plugin loader. This subpath requires an OpenCode
// runtime — do not import it from a standalone script or server.
3. Using just the schema (works anywhere, including a plain Node script or an MCP server)
import type { WidgetSchema, GenUISchema } from "opencode-gen-ui/schema"
4. Using the standalone browser tool (no OpenCode required)
import { BrowserTool } from "opencode-gen-ui/tools/browser"
// Requires a running "browser-sandbox" Docker container with the
// agent-browser CLI and Chromium installed — see gen-ui/tools/browser.ts.
const result = await BrowserTool.execute({ command: "open", args: ["https://example.com"] })
🎨 Supported Widgets & Components
| Component | Description | Sample Data Keys |
|---|---|---|
gen_ui |
Dialog schema or typed widget | { type: "dialog", dialog: { ... } } |
widget |
Standard iframe chart | { widget: "chart", engine: "chartjs", props: { ... } } |
bar_chart |
Categorical bar chart | { title, labels, values } |
line_chart |
Time-series line chart | { title, labels, values } |
table |
Standard data table | { headers, rows } |
metric_card |
KPI metric highlights | { metrics: [{ label, value, change, trend }] } |
timeline |
Chronological event list | { events: [{ date, title, description }] } |
progress |
Progress bars | { items: [{ label, value, max }] } |
mermaid |
Flowcharts & diagrams | { definition, theme } |
plotly |
Statistical plots | { data, layout } |
d3 |
Custom SVG charts | { type, values, points } |
leaflet |
Interactive maps | { center, zoom, markers } |
threejs |
3D scene objects | { background, objects } |
ag_grid |
Large interactive data grid | { columns, rowData } |
⚠️ The html component renders arbitrary model-provided HTML in a sandbox="allow-scripts" iframe. Sandboxing reduces but does not eliminate risk — do not remove the sandbox attribute, and add a Content-Security-Policy on whatever page hosts that iframe if you serve this over the network.
Known limitations
gen-ui/tools/weather.tshas a broken import: it importseffect/unstable/http, which does not exist ineffect@3.x. This subpath will throw at import time until it's updated to the correct HTTP client API for theeffectversion you depend on (likely@effect/platform'sHttpClient). Left as-is pending a decision on whicheffectecosystem package to standardize on.ui/plugins/leaflet.tsxside-imports Leaflet's CSS, which only a bundler (Vite/webpack/OpenCode's build) can resolve. Importing that subpath — or the root barrel, which re-exports it — in plain Node with no bundler will throw on the CSS import. This is inherent to shipping a Leaflet wrapper; use theopencode-gen-ui/schemasubpath if you need a Node/server-only, DOM-free surface.
📄 License
MIT © Pranav Sai Madala
同类生态推荐
Browser
opencode-browser
OpenCode plugin that integrates Browser MCP for browser automation
Qoder Bridge
opencode-qoder-bridge
Qoder provider plugin for OpenCode powered by the official Qoder Agent SDK, with streaming, tools, MCP, sessions, multimodal input, and quota tracking.
Navigator
opencode-navigator
Search, navigate, and manage OpenCode sessions from the TUI