Open-source project
jxlarrea/voice-satellite-card-integration avatar
jxlarrea/voice-satellite-card-integration

Voice Satellite: turning any browser into a Home Assistant Assist satellite

Voice Satellite turns any tablet, phone, or browser into a hands-free voice assistant for Home Assistant

901 stars42 forksJavaScriptAGPL-3.0

At a glance

What is it?
Voice Satellite is a Home Assistant integration that turns a tablet, phone or browser into a hands-free voice assistant, running wake word detection on device and registering itself as an assist_satellite entity. The interesting engineering is in the choice of wake word engine, where three WebGPU and CPU options are supported side by side.
Who is it for?
Voice Satellite suits a Home Assistant user with a spare tablet who wants voice control and rich visual responses without buying a physical voice assistant, and the browser route needs no new hardware at all. It does not suit a user whose browser must stay closed or who needs the screen off, since a browser tab cannot listen in the background, and the documentation is explicit that this requires the Kiosk Satellite companion app.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 28 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A satellite that loads on every page instead of a dashboard card

Voice Satellite turns any tablet, phone or browser into a hands-free voice assistant for Home Assistant, like Alexa, Siri or Google Home, but the documentation emphasises fully private and running on your own hardware.

The architectural decision that distinguishes it from a Lovelace card is stated early. It runs as a global engine that loads on every page of Home Assistant, with no dashboard card required. Once you assign a satellite entity in the sidebar panel, the engine starts automatically and listens for wake words across all page navigations.

That is a meaningful difference in behaviour. A card based approach only hears you when the dashboard is open and the card is visible. A global engine hears you wherever you are in the interface, including on a settings page or a logbook view, which is what makes it usable as an actual satellite rather than a widget.

The integration registers as a proper assist_satellite device in Home Assistant, with what the documentation calls full feature parity with physical voice assistants. That matters because it means Home Assistant's own Assist pipeline treats it as a satellite, so the conversation model, the TTS engine and the intent handling are the platform's, not the integration's.

The repository is a HACS integration rather than a core one. There is a hacs.json at the root, a custom_components/ directory holding the Python side, a src/ directory for the JavaScript, an assets/ directory for the banner and screenshots, and a webpack.config.js for bundling the front end.

Three wake word engines and the reasons to pick each

The wake word detection section is the most substantive part of the feature list, because it describes three engines that all run in the browser with different trade-offs.

vsWakeWord uses WebGPU, is purpose-built for wall-mounted tablets, and is described as having the best recall and zero false positives in the project's own benchmarks, along with interpretable per-trigger phoneme logs. The phoneme log is a debugging feature rather than a nicety: when a wake word misfires on a wall tablet in a noisy room, being able to see which phonemes triggered is how you diagnose it.

microWakeWord is pure JavaScript on the CPU, works on every device, and has the lowest per-chunk latency. This is the fallback for hardware without WebGPU support.

openWakeWord is WebGPU-accelerated with a broad pre-trained keyword library, and the documentation describes multi-keyword scaling as near-free.

All three support custom models and an optional voice-activated stop interruption, and all three fall back to server-side detection when preferred.

That last point matters for the privacy claim. On-device detection keeps the audio local, but the fallback means the architecture allows the audio to leave the machine, and a user who insists on fully local processing needs to know that the server-side path exists.

The dual wake word feature is the more unusual capability. You can load two wake words simultaneously and route each to its own Assist pipeline. The documentation gives the concrete uses: a household that mixes languages, a setup that mixes a local-only pipeline with a cloud or LLM one, or giving each character its own conversation agent and voice.

A media player entity, a screensaver and ten skins

Beyond the voice interaction, the integration exposes a set of entities and display features that make it work as a wall panel rather than a toy.

The satellite is exposed as a TV-class media player entity. It plays audio, local video files, and HLS and MJPEG camera streams full screen on the satellite, with volume control, tts.speak targeting, media_player.play_media from automations, and Media Browser support. Text to speech can route to the browser or to a remote speaker, which is the difference between a satellite that answers and one that also announces.

For automations there are three entry points named in the documentation: assist_satellite.announce, start_conversation and ask_question, so an automation can push a spoken message to the satellite, open a conversation or ask the user something.

The visual side has ten built-in skins, named in the documentation as Default, Alexa, Google Home, Home Assistant, Ink Blobs, Kiosk Satellite, Lens Flares, Retro Terminal, Siri and Waveform, all with CSS overrides. There is also a reactive audio-level animation on the activity bar, which is the small detail that makes a skin feel alive rather than static.

The screensaver is configurable as a black overlay, an image, a video, a folder from the Home Assistant media library, or a live camera feed. It cross-fades between folder items, and it integrates with kiosk app backlight dimming and with motion dismiss for the Kiosk Satellite and Fully Kiosk apps.

There is also a mini card, an optional voice-satellite-mini-card for in-dashboard text display without the fullscreen overlay, which is the option for a screen you do not want to become a voice assistant.

The experimental LLM tools are a separate repository, Voice Satellite - LLM Tools, and cover image, video and web search, Wikipedia, weather, and stocks or crypto with visual panels.

Why a tablet needs a native app instead of a browser tab

The documentation contains a comparison table that is more useful than any feature list, because it states what a browser cannot do.

The rows that matter are the screen-off row and the microphone access row. A browser tab only gets microphone access while it is in the foreground and the page is active, so a browser based satellite goes deaf the moment you lock the tablet or open another app. The microphone access row is the same problem in a different guise: browsers require a secure context for microphone permission, so a Home Assistant instance served over plain HTTP on a local network cannot use the microphone at all.

That is why the Kiosk Satellite companion app exists. On Android it runs the wake word detection natively, keeps listening with the screen off or another app in front, starts on boot, and assigns the satellite entity automatically during its setup wizard. Voice Satellite detects that it is running inside Kiosk Satellite and hands wake word detection over to the app's native engine automatically, so you configure everything in Voice Satellite as usual.

The detection cost row is the one that decides the hardware question. Browser based detection is described as heavy on tablets, with 10x to 30x faster for native CPU inference. If you have an old tablet with a weak CPU, the browser route may not keep up with a wake word at all.

The repository also carries a build step for model conversion, convert:oww-onnx, running scripts/convert-oww-tflite-to-onnx.mjs, which is how the openWakeWord models get into a form the browser can run.

Packaging, release cadence and where the split between Python and JavaScript sits

The build system explains how a browser extension of this size gets shipped.

The front end is a webpack bundle, built in production mode, with Babel handling the transpilation and Babel's preset-env targeting the browsers it needs to support. There is a prebuild and a predev step that both run three scripts: sync-version.js, copy-fonts.js and copy-vendor.js. The version sync is what keeps the JavaScript bundle's version string in step with the release, and the vendor and font copies pull in the assets that are not compiled from source.

The only runtime dependency is hls.js at 1.6.16, which is the HLS streaming library used for the camera streams. Everything else in the package is a devDependency: Babel core and preset-env, babel-loader, webpack and webpack-cli.

That is a very small dependency footprint for something with this much functionality, and it is a consequence of the architecture. The wake word detection runs in the browser using models converted to a browser-friendly format, the media playback uses the browser's own media stack plus hls.js, and the Home Assistant side is a Python integration in custom_components/.

The tests run on Node's own test runner with the experimental VM modules flag, over the .test.cjs files in tests/.

bash
npm run test

The release naming is dated rather than semantic. The listed releases are 2026.9.13 from 2026-09-25, 2026.9.12 from 2026-09-22 and 2026.9.11 from 2026-09-19, with the last push on 2026-09-25. Three releases in a week is a fast cadence, which for a Home Assistant integration is normal because the platform itself ships monthly and the integration has to track it.

The licence field on the repository says AGPL-3.0, which is a strong copyleft licence. That is a meaningful constraint for anyone considering whether to base another project on this code. This is not legal advice, and the LICENSE file in the repository root is the document to read.

Where Voice Satellite is the wrong choice

The clear case against it is the browser background limitation, and the documentation is upfront about it rather than hiding it.

A browser tab is not a voice assistant device. It cannot listen with the screen off, it cannot listen when another app has focus, and it cannot use the microphone on a Home Assistant instance served over plain HTTP. So if the goal is a wall tablet that behaves like an Echo, the browser route is a prototype and the Kiosk Satellite app is the real answer. If the goal is a phone on your desk that hears you while you are looking at it, the browser route is fine.

The second limit is the wake word dependency. The documentation is candid that the browser based path is heavy on tablets and struggles on low-end hardware, and while three engines are offered, they are three ways of solving the same problem with different resource profiles rather than three independent options. A user on old hardware is pushed toward the native app regardless of preference.

The third is the reliance on the Assist pipeline for anything beyond the voice loop. The integration registers as an assist_satellite and the conversation behaviour comes from Home Assistant's pipeline, which means the quality of what it answers depends on which pipeline you have configured. A local-only pipeline with a small model will be noticeably less capable than a cloud one, and the visual richness of the responses depends on that model too. The experimental LLM tools, which produce the panels with images and weather and stocks, live in a separate repository and are marked experimental, so they carry the usual warning.

The alternatives differ in what they cost you. A physical voice assistant, an Echo or a HomePod or dedicated voice assistant hardware, gives you a device with a microphone that works when the screen is off, and it costs money but nothing in your attention. A dedicated small Linux box running a local browser in kiosk mode gives you the same property and more control, at the cost of owning a machine. And the Home Assistant Assist pipeline can be used with a plain browser and no extra hardware if voice control is a nice-to-have rather than the point.

Editorial conclusion

Voice Satellite suits a Home Assistant user with a spare tablet who wants voice control and rich visual responses without buying a physical voice assistant, and the browser route needs no new hardware at all. It does not suit a user whose browser must stay closed or who needs the screen off, since a browser tab cannot listen in the background, and the documentation is explicit that this requires the Kiosk Satellite companion app. Before adopting it, check the wake word engine comparison against your device, because the browser based path is described as heavy on tablets, and decide whether the experimental LLM tools and the separate companion repository are things you want to depend on.

Frequently asked questions

What does the Voice Satellite integration do?

It turns any tablet, phone or browser into a hands-free voice assistant for Home Assistant, working as a drop-in integration that registers as an assist_satellite device with wake word detection, media playback and visual feedback. It runs as a global engine that loads on every page, so no dashboard card is required.

Which wake word engines does Voice Satellite support?

Three, all running in the browser: vsWakeWord using WebGPU and aimed at wall-mounted tablets, microWakeWord as pure JavaScript on the CPU for the lowest per-chunk latency and the widest device support, and openWakeWord using WebGPU with a broad pre-trained keyword library. All three support custom models and fall back to server-side detection when preferred.

Can Voice Satellite listen when the screen is off?

Not in a browser. The documentation's comparison table shows wake word with the screen off and with another app in front as unsupported in the browser, but supported inside the Kiosk Satellite companion app on Android, which runs wake word detection natively with 10x to 30x faster detection cost.

How is Voice Satellite installed?

It is distributed as a HACS integration, and the repository includes a hacs.json. The front end is a webpack bundle built with the prebuild step running sync-version.js, copy-fonts.js and copy-vendor.js, while the Python side lives in custom_components/. The only runtime dependency is hls.js.

What licence does Voice Satellite use?

AGPL-3.0, according to the licence field on the repository, with a LICENSE file in the root. The latest listed release is 2026.9.13 from 2026-09-25 and the last push was on 2026-09-25.

Official sources

  1. Issues
  2. jxlarrea/voice-satellite-card-integration on GitHub
  3. License: AGPL-3.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/jxlarrea-voice-satellite-card-integration.svg)](https://hysenlabs.com/projects/jxlarrea-voice-satellite-card-integration)

Was this useful?