Architecture
Home Assistant iOS is a multi-target Apple platform project. It started as a companion app centered around a web experience and has grown into a hybrid codebase with native onboarding, sensors, widgets, Apple Watch support, CarPlay, App Intents, and notification-driven features.
The repository combines app-specific code, shared platform code, extensions, and a small Swift server component in a single workspace.
Core principles
Multi-target by design
The repository is organized to share as much logic as possible across targets while still allowing platform-specific implementations where needed. Cross-cutting concerns such as database access, networking, design system pieces, notifications, widgets, and shared models live in common modules so multiple targets can reuse them. See the targets guide for an overview of each surface.
Hybrid UI stack
The project uses both SwiftUI and UIKit. Newer flows and components increasingly use SwiftUI, while legacy and platform-specific integrations still rely on UIKit and other Apple frameworks directly.
Repository structure
Sources/App
This contains iOS app-specific functionality such as onboarding, settings, scenes, cameras, notifications, web/frontend integration, kiosk features, and utilities.
Sources/Shared
This is the heart of the shared codebase. It includes:
- API and networking support
- Database code built around GRDB
- Shared models and domain logic
- Design system utilities
- Widget and notification support
- Location, Assist, and service integrations
Sources/Extensions
This area contains code for extensions and system integrations, including:
- Widgets
- App Intents
- Share extension
- Notification service and content extensions
- Matter support
- Push provider support
Other important directories
Sources/CarPlay: CarPlay templates and feature logicSources/WatchandSources/WatchApp: Apple Watch communication and watch app codeSources/Thread: Thread credential management and sharing flowsSources/MacBridge: macOS-specific bridge code used for Mac buildsSources/PushServerandSources/SharedPush: Swift package-based server and shared push logicTests: App, shared, UI, and widget testsfastlane: Linting, testing, versioning, and build automation
Key technologies
The current codebase makes heavy use of:
- Swift
- Xcode workspaces and schemes
- CocoaPods
- Fastlane
- WKWebView for frontend integration
- SwiftUI and UIKit
- App Intents and WidgetKit
Notable third-party dependencies
Beyond Apple frameworks, the app relies on several open-source libraries. The complete list lives in the Podfile, but these are the most commonly touched:
- HAKit — Home Assistant API client (WebSocket and REST)
- GRDB.swift — SQLite database access
- Alamofire — HTTP networking
- PromiseKit — promise-based async flows
- Starscream — WebSocket transport used by HAKit (we track a fork with a specific fix)
- SFSafeSymbols — type-safe access to SF Symbols
- KeychainAccess — keychain storage helper
- Eureka — form-based UI in legacy screens
- ObjectMapper — JSON mapping in legacy models
- XCGLogger — logging
- Improv-iOS — Improv Bluetooth onboarding
Architectural patterns in practice
Shared environment access
The project uses a shared Current environment pattern (see How to control the world) in many places to access dependencies and services. In practice, this means a single Current value groups the dependencies the app needs, which makes them easy to read from anywhere and easy to swap out in tests. The codebase treats this carefully enough that SwiftLint has a custom rule to prevent casual reassignment.
Extensions are first-class
We encourage you to take widgets, notifications, CarPlay, watchOS support, and App Intents into account from the start. The app needs to work well across all these surfaces while maintaining code quality, so changes often need to consider extension-safe code, shared storage, and cross-target reuse.
App plus platform surfaces
A feature may touch more than the main app. For example, an entity action could appear in the app UI, widgets, Apple Watch, App Intents, or CarPlay. It is worth checking whether a change belongs in Sources/App, Sources/Shared, or an extension target before you start coding.
How to navigate the codebase
The diagram below shows the actual Xcode shipping products on top and the Sources/* directories that feed into each one. Read it in either direction:
- Starting from a product (for example, the Apple Watch app): follow the arrows out to see every source directory that ships in it.
- Starting from a source directory (for example,
Shared): follow the inbound arrows to see every product that consumes it.
A few pieces live outside the main workspace:
Sources/PushServeris a standalone Swift package for the server-side push relay.Sources/SharedTestingis a test-only framework used by the test targets.
If you are new to the repository, a good way to orient yourself is:
- Start in
Sources/Appto see how the main iPhone and iPad app is structured. Most features originate here. - Place logic that multiple targets need in
Sources/Sharedso it can be reused by extensions, watch, and CarPlay. - For target-specific features (for example a watch-only or widget-only change), look in
Sources/Extensions,Sources/CarPlay, orSources/Watchfor the matching surface. - Look in
Tests/AppandTests/Sharedfor examples before adding new code.