Library / SDK
google/horologist avatar
google/horologist

Horologist: Google libraries for the gaps in Wear OS

Horologist is a group of libraries that aim to supplement Wear OS developers with features that are commonly required by developers but not yet available.

702 stars123 forksKotlinApache-2.0

At a glance

What is it?
Horologist is a set of Kotlin libraries from Google that fill in what Wear OS does not ship, most visibly the Media Toolkit with a Media3 based background playback service and a full set of Material 3 player, browse and volume screens. It is versioned in parallel branches, with 0.7.x kept stable and main moving to newer AndroidX.
Who is it for?
Adopt Horologist if you are building a media app on Wear OS and want a background playback service that respects watch specific routing rules plus a complete set of player and volume screens, rather than assembling that from Media3 and Wear Compose yourself. Do not adopt it if you are shipping on a stable branch and depend on APIs that main has since renamed, because main actively removes and changes APIs while the maintenance branches promise not to.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Kotlin, 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 gap filler, not a framework, and the naming shows it

Horologist's own description sets the expectation precisely: it is a group of libraries that aim to supplement Wear OS developers with features that are commonly required by developers but not yet available. That is a deliberately narrow claim, and it matters when you decide whether to depend on it.

You are not adopting an application framework. There is no Horologist application class, no opinionated navigation host, no lifecycle policy. What you are adopting is a set of specific pieces: a media toolkit with its own domain, data, backend and UI layers, a set of prebuilt composables, and a pile of smaller modules visible in the repository layout, including annotations, auth, compose-layout, compose-material, compose-tools, datalayer, health, network-awareness, remotecompose and tiles.

The Kotlin codebase sits under a Google organisation, which means the code follows Google conventions and is released under Apache 2.0, and the documentation is published as a site at google.github.io/horologist with a mkdocs setup and a docs directory in the tree. The project is also an alpha, since the most recent releases are v0.8.4-alpha, v0.8.3-alpha and v0.8.2-alpha, which is the honest signal that the API surface is still settling.

Two maintained branches with different stability promises

The versioning table is the single most useful piece of documentation in the repository, because it tells you what stability you are buying. The currently maintained branches are 0.7.x on the release-0.7.x branch and 0.8.x on main.

Both require a minimum Wear SDK of 26 and both target Kotlin 2.2 with JDK 17, so the floor is the same on either line. What differs is the AndroidX surface. The 0.7.x branch pairs Wear Compose 1.5.x with Compose 1.8.x and generally the latest stable Androidx, while 0.8.x on main pairs Wear Compose 1.6.x with Compose 1.9.x and generally the latest relevant alphas of Androidx.

The stability contract is stated in one sentence. Maintenance branches will not delete existing APIs and they should remain stable, but the main branch will actively update to incorporate new API guidance, removing or changing APIs.

That is a clear division of labour, and it tells you how to consume the project. Pin to release-0.7.x if you cannot absorb breaking changes, and treat main as a place where your build can break without a version bump. Since the published releases are alpha tags, the branch choice does more work than the version number in your dependency declaration.

Nightly builds are run in CI on main, and there is a separate nightly release workflow alongside the regular build and test workflow, which means the main branch is exercised continuously even when a tagged alpha is months old.

The Media Toolkit splits domain, playback engine and screens

The Media Toolkit is the centrepiece, and it is described as designed using a clean architecture, which is visible in how the modules are named.

The core and playback side has three pieces. The media-core module holds core domain models, interfaces and state representations for media playback, and is agnostic of the underlying player implementation. The media-data module implements that domain using AndroidX Media3. The media3-backend module is the background playback service and engine built on Media3, and its distinguishing job is enforcing Wear OS specific routing rules, with Bluetooth output given as the example.

That last point is the one you cannot easily write yourself. On a watch, audio routing is not a settings toggle, and a background service that plays to the wrong output on a watch is broken in a way that the same code on a phone is not.

The presentation side is split the same way, and again the split is the point. There are shared presentation data classes and view states in media-ui-model, which means the screens do not own their state. The screens themselves come in two flavours: media-ui-material3 with modern Material 3 screens, scaffolds and responsive components, and media-ui with the legacy Material 2 components. Audio and volume follow the same pattern, with media-audio holding core domain models, output device trackers and volume managers, media-audio-ui-model holding shared audio view states, and matching material3 and legacy UI modules.

So a team can adopt the Material 3 screens while keeping Material 2 components elsewhere, and the presentation data classes are shared between the two.

Sync, logging and the output switcher fill in the dull parts

Beyond the domain and the screens, three smaller modules handle the parts of a media app that are tedious and easy to get wrong.

The sync module covers offline content, the download queue, and play state synchronization between phone and watch. For a watch app, that gap between the two devices is where most of the engineering effort actually goes, and having it as a library rather than a per project decision is a real saving.

The media3-logging module provides diagnostic logging utilities for tracking Media3 player events on Wear OS. When a watch app plays audio to the wrong place or stops without an error, the first question is always what the player was doing, and having a logging utility already written for the Wear OS case saves an afternoon of reading a stack trace.

The media3-outputswitcher module holds output switching and Bluetooth pairing prompt controllers, which is the counterpart to the routing rules in the backend service. The audio domain module carries output device trackers, so the UI can show what is playing where.

There is also a benchmark module and a sample-benchmark module for macrobenchmarks and performance test suites covering both the libraries and the sample application. Having performance tests for the libraries themselves is unusual and is the kind of thing that only happens when the maintainers care about the libraries being used at scale on constrained hardware.

The sample app is the documentation that actually helps

For a library set this size, the sample is the reference implementation, and the media sample is described as a UAMP clone showcasing local and streaming music, downloads, volume control and Navigation 3.

A UAMP clone is a useful choice for a reference because it is the application everyone in the Wear OS world already has a mental model of. The point of the sample is not the feature list but the wiring: it shows how media-core, media-data, media3-backend and the UI modules are combined in a project that runs.

The screenshot table in the README shows the player screen, browse screen, entity screen and volume screen for the material3 UI, which is a quick way to judge whether the visual design matches what your own app wants before reading any code.

On the composables side, Horologist ships prebuilt composables, with time and date pickers named as the examples, in the horologist-composables library. The repository also contains a compose-tools directory, a compose-layout directory and a compose-material directory, plus a tiles directory, a remotecompose directory and a network-awareness directory, and a sample application of its own outside the media toolkit.

A developer-oriented project also sits in the tree: the ai directory, and an annotations module. Aiming to make the libraries consumable by other teams is what the module boundary and the per module documentation links are for.

Getting the libraries in, and where the docs live

The project does not present a single install step, because Horologist is a set of separate libraries rather than one artifact. The documentation is published per module under google.github.io/horologist, with paths such as media-core, media-data, media-ui-material3, audio and composables, and each entry in the module list links to its own page.

So the practical approach is to read the module list, decide which pieces your app needs, and pick them up from the module coordinates given in the project documentation, for example :media:core for the media core library, :media:data for the Media3 backed implementation, :media:backend-media3 for the background service, and :media:ui-model, :media:ui-material3 and :media:ui for the presentation layer.

The build itself is a Gradle project with a settings.gradle.kts and a build.gradle.kts at the root, a gradle directory, a gradlew wrapper and a catalog.spec.json for the version catalog, plus a renovate.json for dependency updates. There is a checksum.sh script, a generate_docs.sh script, a spotless directory for formatting, and a .editorconfig. A sample/build.gradle.kts is checked in alongside the sample source, so the sample's own build file is the fastest reference for how a consuming module is wired up.

The repository also carries an annotations module and a localization.bzl file, which tells you that the libraries are built to be localised rather than hard coded for English, an important detail for a library that other teams will ship to many markets.

Editorial conclusion

Adopt Horologist if you are building a media app on Wear OS and want a background playback service that respects watch specific routing rules plus a complete set of player and volume screens, rather than assembling that from Media3 and Wear Compose yourself. Do not adopt it if you are shipping on a stable branch and depend on APIs that main has since renamed, because main actively removes and changes APIs while the maintenance branches promise not to. Before you commit, pick the 0.7.x or 0.8.x line deliberately, check that your minimum Wear SDK of 26 and your Kotlin and JDK versions match that line, and read the media sample app to see how the modules fit together.

Frequently asked questions

What is Horologist?

Horologist is a group of libraries from Google that supplement Wear OS development with features that are commonly needed but not yet available in the platform, most notably the Media Toolkit, a set of prebuilt composables such as time and date pickers, and modules for tiles, datalayer, health and network awareness.

Which Horologist branch should I depend on?

The 0.7.x line on the release-0.7.x branch pairs Wear Compose 1.5.x with Compose 1.8.x and the latest stable Androidx, and its APIs will not be deleted. The 0.8.x line on main pairs Wear Compose 1.6.x with Compose 1.9.x and newer Androidx alphas, and main actively removes or changes APIs.

What does the Horologist Media Toolkit include?

It includes a media-core module with domain models and state representations that are agnostic of the player, a media-data module implementing that domain with AndroidX Media3, a media3-backend background playback service that enforces Wear OS routing rules, and presentation modules for Material 3 and legacy Material 2 screens.

Does Horologist support audio output switching on a watch?

Yes. The media3-outputswitcher module provides output switching and Bluetooth pairing prompt controllers, and the media-audio module carries core domain models, output device trackers and volume managers, while the background service enforces Wear OS specific routing rules.

What licence is Horologist released under?

The repository carries an Apache 2.0 licence, and the documentation is published per module on the project documentation site, with pages for media-core, media-data, the UI modules, audio and composables.

Official sources

  1. google/horologist on GitHub
  2. License: Apache-2.0
  3. Project website
  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/google-horologist.svg)](https://hysenlabs.com/projects/google-horologist)

Was this useful?