Publish a widget from the command line
Log in with the VizChat CLI, preview your widget locally with narrated demos, and publish it to the Marketplace — all from your terminal.
If you develop a widget locally — in your own editor, with your own tooling — the vizchat-widget CLI takes it from a folder on your machine to a published Marketplace entry. This guide covers the four commands you need: auth login, dev, tts, and publish.
Prerequisites: Node.js and a package manager. That's it — the next step creates the project.
Create the project
npm create vizchat-widget my-widgetIt asks for the mount form (inline for a React component in the host tree, nested for a self-contained page in an iframe), writes a complete package — schema, view, demo storyboard, i18n, tests — and prints the install command for whichever package manager you used. Pass --yes to take the defaults, or --mount inline --scope <your-username> to skip the questions.
pnpm create vizchat-widget and npx create-vizchat-widget@latest do the same thing.
Already have a widget package? Then you only need @vizchat/widget-scripts in its dev dependencies, and a name of the form @<your-username>/<widget-slug>.
cd my-widget && pnpm installThe CLI is available inside the project as pnpm exec vizchat-widget.
Log in
pnpm exec vizchat-widget auth loginThe CLI prints a short code and a browser link. Open the link, confirm the code matches, and approve — the terminal picks up the credential automatically. The token is stored in ~/.config/vizchat/credentials.json, scoped to the server it was issued for, and stays valid as long as you use it at least once every 90 days.
auth whoami shows who you're logged in as; auth logout revokes the token on the server and deletes it locally. You can also revoke CLI tokens any time from Settings in the web app.
Preview locally
pnpm exec vizchat-widget devThis starts a local preview server and watches your source. The Demo tab plays your demo.stb storyboard; the Interact tab mounts the widget in a live dashboard where you can click and edit it. Source changes recompile and reload automatically.
Inside VS Code
If you work in VS Code, the VizChat Widget Preview extension (vizchat.vizchat-vscode-extension) saves you the trip to a browser: open any file in your widget package, run VizChat: Open Widget Preview from the Command Palette, and the preview opens in a panel beside your editor. The extension starts the same dev server for you and shuts it down when you close the panel.
It is a shortcut, not a different product — the panel embeds the very page dev serves, so a browser pointed at the same address shows exactly the same thing. Nothing here is VS Code-only.
Add narration audio
Your demo storyboard's markedText narration can be synthesized into audio that plays in the local preview and ships with the published widget:
pnpm exec vizchat-widget ttsSynthesis is billed to your account's credits, and only pages whose text changed are synthesized — re-running is free when nothing changed. The audio lands in public/demo-tts/ (git-ignored; it travels with the package upload instead). The preview also offers a one-click synthesize bar when pages are missing audio.
Publish
pnpm exec vizchat-widget publishThe CLI builds locally first (so obvious errors never leave your machine), uploads the package, and asks the server to compile, validate, and publish it. The server is the authority: it rebuilds from source and bakes your demo audio into the published version — reusing what you already synthesized locally, at no extra cost. If you pass --open-source, it also scans the source for accidentally committed secrets before publishing it (see Secret scanning below).
Publishing makes it public
A published widget is immediately visible on the Marketplace — there is no separate "list it" step. The one thing left for you to decide is whether to publish the source code alongside it:
pnpm exec vizchat-widget publish # publish; source stays closed
pnpm exec vizchat-widget publish --open-source # publish and open the source--open-source is orthogonal to publishing: it controls whether others can read your source, not whether the widget itself is visible.
Opening the source cannot be undone — you cannot un-see what has been seen. So do a dry run first:
pnpm exec vizchat-widget publish --dry-runA dry run builds locally, prints the exact list of files that would be uploaded, and stops. The server receives no writes.
To remove a widget from the Marketplace later, use "Take down" on the web — that one is reversible, and independent of whether the source is open.
Secret scanning
When you pass --open-source, the server scans for likely secrets before publishing the source. If a finding is intentional (a demo API key placeholder, say), re-run with --acknowledge-secrets once you have reviewed it:
pnpm exec vizchat-widget publish --open-source --acknowledge-secretsOn an unacknowledged finding the version has still been published — only the "open the source" step stops and waits for you. There is no need to cut another version.
Using it in scripts and CI
Every command writes exactly one line of JSON as the last line of stdout; progress and messages go to stderr, so | tail -1 | jq just works. Exit codes are fine-grained so you can branch on them:
| Code | Meaning | What to do |
|---|---|---|
0 | Success | Continue |
2 | Usage / argument error | Fix the command |
3 | Not logged in, or credential expired | Run auth login |
4 | Local validation / build / test failure | Fix the code |
5 | Needs informed confirmation | Re-run with --acknowledge-secrets or --yes |
6 | Remote / network error | Retryable |
Commands that spend credits or have irreversible side effects do not proceed silently in a non-interactive shell: tts requires an explicit --yes (or use --dry-run to see the quote only).
Troubleshooting
- "Not logged in" right after logging in — the credential is scoped per server. If you logged in against a non-default server via
VIZCHAT_API_URL, every command (includingdev) needs the same variable set. - Preview says pages are missing audio but you already synthesized —
public/isn't watched, so the audio index is only refreshed on a rebuild. Touch a source file or restartdevto trigger one. publishrejects the author name — the scope in yourpackage.jsonnamemust match your VizChat username exactly.