ZOYKUHot Board

robertg761/ha-desktop-widgetДокументация

Free, open-source Home Assistant desktop app and widget for Windows, macOS, and Linux. Control devices, view sensors, and pin entities to your desktop.

Языковое уведомление:Перевод на данный язык отсутствует. Отображается официальный английский оригинал.
npm i ha-desktop-widget

HA Desktop Widget

A free, open-source Home Assistant desktop app and frosted-glass widget for Windows, macOS, and Linux. Control devices, view sensors, and pin entities to your desktop.

CI Release License: MIT DownloadsCommit Archive 2026

GitHub Sponsors

Main view Edit view Light adjust

Settings

Appearance settings

Settings are organized into six pages on the left: General (Home Assistant connection, window behavior, language), Appearance (light or dark theme, colors, window effects, readability), Dashboard (primary cards, date and time formats, weather source, media tile, custom entity icons), Hotkeys, Alerts, and Advanced (updates, profile sync, diagnostics).

Use Search settings at the top of Settings to find an option by its name or help text. Choose a result to open its page and any collapsed section. Press Escape in the search field to clear the search.

In Appearance → Readability, choose Text and control size (100%, 115%, 130%, or 150%) to enlarge the interface, dialogs, and desktop pins. Enable High contrast with opaque panels for a dark, solid background and brighter text and borders. These preferences save immediately. Desktop pins grow with it, so a pin keeps showing all of its controls.

Light, climate, fan, cover, and media tiles include a Controls button (the sliders icon in the tile corner) to open their detailed controls. Keyboard users can also focus a tile and press Shift+Enter.

Omarchy and Arch Linux

See the Omarchy guide for native desktop layers, independent desktop pins, the Omarchy 4 bar plugin, Hyprland shortcut setup, live theme following, and Arch packaging. Build a local pacman package with npm run dist:arch followed by makepkg --nodeps in dist/arch.

Sway, niri and river

On Sway, niri and river the widget sits on the desktop under your windows, as it does on Hyprland. To bring it forward, bind a key to its --toggle command, which shows or hides it. Settings → Hotkeys shows the command for your installation: ha-desktop-widget for the Arch package, home-assistant-widget for the .deb, and ~/.local/bin/ha-desktop-widget for the AppImage. With the .deb:

  • Sway: bindsym $mod+Shift+h exec home-assistant-widget --toggle
  • niri: Mod+Shift+H { spawn "home-assistant-widget" "--toggle"; }
  • river: riverctl map normal Super+Shift H spawn 'home-assistant-widget --toggle'

The AppImage's file name includes its version. An update saves the new version under a new name and deletes the old file, so a key bound to the file itself stops working after the first update. Bind the link instead. Each time the AppImage starts, the widget points ~/.local/bin/ha-desktop-widget at it. niri does not expand ~, so give it the full path that Settings shows. The Copy button under it copies the command. With the AppImage:

  • Sway: bindsym $mod+Shift+h exec ~/.local/bin/ha-desktop-widget --toggle
  • niri: Mod+Shift+H { spawn "/home/you/.local/bin/ha-desktop-widget" "--toggle"; }
  • river: riverctl map normal Super+Shift H spawn '~/.local/bin/ha-desktop-widget --toggle'

The widget only moves its own link: the one it made, or one that already led to the AppImage when the widget had no link of its own. It leaves that name alone if something else already has it, such as a file or a link of yours there (even one to another AppImage) or the Arch package's ha-desktop-widget. Settings then names the AppImage file itself. To keep that working across updates, rename the file to a name with no version number and no spaces, such as ~/Applications/ha-desktop-widget.AppImage. Updates then replace it under the same name.

Weather Effects

Rain effect Snow effect

Features

Smart Home Control

  • Real-time Updates: WebSocket connection for instant entity state changes
  • Quick Access Dashboard: Customizable grid of your most-used entities
  • Duplicate Pages: In reorganize mode, use Duplicate page beside the active page name. The copy opens beside the original with the same tile order and its own copies of comparison charts. Device names and tile preferences remain shared for the same Home Assistant entity.
  • Entity Management: Add, remove, rename, and reorder entities with drag-and-drop
  • Desktop Pins: Pin selected Quick Access entities as movable, resizable desktop tiles
  • Custom Names & Icons: Rename entities and override entity icons without changing Home Assistant
  • Tile Options: Adjust selected Quick Access readout sizing for dense or prominent tiles
  • Camera Tile Previews: Opt into a visibility-scoped authenticated HLS stream or snapshots, then click the tile to grow that same feed into a larger view and reconnect a stale camera session when needed
  • Interactive Controls: Toggle lights, switches, scenes, and more with a single click

Modern Interface

  • Frosted-glass Design: One pane of frosted glass with clear, separate tiles; a solid panel where the system cannot blur
  • Responsive Layout: Auto-sizing tiles that adapt to content
  • Themes: Auto, Dark or Light (Auto follows the system)
  • Color Personalization: Built-in and custom accent/background colors with live preview
  • Weather Effects: Optional subtle rain, snow, clouds, sun, and storm animations when frosted glass is enabled
  • Smooth Animations: Fluid drag-and-drop and hover effects
  • Toast Notifications: Real-time feedback for all actions

Entity Support

  • Lights: Toggle on/off, brightness control, and desktop-pin brightness presets
  • Switches, Fans & Input Booleans: Simple on/off controls, with fan speed controls where available
  • Covers & Locks: Open/close and lock/unlock controls
  • Sensors & Binary Sensors: Real-time value display with units and state-aware icons
  • Timers: Live countdown displays for active timers
  • Cameras: Optional Quick Access snapshots plus live feed viewing with snapshot fallback
  • Climate: Temperature display and control
  • Media Players: Play/pause, previous/next, artwork, seek bar, and 10-second rewind/fast-forward where supported
  • Scenes, Scripts & Buttons: One-click scene activation, script running, and button/input-button pressing
  • Automations: Trigger, toggle, enable, or disable from configured hotkeys

Advanced Features

  • Updates: Windows installer and Linux AppImage builds download and install updates themselves; portable, macOS, and Linux deb builds are told once per new version and open the GitHub Releases download
  • System Tray: Hide to tray with quick access menu
  • Tray Entity Icons (Beta only): Show any entity's live value (battery %, temperature, ON/OFF, timer countdown, …) as its own icon in the system tray, CPU-Z style
  • Start at Login: Optional OS login startup control
  • Configuration: Native Home Assistant browser authorization; legacy access-token setup remains available as an advanced fallback
  • Performance: Optimized rendering and memory management
  • Cross-Platform: Windows x64, universal macOS (Intel and Apple Silicon), and Linux x64 support with transparency effects where available
  • Appearance: Auto, dark or light theme, accent/background themes, custom colors, window opacity, frosted glass, weather effects, custom icons, and desktop pins
  • Line icons: Entities are drawn with crisp line icons that take the accent color when on; your own emoji and Home Assistant icons still win
  • Localization: Auto/system language mode with downloadable offline language packs
  • Hotkeys: Global entity hotkeys and popup hotkey to bring the window to front
  • Alerts: Desktop notifications for entity state changes
  • Primary Cards: Configure the top two cards (weather/time or any entity)
  • Comparison Graphs: Plot several entities on one 24-hour chart to compare them at a glance (e.g. every room temperature against the outside temperature)
  • Per-Tile Charts: Give each numeric sensor tile a line chart, a gauge with an automatic or custom range, or no chart at all
  • Media Tile: Choose a primary media player or hide the tile
  • Profile Sync (Opt-in): Keep Quick Access, appearance, alerts, and weather and media choices the same on every computer through a folder you already sync (see Profile sync)

Export and import settings

Open Settings → Advanced → Settings files to export your saved pages, appearance, alerts, weather and media choices to a JSON file. Connection details and credentials, desktop pins, hotkeys, tray preferences, text size, Omarchy theme following, startup, updates, and profile sync settings stay on each computer.

Import shows the sections that will change, page names, and how many referenced devices are missing from the current Home Assistant connection. Confirming applies the file immediately and replaces unsaved Settings edits. Imported entity IDs still refer to the original Home Assistant devices; importing does not create devices or automations.

The widget saves a backup before applying an import. Restore it under Advanced → Settings files → Backups, even with profile sync disabled. Imports and restores follow your existing sync scope when sync is enabled. Settings files use a versioned format and have a 1 MB limit.

Live tray values (beta only)

Live tray values are available only in beta builds. Stable builds retain saved tray preferences without showing the feature. Enable Receive beta updates in Settings to receive beta releases.

Right-click a Quick Access tile and choose Show in Tray, or enable Show in system tray under Edit tile settings. Each selected entity gets its own tray icon or macOS menu-bar value. Hover for its name and full value; use its menu to show the widget or remove the icon.

Tile settings also provides an optional short name. On macOS it appears before the value in the menu bar, with units and decimal precision retained. On Windows and Linux it appears in tooltips and menus; an optional icon color helps distinguish multiple readings at a glance.

An offline connection displays -- in bitmap trays or a translated Offline label on macOS. Values return after a fresh Home Assistant snapshot. An unavailable entity uses !, and an unknown state uses ?, with the full explanation in the tooltip. Warning colors take precedence over custom icon colors. A renderer failure or reload clears the last value to a placeholder.

Active timers refresh each second even when the widget is hidden. The dashboard retains its normal background behavior, including pausing hidden camera previews. On Windows and Linux, activating a tray value toggles the widget; on macOS, clicking opens its menu.

Roadmap

Planned for a future release:

  • HA Assist voice: A microphone button wired to Home Assistant's Assist pipeline (speech-to-text → intent → text-to-speech) so you can talk to your smart home from the desktop. Deferred as a standalone update because it needs the full HA server-side audio pipeline and real device testing.

Quick Start

Download & Install

  1. Go to the Releases page and download the latest available build for your OS.
  2. Windows: run the .exe installer or portable build. macOS: open the universal .dmg or .zip (older releases may be Apple Silicon-only). Linux: use the .AppImage or install the .deb package.
  3. Open the app and follow its setup to connect Home Assistant (see First-Time Setup).

macOS Gatekeeper notice: Current macOS artifacts are universal, but they are temporarily not Apple Developer-ID signed or notarized. macOS may block the first launch because it cannot verify the developer. For a copy downloaded from this project's official GitHub Releases page, Control-click the app and choose Open; if needed, go to System Settings > Privacy & Security and choose Open Anyway. The package's ad-hoc integrity signature is not a substitute for Developer-ID signing. Do not bypass Gatekeeper for copies obtained elsewhere.

Linux keyring: The widget remembers your Home Assistant sign-in and sync passphrase in the system keyring (a Secret Service such as GNOME Keyring or KWallet). Minimal desktops (i3, Sway, XFCE) may not run one, and then nothing is remembered after you quit. Install and start gnome-keyring, or another Secret Service, and restart the widget. The .deb recommends gnome-keyring, and the Arch package lists it as optional.

AppImage on Ubuntu 23.10 and later: These releases block the sandbox the AppImage needs, so a double-clicked AppImage closes without opening a window. Install the .deb instead, or start the AppImage once from a terminal with --no-sandbox. See Running the AppImage on systems that block the Chromium sandbox.

First-Time Setup

  1. Get your Home Assistant URL: Use the exact address you normally open in your browser, such as http://homeassistant.local, a legacy http://your-ha-ip:8123 address, or https://your-ha-domain.com
  2. Connect the widget: Enter that URL and click Connect. The app opens Home Assistant in your system browser so you can sign in and approve it; your Home Assistant password never enters the desktop app.
  3. Return to the widget: Authorization finishes through a temporary loopback callback on this computer and live updates start automatically. If you change your mind, Cancel next to the connect button stops waiting and closes the loopback callback.
  4. Add entities: Choose a room to start from, or click the "+" button to add your favorite entities to Quick Access.

The legacy long-lived access-token form remains under Settings > General > Legacy access token (advanced) for compatibility. New setups should use browser authorization.

Home Assistant Companion Integration

The optional HA Desktop Widget Companion custom integration makes registered desktops visible as native Home Assistant devices and supports show, hide, toggle, switch_page, and apply_profile actions. The desktop uses the same authenticated Home Assistant WebSocket connection for registration, state reporting, command delivery, and acknowledgements. It never accepts arbitrary shell commands, JavaScript, file access, URLs, or generic Electron IPC from Home Assistant.

apply_profile applies a named profile authored in Home Assistant: a bounded configuration document covering appearance (theme, accent, background, opacity, frosted glass), primary cards, Quick Access pages and tiles, comparison graphs, custom icons, and tile options. Profiles never carry credentials, hotkeys, window geometry, desktop pins, or file-sync settings; those stay local to each machine. The desktop reports which profile revision it last applied so Home Assistant can flag out-of-date desktops.

Note

A Home Assistant profile overwrites the sections it contains. If profile sync is also on for the same sections, the applied profile counts as a local change and syncs to your other computers — avoid managing the same settings with both at once.

How to Use

On Windows, macOS, and Linux X11, choose the widget's display in Settings > General > Window & behavior > Display, or use Move to Monitor in the tray menu. The choice stays on this computer. If the display disconnects, the widget moves to an available display and returns when the selected one reconnects. Dragging onto another connected display updates the selection. Automatic remembers the last window position without choosing a preferred display. Individual desktop pins keep their own positions. Linux desktop-layer mode continues to use its tray monitor menu.

Quick Access Management

  • Start with a useful dashboard: After browser authorization, choose Choose rooms and entities or Skip for now. The same action is available from an empty Quick Access dashboard. A populated room is suggested with up to eight available everyday controls selected; review the preview, search and adjust the entities, name the page, and choose Add Page. Beside other pages, an empty page offers Fill this page instead and keeps its name. Either way, pages that already hold entities are never replaced. If room registry access is unavailable, choose directly from your entities; the list shows the first 100 matches, so type to narrow it. The picker waits for the connection to finish starting; use Retry if it cannot connect.
  • Build a page from a room: Enter reorganize mode and choose Add page. Rooms load automatically when connected; use Load rooms or Retry if needed. Select a Home Assistant area, choose its entities, review the preview, and save. Entity area overrides take precedence over device areas; hidden and disabled registry entries are omitted. Registry access requires permission from Home Assistant.
  • Undo and restore: The undo arrow reverses the latest dashboard edit, one edit at a time. Settings > Advanced > Restore dashboard lists up to 20 local restore points, retained across restarts and separated by Home Assistant server. Edits less than 30 seconds apart share one restore point, so a run of small changes does not push older layouts out of the list. The layout from before them is kept when the first edit is saved, and the layout they leave once the dashboard has been idle for 30 seconds or the app closes. The dialog leaves out a restore point that matches the layout already on screen, since restoring it would change nothing. Restoring a saved layout, an undo, or a profile applied from Home Assistant always keeps the layout it replaced as a restore point. These backups contain dashboard data, including names, icons, tile options, and comparison graphs, but exclude authorization, desktop pins, hotkeys, and connection settings. They depend on local browser storage being available.
  • Add Entities: Click the "+" button to search and add entities to your dashboard
  • Reorder: Click the Reorganize button to enter reorganize mode, then drag and drop to reorder. Without dragging, select a tile and then the tile whose place it should take, or press Alt and an arrow key on a tile's buttons to move it
  • Rename: In reorganize mode, click the edit icon to set custom display names
  • Camera Previews: Edit a camera tile to choose an HLS live feed or a 30-second, 10-second, or 5-second snapshot cadence; previews pause while the app or tile is hidden, clicking expands the current feed without restarting it, and the expanded live view includes a Reconnect action for stale sessions
  • Remove: In reorganize mode, click the remove button to remove entities
  • Pin to Desktop: In reorganize mode or the tile context menu, pin supported Quick Access entities as standalone desktop tiles
  • Show in Tray: From the tile context menu or the pencil settings, put an entity's value in the system tray as its own icon (Windows and Linux draw a compact value icon; macOS shows the value as menu-bar text)
  • Chart Type: In a numeric sensor tile's pencil settings, pick a line chart, a gauge, or no chart. Gauge ranges come from the sensor's unit, min/max attributes, device class, or recent history, and can be overridden

Comparison Graphs

  • Create: Click the "+" button, then Add comparison graph
  • Pick entities: Add up to 7 numeric sensors. Weather and climate entities can be graphed too — a weather entity contributes the outside temperature (search "outside" to find it, even though it is usually named after the integration, e.g. "Forecast Home")
  • Read it: Series share one time axis and one value scale, so the curves are directly comparable. Hover anywhere to get a crosshair and a readout of every series at that moment
  • Units: Entities sharing a unit share a scale. Adding a different unit (e.g. humidity next to temperature) warns and scales it separately
  • Width: Choose 2, 3 or 4 tiles wide in the graph's editor
  • Edit / remove: In reorganize mode, click the edit icon on the graph tile (or the remove button)

Press Ctrl+K or Cmd+K to search entities and actions. Choose an explicit action to turn supported lights, switches, fans, or input booleans on or off, run a scene or script, or switch pages. An entity result opens its controls when it has any. A result with none, for an entity that has an action of its own in the list (a switch, an input boolean, a scene), only says what it is now and changes nothing, so a stray Enter never switches it; a button, an automation or a timer, which has no action there, still runs its own. Successful commands appear first when opening an empty search during the current session. Unavailable entities do not offer actions, and failed commands show an error.

Alert conditions

In Settings > Alerts, configure a state change, exact state, or numeric threshold. Optional duration and cooldown fields use seconds. A duration requires the condition to remain true continuously while the app observes it; disconnecting cancels pending alerts, except the wait before an unavailable notification, which starts over when the app reconnects and the entity is still offline. Quiet hours use the computer's local time and can cross midnight. Matching updates do not repeat an alert until the condition clears and is reached again. Alerts suppressed by quiet hours or cooldown are not queued for later delivery. The app must be running and connected.

A state change alert also tells you when the entity goes unavailable or unknown, but only if it stays that way for 30 seconds, and at most once every 15 minutes per entity, so a flapping device does not flood you. An outage that begins inside those 15 minutes is not reported later, even if it lasts. Saving the rule starts a pending wait over, but does not reset the 15 minutes. The rule's own duration, cooldown and quiet hours apply as well. Coming back is not announced unless the entity returns as something other than it was before the outage. Turn off Notify when unavailable or unknown on the rule to skip these. To be told about every outage, use an exact-state alert for unavailable or unknown, which follows only its own duration and cooldown.

Sensor history

Click a numeric sensor tile to open its larger chart. Select 1 hour, 6 hours, 24 hours, or 7 days and use Refresh to fetch new readings. Minimum, maximum, and sample average describe the recorded numeric values. The average is not time-weighted. History availability depends on Home Assistant's recorder and retention settings; an empty period and a failed request have separate messages.

Connection diagnostics

Open Settings > General > Connection diagnostics to inspect connection attempts, the last successful connection, the last received state update, and a generic issue code. Copy report copies an allowlisted report without server URLs, credentials, entity names, readings, or raw error messages. These counters cover the current app session.

Entity Interactions

  • Lights: Click to toggle, long-press for brightness slider
  • Fans: Click to toggle, long-press for speed controls
  • Covers: Click to open/close, long-press for open/stop/close controls
  • Climate: Long-press for target temperature and mode controls
  • Media Players: Use the media tile controls or long-press a media player for details and seek controls
  • Cameras: Click to open the camera viewer (snapshot, with a Live button)
  • Sensors: Display real-time values with automatic unit formatting
  • Timers: Show live countdown when active
  • Scenes, Scripts & Buttons: Click to activate, run, or press instantly

Use Tab to focus a primary card or the Quick Access grid. Arrow keys move between Quick Access tiles; Enter or Space activates the focused device. Shift+Enter opens its available detail controls. With several pages, Tab reaches the page tabs once: Left and Right (or Home and End) move along them and switch page. The tabs scroll to keep the active page in view, and the mouse wheel scrolls them. Heat/cool thermostats provide separate heating and cooling targets, and on/off-only lights show power controls without a brightness slider.

System Integration

  • Hide to Tray: The minimize button, the title-bar X, Ctrl+W (Cmd+W on macOS) and Alt+F4 all hide the widget to the system tray, and it keeps running. Choose Quit from the tray menu (or the app menu on macOS) to exit
  • Hide on Focus Loss: Enable “Hide to tray when focus is lost” (“Hide to menu bar when focus is lost” on macOS) under General → Window & behavior to dismiss the widget when switching apps. This is off by default. Reopen it from the tray or with the popup hotkey. Desktop pins and Linux desktop-layer mode stay visible.
  • Updates: Windows installer and Linux AppImage builds can update in app; portable, macOS, and Linux deb builds offer a GitHub Releases download. The app checks 30 seconds after it starts and then every six hours, and What's new under the update buttons opens the release notes of the running version
  • Start at Login: Enable or disable startup from Settings > General
  • Start Hidden: Add --hide to the launch command to start with the widget hidden in the tray. The Omarchy guide lists the related --toggle and --show actions
  • Settings: Access via the Settings button or right-click the tray icon

Settings Highlights

  • General: Configure Home Assistant connection, always-on-top, startup behavior, and language packs

  • Themes: Choose built-in or custom accent and background colors

  • Window Effects: Adjust opacity, toggle frosted glass, and enable subtle weather effects. On Windows, frosted glass needs Windows 11 version 22H2 or later; Windows 10 and older Windows 11 builds draw the solid panel instead

  • Primary Cards: Pin weather/time or any entity to the top two cards

  • Custom Entity Icons: Search or paste emoji/glyph overrides for entity icons

  • Media Tile: Select the primary media player or hide the tile

  • Hotkeys: Configure global entity hotkeys, action-specific shortcuts, and a popup hotkey (hold/toggle on macOS and Windows; press/toggle on Linux)

    On macOS the popup hotkey needs System Settings > Privacy & Security > Accessibility access. The widget asks when you set the hotkey and says so if it is still missing. macOS may ask again after an update; if the popup hotkey stops working, switch the widget on in that list and set the hotkey once more.

  • Alerts: Enable desktop notifications for entity state changes or target states, and choose whether Home Assistant's own notifications (new devices, repairs, updates) also reach the desktop; they always appear in the bell

  • Advanced: Updates, profile sync, logs, and interaction diagnostics for troubleshooting

Advanced Usage

Build from Source

git clone https://github.com/Robertg761/HA-Desktop-Widget.git
cd HA-Desktop-Widget
npm install
npm run dev   # Development mode (separate app and DevTools windows)
npm run dev:climate-demo # Isolated simulated Fahrenheit air-conditioner demo (no HA required)
npm start     # Regular run (builds the renderer, then starts Electron)
npm run lint  # Run ESLint
npm test      # Run Jest tests
npm run dist        # Build Windows NSIS and portable artifacts
npm run dist:win    # Build Windows NSIS installer artifacts
npm run dist:mac    # Build macOS distribution artifacts
npm run dist:linux  # Build Linux AppImage and deb artifacts

Building the Linux artifacts additionally requires a Rust toolchain (1.98 or newer, as pinned in .mise.toml) and python3: npm run dist:linux compiles the bundled windowtolayer layer-shell helper from vendor/windowtolayer before packaging.

Climate UI Demo (Development Only)

Run npm run dev:climate-demo to launch a simulated Demo Air Conditioner without a Home Assistant server. The demo starts with a Fahrenheit AC entity in Quick Access and advertises its HVAC, fan, and preset modes plus a 60–86°F target range with 1°F steps. Click the tile to toggle it; press and hold it to exercise the target-temperature, mode, fan, and preset controls.

This command only works with the development --dev launch path. It creates a fresh temporary Electron profile for that run, blocks all real Home Assistant service calls, and never reads or writes the normal app configuration, token, desktop pins, or profile-sync data. Remove the dev:climate-demo script and development/dev-climate-demo.js when the fixture is no longer useful.

To test the card alongside a real Home Assistant connection, run npm run dev:climate-overlay. This development-only mode leaves the normal Electron profile and Home Assistant connection intact, then places a renderer-local Demo Air Conditioner card at the start of Quick Access for the current session. Its fake state and climate service calls stay in memory and are intercepted before the WebSocket layer; the card is not saved as a favorite, cannot be edited/removed in Quick Access, and is never written into the normal configuration or sent to Home Assistant. The existing npm run dev:climate-demo remains the fully isolated mode.

Because the overlay uses the normal Electron profile, and only one widget runs per profile, it cannot start while a copy of the widget is already running — quit that one first. The isolated dev:climate-demo gets its own temporary profile and runs alongside the real widget.

Release Channels

  • Stable releases: Land the version bump (package.json, package-lock.json) and a CHANGELOG.md section for the version on main, wait for CI to pass there, then run the Tag Release workflow from the Actions tab with the version. It tags main and starts the release workflow, which publishes a normal release. Windows installer and Linux AppImage users can receive it through the in-app updater; portable, macOS, and Linux deb users download it from GitHub Releases.
  • Tester prereleases: Push a SemVer prerelease tag like v4.1.0-beta.1. GitHub Actions marks it as a prerelease. Only users who enable Receive beta updates in Settings → Advanced are offered these builds.
  • Nightly betas: At 07:17 UTC, GitHub Actions checks main against the last successfully published beta in the active series. When unreleased changes exist, it creates the next vX.Y.Z-beta.N tag and runs the normal release workflow. The job can also be started manually from the Actions tab.
  • Manual-update builds: Portable, macOS, and Linux deb users update from GitHub Releases. The update checker shows the appropriate stable or prerelease download when beta updates are enabled.

The minimum planned beta version is stored in .github/beta-target. The nightly job starts the active series at that version (for example v4.0.0-beta.1). Once that version is stable, it automatically moves to the next patch (v4.0.1-beta.N); increasing the file starts a future minor series instead.

Release builds align their package version from the tag. Manually prepared betas commit matching prerelease metadata before tagging; automated nightly betas align it only inside the build. Stable releases continue to sync package.json and package-lock.json after publishing.

The notes of a stable release are its CHANGELOG.md section, followed by a link to the full changelog, and the release fails without a non-empty section. A beta uses its own section when the changelog has one; otherwise GitHub generates its notes from merged pull requests, comparing against the previous published prerelease in the same version series (or the latest stable release for the first beta). Notes are written once, when the release is created; to replace a published release's notes, add or correct its CHANGELOG.md section on main and run the Update Release Notes workflow with the release's tag.

The website in website/ is not deployed by GitHub: a change merged to main goes live only when someone publishes it with the Vercel CLI, usually before a release is tagged, so every line on it has to read correctly on both sides of the release. Publish exactly what main holds, not a local folder that may be stale or have uncommitted edits:

(
  set -euo pipefail # any failed step, a fetch included, stops before the deploy
  git fetch origin
  rm -rf /tmp/ha-site # one command a line: set -e ignores a failure on the left of &&
  mkdir -p /tmp/ha-site
  git archive origin/main website | tar -x -C /tmp/ha-site # exactly what main holds
  cp -r website/.vercel /tmp/ha-site/website/              # the link `vercel link` made
  cd /tmp/ha-site/website
  vercel deploy --prod
)

Then run the Website deploy check workflow, which checks out main and compares every live page, asset and response header with it. (node scripts/check-website-deploy.cjs does the same against your own checkout, so it only proves anything on a clean, up-to-date main.)

Configuration

  • Config Location: Stored as config.json in Electron's userData directory.
    • Windows: %APPDATA%\home-assistant-widget\config.json
    • macOS: ~/Library/Application Support/home-assistant-widget/config.json
    • Linux: ~/.config/home-assistant-widget/config.json (or $XDG_CONFIG_HOME/home-assistant-widget/config.json)
    • Development builds: use the sibling home-assistant-widget-dev folder
  • Config Contents: homeAssistant (url and auth method; encrypted token fields only for legacy-token authentication), desktopCompanion (a random installation ID), favoriteEntities, customEntityNames, desktopPins, customEntityIcons, quickAccessTileOptions, tileSpans, selectedWeatherEntity, primaryMediaPlayer, globalHotkeys, entityAlerts, popupHotkey, windowPosition, windowSize, opacity, ui (theme, accent, background, language, customColors, timeFormat, dateFormat, use24HourClock, weatherEffectsEnabled, weatherOverride, enableInteractionDebugLogs), and customTabs. Other stored values include primaryCards, alwaysOnTop, frostedGlass, popupHotkeyHideOnRelease, popupHotkeyToggleMode, updates, and profileSync.
  • Security: OAuth refresh tokens are stored in a separate OS-encrypted credential file and short-lived access tokens remain in memory. OAuth pairing fails closed when secure storage is unavailable. Legacy tokens are encrypted at rest when supported by the OS and are never stored in plaintext as a fallback.

Anonymous install count

Release download numbers count every update, so they can't say how many people use the app. If you turn on Settings → Advanced → Count this install (it is off by default), packaged builds send one request a day with a random install ID, the app version, and the OS family (Windows, macOS, or Linux). Nothing about you, your Home Assistant, or your settings is sent, and the counter does not store IP addresses. The ID lives in usage-ping.json next to config.json and is never synced or exported. DO_NOT_TRACK=1 stops the request even when the setting is on. The counter service is in services/usage-counter.

Profile sync

Profile sync keeps your widget set up the same way on every computer. It writes one file, ha-widget-profile-sync.json, into a folder that Dropbox, OneDrive, iCloud Drive, Google Drive, Syncthing, or any similar app already keeps in sync. Folder sync needs no server and no account.

You can also choose HA Desktop Widget Cloud as the sync app, which is Cloud Sync: sign in with Google or GitHub on each computer instead of choosing a folder. It is a paid service: new accounts can save settings free for 14 days, and the subscription is USD 24 a year, billed from the day you subscribe. Once the trial ends or a subscription lapses, changes from your other computers still download, and this computer's changes wait until you subscribe. Everything below about scope, merging, backups and encryption works the same way. With encryption on, the service cannot read your synced settings. Running the service yourself is covered in docs/cloud-sync-setup.md.

Set up the first computer

  1. Open Settings → Advanced → Profile syncing and turn on Profile sync.
  2. Pick your Sync app, then Choose folder... and select a folder inside it.
  3. Optionally turn on Encrypt synced profile with passphrase and enter a passphrase of at least 8 characters.
  4. Choose Save and close. The sync file is created.

Add another computer

Do the same with the same folder (and the same passphrase if you encrypt). If both computers already have different settings, Settings lists which ones differ and asks which to keep: This computer (upload) or Sync file (download). The side you replace is backed up.

What syncs

Each computer chooses its own Sync scope. Changing it on one computer never changes another.

Section Contains
Quick Access and layout Favorites, pages, tile options, custom names and icons, primary cards, comparison graphs, tray values
Appearance Theme, colors, density, language, date and time formats, weather effects, opacity, frosted glass, always on top, hide on focus loss
Alerts Entity alert notifications
Weather and media Weather source and primary media player

These always stay on each computer: the Home Assistant connection and credentials, desktop pins, hotkeys and the popup hotkey, the open Quick Access page, text and control size, Omarchy theme following, window position and size, startup, updates, and diagnostics settings.

How changes are merged

Sync runs shortly after you change a setting, on the interval you choose (1 minute to 1 hour), when the widget regains focus, after the computer wakes, and when you choose Sync now.

Each section is compared with how it looked the last time this computer synced. A section that changed on only one side is copied to the other side, whatever either computer's clock says, so changes to different sections on two computers are both kept. Only when two computers changed the same section does the newer change win. The other version is then backed up and Settings says so.

Sync up replaces the file with this computer's settings, and Sync down replaces this computer's settings with the file. Both ask first and back up what they replace.

Backups

Before sync replaces settings on this computer, or replaces another computer's settings in the file, it saves a copy to profile-sync-backups/ in the app data folder. The last five of each kind are kept. Restore one from Backups in Settings: it is applied here and then syncs to your other computers, and the settings it replaces are backed up in turn.

Encryption

With encryption on, the whole file is encrypted with AES-256-GCM, using a key derived from your passphrase with scrypt. Every computer needs the same passphrase. Remember passphrase on this device stores it encrypted with the operating system's credential protection; where that is unavailable, it is kept only until the app closes. Turning encryption on or off, or changing the passphrase, rewrites the file in a way that recovers from a crash partway through. A computer whose settings do not match the file (encryption off, or an old passphrase) stops with an explanation instead of writing to it.

Troubleshooting

  • Nothing reaches the other computer: check that both use the same folder and that your sync app has finished copying. A folder inside the app's own data folder syncs with nothing, and Settings warns about it.
  • "Found conflict copy files": your sync app saw two computers save at the same moment and kept both, such as Syncthing .sync-conflict- or Dropbox "conflicted copy" files. Profile sync already merged the main file. Delete the copies you do not need.
  • Google Drive on Linux: there is no official client. Use a third-party client such as Insync or rclone, or Syncthing.
  • "The sync file was written by a newer version": update this computer.

Compatibility

Version 4.0 writes version 3 of the sync file, which stores each section with its own timestamp. It reads files from 3.x and upgrades them the first time it saves a change. Versions 3.x cannot read the new file. They stop with an error rather than overwriting it, so update every computer to 4.0.

See the 4.0 migration guide for backups, credential recovery, and returning to 3.x.

Troubleshooting

Connection Issues

  • Verify URL: Ensure your Home Assistant URL is accessible from your computer
  • Reconnect authorization: In Settings, click Reconnect with Home Assistant if authorization expired. Legacy-token users should verify that token manually.
  • Firewall: Ensure your OS firewall allows the app to connect to your network
  • Network: Test connectivity by opening your HA URL in a web browser

Linux

  • No tray icon on GNOME: Stock GNOME shows no tray icons. Install an AppIndicator extension (such as "AppIndicator and KStatusNotifierItem Support") to get the widget's icon. Without one, Minimize leaves the widget in the dock and the window switcher, but the title-bar X, Ctrl+W and Alt+F4 hide it with no icon to bring it back. The first time, a notification says the widget is still running: open HA Desktop Widget from your app launcher again, which shows it.
  • Black window, or black corners round the pins, on X11: See-through windows need a compositing manager. On a window manager without one (i3 or Openbox without picom, for example) the widget and its desktop pins are drawn against black. Run a compositor such as picom, or set Settings → Appearance → Window opacity to 100%, which makes the windows solid and gives the pins their rounded corners back.
  • The widget and its pins in the taskbar and Alt-Tab on Wayland: GNOME and KDE on Wayland list every window, because Wayland has no way for an app to ask to be left out. On KDE a window rule hides them; see Linux Wayland notes.
  • The AppImage closes without a window: On Ubuntu 23.10 and later, install the .deb, or start the AppImage from a terminal with --no-sandbox. See Running the AppImage on systems that block the Chromium sandbox.
  • Hindi text shows as boxes: Install a font with Devanagari, such as fonts-noto-core on Debian and Ubuntu or noto-fonts on Arch.

Performance Issues

  • Reduce Entities: Limit the number of entities in Quick Access
  • Visual Effects: Disable transparency if experiencing performance issues

Common Solutions

  • Restart: Close and reopen the app if entities aren't updating
  • Reconnect: Go to Settings and click Reconnect with Home Assistant
  • Check Logs: Use Settings > Advanced > Show log file to show the log file in your file manager (its path is copied if no file manager opens)

Contributing

We welcome contributions! Here's how you can help:

Reporting Issues

  • Bug Reports: Use the Issues page
  • Feature Requests: Submit enhancement ideas with detailed descriptions
  • Documentation: Help improve this README or add usage examples

Development

  • Fork & Clone: Fork the repository and clone your fork
  • Create Branch: Make changes in a feature branch
  • Test: Ensure your changes work and don't break existing functionality
  • Submit PR: Create a pull request with a clear description of your changes

Code Style

  • ESLint: Follow the existing code style (run npm run lint)
  • Comments: Add comments for complex logic
  • Testing: Add tests for new features when possible

Sponsors

HA Desktop Widget is independently developed and will remain free and open source. Sponsorship helps support ongoing development, maintenance, cross-platform testing, and other project expenses.

Become a sponsor or see the full sponsor list and recognition details.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments


If you find this project useful, please give it a star on GitHub!

Зеркало документации архивировано из официального репозитория GitHub · Перейти на GitHub
Дата снимка: 2026-11-08