Upgrading to SDK 1.0
@glasshome/widget-sdk 1.0 is the security release. Widgets now run inside an isolated, permission-scoped sandbox. Most widgets that only use SDK hooks need small, mechanical changes. This page is the migration checklist.
Dash only loads widgets built against SDK 1.x. A widget published against an older SDK shows a “needs update” tile until you republish. Bump your @glasshome/widget-sdk dependency to 1.x, work through this page, then bun widget publish.
What changed
Shadow-root rendering
Each widget renders in its own closed shadow root for style and DOM isolation. Your CSS no longer leaks into Dash or other widgets, and vice versa.
Separate stylesheet
The build emits index.css next to index.js. Dash adopts it into your widget's shadow root. CSS is no longer inlined into the JS bundle.
Capability declarations
Your manifest declares which Home Assistant domains the widget reads or controls. The user approves them at install; the host enforces them.
No direct HA access
Widgets no longer import @glasshome/sync-layer or call fetch/WebSocket directly. All Home Assistant interaction goes through SDK hooks, which are permission-checked.
Migration checklist
1. Bump the SDK dependency
// package.json
"peerDependencies": {
"@glasshome/widget-sdk": "1.0.0"
}
And set the manifest range so Dash knows the widget targets 1.x:
// manifest.json
"sdkVersion": "^1.0.0"
2. Import data and service hooks from the SDK, not sync-layer
Direct @glasshome/sync-layer imports now fail the build with a clear error. The SDK re-exports every hook you used:
- import { useEntity, useService } from "@glasshome/sync-layer/solid";
+ import { useEntity, useService } from "@glasshome/widget-sdk";
This is what makes permissions enforceable: service calls route through the host’s permission check instead of straight to Home Assistant.
3. Declare capabilities
Add a capabilities array to your manifest listing the Home Assistant domains your widget touches, control for ones you operate and read for ones you only display. A widget that never touches Home Assistant declares []. Publishing a 1.x widget without the array is rejected.
// manifest.json
"capabilities": [
{ "domain": "light", "access": "control" },
{ "domain": "sensor", "access": "read" }
]
The full grammar (access levels, narrowing to specific entities or services, what the user approves, and how the host enforces it) is covered in Capabilities & Permissions. Declare the minimum: a widening update has to be re-approved by the user.
4. Don’t fight the shadow root
Your widget now renders in an isolated shadow root with its own CSS bundle. Theme variables still inherit, so don’t redefine them; keep @glasshome/ui as a dependency; and reach Home Assistant through SDK hooks rather than window/document globals. The full styling model is in Styling & Animation.
5. Rebuild and publish
bun run build # emits index.js + index.css + an updated registry
bun widget publish --scope <your-scope>
The publish flow verifies the bundle hash server-side and validates your capability declaration before the version goes live.
Testing locally first
bun widget connect <dash-url> builds and serves your widget to a running Dash, including the capability flow: install it, and you’ll see the same permission prompt your users will. Confirm the widget renders correctly inside its shadow root (styling, theme, dialogs) and that its service calls work before publishing.