Getting Started
A widget is a SolidJS component + a Zod config schema, wrapped with defineWidget. The dashboard renders the component, auto-generates the settings form from the schema, and feeds in entity state.
Scaffold
`bunx @glasshome/widget-cli@latest` (no args). Creates a project and your first widget.
Hot-reload
`bun widget connect <dashboard-url>` rebuilds on save and re-uploads to a running dashboard.
Publish
`bun widget publish` to Hub. Pick personal or organization scope.
Inside a scaffolded project, bun widget <cmd> works (the CLI is pinned in devDependencies, with a widget script alias to glasshome-widget); elsewhere use bunx @glasshome/widget-cli@latest <cmd>. Full command list: Widget CLI.
Prerequisites
| Tool | Version | Notes |
|---|---|---|
| Bun | 1.0+ | CLI engines field requires bun >=1.0.0 |
| Node.js | 18+ | Required by @glasshome/widget-sdk (engines.node >= 18); Bun’s bundled Node compatibility layer satisfies this |
Scaffolded projects ship a .mise.toml pinning the versions. Install mise and run mise install.
Quickstart
- 1
Scaffold a project
bunx @glasshome/widget-cli@latest cd <project-name>Generates
package.json,vite.config.ts,tsconfig.json, thewidgetscript alias, and your first widget (prompts for name + description). - 2
(Optional) add more widgets
bun widget addPrompts for name and description, creates
src/<name>/index.tsxandsrc/<name>/manifest.json. - 3
Connect to a running Dash instance
bun widget connect http://homeassistant.local:3123Builds, runs an OAuth device-code flow against your local Dash instance (not Hub), uploads each bundle to the Dash API under the
localscope, enables dev mode, then watchessrc/, re-uploading on save; widgets refresh without a page reload. - 4
Publish
bun widget publishpublishrunsloginautomatically the first time. See Publishing.
Project layout
my-widgets/
├── package.json
├── vite.config.ts
├── tsconfig.json
└── src/
├── my-widget/
│ ├── index.tsx # Component + defineWidget
│ └── manifest.json # Widget metadata
└── another-widget/
├── index.tsx
└── manifest.json
One widget per directory under src/. Build outputs one self-contained JS bundle per widget plus a registry.json in dist/.
Mental model
- The dashboard handles rendering, gestures, theming, entity subscriptions, settings forms, and layout. Your widget supplies how the bound entities are visualized and what the primary tap does.
- No settings UI to write: define a Zod schema; the dashboard renders the form.
- No WebSocket state to manage:
useEntity/useEntitiesread the entity ids the user picked in config and stay reactive;useWidgetEntityGroupaggregates them and supplies an empty state. - No Home Assistant connection or token to hold: all reads and service calls go through SDK hooks, checked against your declared capabilities.
Versions at a glance
| Version type | Where it lives | Who bumps it | What breaks without it |
|---|---|---|---|
SDK version (sdkVersion) |
manifest.json, as a semver range (e.g. ^1.0.0) |
bun widget upgrade (bumps the dep and rewrites the range) |
Dash may refuse to load bundles built against a wildly different SDK |
Widget version (version) |
manifest.json |
--bump flag on bun widget publish |
Re-publishing the same version is rejected (409) |
Config version (configVersion) |
manifest.json, integer |
You, when config shape has breaking changes | Without a bump, users’ saved configs aren’t migrated and may fail Zod parse |
| CLI minimum (Hub-enforced) | Served by Hub at /api/widgets/cli-version |
Hub (I bump it on protocol changes) | login/publish hard-stop if CLI is below the floor |
Auth flows: connect vs. login
Both flows open a browser, but they authenticate against different hosts, and the resulting tokens are stored separately, never interchangeable:
Where to go next
Widget SDK guide
defineWidget, Widget components, hooks, the HA data layer, entity helpers.
API Reference
Every public export across the SDK, /schemas, and /vite entry points.
Capabilities & Permissions
Declare the Home Assistant access your widget needs and how the user approves it.
Styling & Animation
Per-widget CSS bundles, Tailwind, your own CSS files, theme variables, container queries, animation.
CLI reference
Every `bun widget <command>` and what it does.
Publishing
Auth, scopes, versioning, trust badges.
Config migrations
Handle breaking config changes without breaking users.