Remote Compose for Android, Wear OS, iOS and desktop
Change what's on screen without shipping an app.
Livery publishes Remote Compose templates as a signed catalog on any static host. Apps, launcher widgets, watches and notifications fetch, verify and cache them, fill them with typed data and play them, without ever waiting on the network.
Design once. Publish anywhere. Play everywhere.
Three steps, and the app never needs a release to show a new look.
-
1
Agree a contract
The contract is the only thing the app and the designer share: what a template may read and which actions it may emit. Author the
.rcin any tool."id": "promo/banner", "major": 1, "inputs": { "headline": { "type": "string", "maxLength": 40 }, "accent": { "type": "color" } }, "actions": { "cta": { "kind": "navigate" } } -
2
Build, sign, publish
The
liveryCLI refuses a broken catalog, signs the manifest and writes content-addressed files for a GitHub release, a CDN or your own server.livery keygen acme livery build catalog build/release \ --github acme/app-templates \ --tag catalog-1 \ --key acme.key --key-id acme-1 -
3
Play it in a slot
The client picks the right template for each player and size, binds data through the contract and draws it, from disk first, with your native fallback underneath.
LiverySlot( key = tile, host = host, fallback = { NativeTile(tile) }, ) { planner.forAppData(query, data) }
How it fits together
Livery sits between "there is a .rc document" and "it is on
screen with the right data", and reports what was shown and tapped.
- Authorany tool
.rc+ sidecar JSON - livery CLIvalidate, signmanifest + blobs
- Any hostGitHub release, CDNdesign server, assets
- Your appfetch, verify, cacheselect, bind, play
- Contract
- What a template reads and may emit (
promo/banner@1). - Design
- One look for a contract, as a picker shows it (
banner-classic). - Template
- One values-free
.rcper design and target. - Catalog
- A signed
manifest.jsonplus content-addressed files.
One template, any data, one gate
A template is values-free. The app, a decision server or a feed supplies the data, and
ContractBinder checks it against the contract on the way in: the same check in the
app, the publisher and agent tools. Data that doesn't fit is refused, not dropped,
and the slot shows your native fallback instead.
Designs are swappable too: ship a bolder banner to a rollout cohort or let people install a skin, and a design that can't play falls back to the automatic one, never to nothing.
{ "name": "Kitchen", "state": "On · 80%",
"is_on": true, "level": 0.8 }

{ "name": "Kitchen", "state": "Off",
"is_on": false, "level": 0 }

{ "name": "Kitchen", "state": "Unavailable",
"available": false }

{ "name": "Kitchen", "state": 80,
"colour": "red" }
state: expected string ·
colour: not in live/status-tile@1Get started
Libraries on Maven Central as ee.schimke.composeai:<module>;
the livery and livery-mcp CLIs attached to each GitHub release.
dependencies {
implementation(platform("ee.schimke.composeai:livery-bom:<version>"))
implementation("ee.schimke.composeai:livery-client") // fetch, verify, cache, select, bind
implementation("ee.schimke.composeai:livery-compose") // LiveryTemplate, LiverySlot
// livery-launcher-widgets, livery-wear-widgets, livery-notifications
}
Android, JVM, iOS and Wasm from one Kotlin Multiplatform client. Set up the repository →
// Package.swift
.package(url: "https://github.com/yschimke/livery", branch: "main")
Livery and LiveryUI for iOS and macOS, held to the Kotlin client by shared conformance fixtures. Swift details →
git clone https://github.com/yschimke/livery && cd livery
./gradlew :livery-publish:installDist :livery-capture-cmp:sampleCatalogs
export PATH="$PWD/livery-publish/build/install/livery/bin:$PATH"
livery build livery-capture-cmp/build/samples/catalog build/sample-catalog
Validate, sign and lay out a catalog for any host. Hosting →
./gradlew :livery-mcp:installDist
claude mcp add livery -- /abs/path/livery-mcp path/to/catalog \
--write --preview-out build/previews
Contracts, the data gate and renders for any MCP agent, but never the signing key. AI workflows →
What you can build
Each page goes from the contract to a deployment checklist.
Interactive ads
Your ad server answers a placement with a template reference and its data; Livery draws exactly that creative, or nothing.
in-appPromotions and growth
Ship rules in the catalog (window, audience, rollout, frequency cap); the device picks the promotion, offline.
in-appFeeds
A feed page is a list of template references plus data; a handful of templates draw thousands of items.
in-appLive content
The app pushes its own live values into a template, and people install skins for it.
launcherLauncher widgets
Subclass one provider; Livery instantiates the template for each widget's size and routes taps back.
wearWear widgets
Subclass one Glance Wear widget; Livery frames the template in each watch's container.
notificationsNotifications
Render a template for a notification's expanded body; taps come back to your receiver.
web · builtThe web
A2UI components for Lit, React and Angular, over the TypeScript player.
Built for templates in production
Never waits on the network
Slots draw from disk, then the bundled catalog, then your native fallback. refresh() runs in the background.
Refused, not dropped
One gate, ContractBinder, checks data in the app, the publisher, decision servers and agent tools alike.
Signed catalogs
Ed25519 manifests, partner keys scoped to a contract prefix, rotation, freshness and a kill switch. Signing →
Any static host
GitHub releases, a CDN or a design server. Content-addressed files cache forever. Hosting →
The right template per player
TemplateSelector matches surface, Remote Compose level, profiles and size.
Agents included
livery-mcp gives agents contracts, validation and PNG previews; drafts stay unsigned. AI workflows →
Kotlin and Swift agree
Both ports run the same conformance/ fixtures for selection, binding, resources and trust.
An open protocol
A normative, versioned manifest: new fields have defaults, old clients ignore what they don't know. Protocol →
Platforms
- Kotlin Multiplatform client (Android, JVM, iOS, Wasm)
- Compose Multiplatform (
LiveryTemplate,LiverySlot) - Swift package (
Livery,LiveryUI) - Launcher widgets (Android 16+)
- Wear widgets (Glance Wear)
- Agent tools (
livery-mcp) and headless previews - Phone-to-watch sync, web element, reference server Planned