User Widgets
Component instances generated by the Agent at runtime, discoverable through the Marketplace.
User Widgets are VizChat's long-tail widget extension mechanism — the Agent generates component instances in a conversation, stores them in the database as username/slug@version rows, and other users can browse them in the Marketplace and pull them into their own canvases through chat. No release cycle required.
What is a Widget
- A data contract (its snapshot schema, defaults and operations) plus a view: either a React component rendered in the canvas (inline mount, the default) or plain DOM code that runs in its own iframe (nested mount). The backend compiles both into a bundle
- Generated by the Agent from a conversational request (or authored by developers and published)
- Uniquely identified by the
username/slug@versiontriple - Enriched with tags, description, thumbnail, favorite count, and a trending score
User Widget vs built-in widgets
| Dimension | Built-in (BUILTIN) | User Widget (USER) |
|---|---|---|
| Storage | Marketplace listing row + bundle in object storage, loaded at runtime | Same — listing row + bundle in object storage |
| Publishing | Source lives in the repo; the VizChat team publishes it through the same publishing pipeline | Any user can publish from the widget editor |
| Scale | ~ten types | Target thousands |
| State access | Depends on mount, not on Built-in vs. User: inline (the default) runs in the canvas's own component tree and can read/write canvas state; nested runs in an isolated iframe | Same — depends on mount |
| Best for | Common, stable, deep canvas integration | Long-tail, one-off, personalized |
How to use
1. Browse the Marketplace
Click the globe icon in the top bar to open /marketplace — it is public, so you can browse it without signing in. Sort by Popular / Trending / Newest, or search by keyword. A widget's detail page runs a live demo, lets you try the widget on a scratch canvas (select it, resize it, edit its data and settings — changes live only on that page; reset or refresh to start over), shows its docs, and lets signed-in users favorite it; open-sourced widgets also let you download the source package or fork it into your own draft (see below).
2. Pull a widget into the canvas from chat
Type @widget: in the chat input to pick from Marketplace, favorited, and recently used widgets, or write the reference by hand as @widget:<author>/<slug> (optionally @widget:<author>/<slug>@<version>). The Agent then places that widget on the canvas. Simply asking the Agent to add a widget works too.
3. Ask the Agent to generate one
In chat:
"Make me a dice-rolling widget" "Build a 10-minute countdown widget"
The Agent builds the widget directly into the canvas — it doesn't go to the marketplace unless you publish it later.
4. My widgets
When signed in, click the VizChat logo in the top bar to reach your home page /me. Its Creations and Favorites sections list the widgets you've published and the ones you've favorited; each has its own full page at /me/creations and /me/favorites.
If something you favorited was deleted by its author, the card is marked Deleted by author and stops linking anywhere; if it was taken down, it's marked Taken down (takedowns can be reversed, so it stays). Either can be removed individually via the ✕ in the card's top-right corner, and the favorites page has a one-click cleanup that clears only the deleted ones.
Building on an official widget
Most official widgets are open source under Apache-2.0 (Math Coordinate is the exception). Whether a widget's source is public is decided per version: the detail pages of widgets whose latest version is open (marked with a green Open source badge next to the title) offer two ways in:
Download source — you get a <slug>-source.zip. Unzipped, it is a complete widget package (package.json, src/, tests, LICENSE, NOTICE). Run pnpm install and develop it locally with the CLI.
Import to my widgets — the server copies the source into a draft under your account and opens the widget editor. Edit, then publish. The package name is rewritten to @<your-username>/<slug> for you.
Both routes give you the same source; the only difference is where you want to edit it — local toolchain, or the in-browser editor.
An import is an independent copy with no link back to the original: changing it does not affect the official widget, and official updates do not flow into your copy. If you already own a widget with that slug, the import is refused rather than overwriting it — rename or delete the existing one in My creations, then retry.
Licensing
Apache-2.0 lets you use, modify, and redistribute the code freely, including commercially, provided you keep the LICENSE and NOTICE files that ship with the package. Both travel with downloads and imports — please don't delete them.
The NOTICE in rich-text carries an additional MIT notice: it embeds styles from Milkdown, and that notice must be preserved too.
Apache-2.0 covers the widget's own source. The @vizchat/* packages it depends on (SDK, UI, build tooling) carry their own license: free to use for developing, building, distributing, and even selling widgets, but you may not redistribute those packages themselves. See the LICENSE inside each package.
Going back to an earlier version of a widget draft
History in the widget editor's toolbar lists the snapshots of the widget's draft, newest first. Snapshots are taken automatically:
- Before an AI turn: each time the agent starts changing the widget, with the last thing it said in that turn;
- Before your edits: before you save in the editor (or sync from a local folder); saves within half a minute count as one;
- Published: every version you publish, with its version number;
- Before a restore: before every restore.
Select a snapshot to see which files restoring it would change (brought back, removed, or reverted); changed text files expand into a line-by-line diff. After you confirm Restore this version, the draft goes back to how it was at that moment and the preview recompiles. The draft as it was before the restore is kept as a "Before a restore" snapshot, so Undo on the confirmation message, or that snapshot in the history, brings it back. Unsaved edits in the editor are lost.
You can also just tell the agent "that broke it, go back to the previous version" — it reads the same history. Each widget keeps its 50 most recent snapshots, plus every published version. A draft with unmerged local changes can't be restored; handle those first, as described in the next section.
Editing your widgets in a local folder
In the desktop app, each widget row in My creations has Sync to a local folder: the widget's draft appears in a folder you choose, and edits made there in any editor sync back. Widgets that are already connected show Show in folder instead. The web app doesn't have this option.
If the Agent or the widget editor on the web changes the widget while you are editing it locally, neither side overwrites the other: the cloud version stays in the draft, your local edits are set aside as local changes to merge, and your local folder switches to the cloud version. Files you added locally, and binary files (images, fonts, and so on) changed only locally, don't need merging and go straight into the draft.
While there are changes to merge, the widget's row in My creations and the top of the widget editor say so and offer two ways forward:
- Merge with Agent opens the widget editor and sends a merge request to the Agent for you. The merge only counts once the Agent has combined both sides and the widget compiles. The next time you ask the Agent to change this widget, it also merges first and then does what you asked.
- Discard these changes lists the files involved; once you confirm, those local edits are no longer merged and the widget keeps what is in the cloud now.
A widget with changes to merge can't be published: the publish dialog explains why and offers the same two options. Handle them, then publish.
Publishing your own widget
Widget publishing shares the authoring workflow with custom widget development. See the Custom widget developer guide.
Publishing checks the version it is about to release: the default view and every demo page are rendered in both languages. Errors while rendering, a page that never finishes loading, a failing operation, an untranslated key showing on screen, or reaching outside the widget (into the host page, or to a source it didn't declare) stop a Marketplace publish, with each problem listed. A widget you've withdrawn from the Marketplace is checked the same way but never blocked. Softer observations (contrast, performance, accessibility) never stop publishing; they are listed alongside the result.
Trying an unpublished widget in your own board
You can use a widget you haven't published yet in your own storyboards and dashboards — ask the Agent to add it. Only you see it there, and it shows the widget's latest successful preview build; if the widget has never been previewed, the board shows a placeholder with Open preview. Before you can publish or export that board, publish the widget: the board then switches to the published version automatically.
After publishing: runtime dependencies and maintenance
A widget is built with the latest versions of the platform runtime at that moment (the SDK, shared UI, and dependencies such as d3, echarts and three), and the build stays pinned to them, so other people's boards don't change when the platform upgrades. After a while an old runtime version enters a deprecation period (90 days) and is then frozen: frozen versions still load, but new builds no longer use them.
On your widget's detail page (only you see this part), or under Runtime & maintenance in My creations, you can see each published version:
- Deprecation notices, such as "The @vizchat/widget-sdk 0.3.2 dependency will be frozen on …". Rebuild builds that version again with the latest runtime. The source and version number stay the same, so boards that use it aren't affected. A rebuild takes a few minutes; you get the result as a notification.
- Switch back: for 7 days after a rebuild you can switch back to the previous build.
- Withdrawn versions: when the platform finds a problem in a runtime version it withdraws it. Widgets built with it still load; rebuild to move to the fixed version.
- Platform maintenance: when a dependency enters its deprecation period, the platform tries building your widget with the latest runtime. If that works, the new build goes live and you're notified (you can switch back); if not, the reason is listed under Platform maintenance. Fix it yourself, or choose Ask the agent to fix it, which you pay for. If you still haven't handled it when the dependency is frozen, the platform takes over.
- Old dependencies bundled: one way the platform keeps a widget running is to bundle the old runtime into the widget itself. It keeps working but gets bigger. You can rebuild at any time to move back to the latest runtime.
If you no longer want to maintain a widget, you can transfer it to the platform in the same place. This can't be undone: VizChat maintains it from then on, you can't publish new versions, and its pages say "Maintained by VizChat" instead of your name. The page address and references to it in boards still contain your username.
Tier limits
Widget development is identical across all tiers — see Billing rules and plan limits. BYOK significantly reduces widget iteration cost; see the pricing page for details.
Next step
- Custom widget development — developer-facing widget authoring
- Custom widget guide