Home AssistantHome AssistantContributors
On this page

The app follows Google's recommended app architecture and takes inspiration from Now in Android. The project has a long history, so you will find code that does not follow these rules yet. This page describes where the project is going. When in doubt, follow this page, not the code next to yours.

A web view with native features

Home Assistant has always been a strong progressive web app, and the Android app builds on that. Its main screen is a WebView that shows the Home Assistant frontend. The app and the frontend talk to each other through a JavaScript bridge: the frontend asks the app for an access token through external authentication, and they exchange messages over the external bus. See the frontend screen for how that works.

Everything else is native: onboarding, settings, sensors, notifications, widgets, tiles, Assist, and the car and watch apps.

Principles

  • Kotlin only. The whole codebase is Kotlin, and it stays that way.
  • Compose for all new UI. No new XML layouts, data binding, or view binding. New widgets use Jetpack Glance. New screens use the HATheme theme. The older HomeAssistantAppTheme is Material 2 and deprecated. See Compose and the design system.
  • Coroutines and Flow for all concurrency.
  • Hilt for dependency injection. Never create injected classes by hand.
  • Keep code flavor agnostic. Put code in the main source set so both flavors get it. Only code that needs Google Play Services goes in full.
  • Keep up with Android. The target SDK follows the latest Android releases, and new Android versions get tested as they come out.
  • Gate features on the server version when they need something from Home Assistant that older versions don't have, for example server.version?.isAtLeast(2025, 6, 0).

Modules

The modules are listed on the Android overview. A few things worth knowing:

  • Shared Gradle configuration lives in convention plugins in build-logic, an included build. If you need the same setting in several modules, it belongs there.
  • :common holds everything the phone, car, and watch apps share, including all user facing strings in common/src/main/res/values/strings.xml. Only edit the English file: translations come from Lokalise. See Translations.
  • :automotive has no sources of its own. It compiles the sources of :app with a different manifest and a higher minimum SDK.

Inside a module, code is packaged by feature: sensors/, notifications/, settings/, onboarding/, widgets/, frontend/, and so on.

The tech stack

Concern What the app uses
UI Jetpack Compose, Glance for widgets
Navigation Navigation Compose with type-safe routes
Dependency injection Hilt
Concurrency Kotlin coroutines and Flow
WebSocket API OkHttp
REST API Retrofit
Serialization Kotlinx.serialization
Database Room, for user data
App settings SharedPreferences, behind a LocalStorage abstraction
Logging Timber

Talking to Home Assistant

The app uses three channels:

  • The webhook of the mobile_app integration, for sensor updates, location, and registration updates.
  • The WebSocket API, kept open for real-time features like Assist, entity state in widgets, and notifications without Firebase.
  • The REST API, for the rest.

Sensors are collected in the background and sent to Home Assistant by foreground services and workers.

Wear OS

The Wear OS app is a separate app in :wear. It cannot onboard on its own: it gets the server URL and credentials from the phone app through the Wearable Data Layer. That requires Google Play Services, so it only works with the full flavor of the phone app. After setup, the watch talks to Home Assistant directly, over the WebSocket API and its own webhook.

Android Automotive and Android Auto

Android Auto runs from the phone app: it projects car screens from :app onto the car display. Android Automotive is a separate build, :automotive, that runs on the car itself. Both use the same sources.

The app handles homeassistant:// links to open specific parts of the app. They are documented for users in the URL handler documentation.

Next

Was this page helpful?

Last updated on .