Why it exists
Backend-driven UI usually arrives as a sealed hierarchy of every widget the product happens to have: a client that must be released whenever the server learns a new component, and a serialiser that turns an unfamiliar type into a crash. kompot inverts that. The core knows about a tree, actions, modifiers and design tokens — nothing about what a "product card" is — and everything concrete is a plug-in module. An unknown type degrades to a placeholder rather than taking the screen down, and the degradation is reported to a sink the deployment owns.
What you get
- Open contracts —
KompotComponent,KompotAction,FieldValueandValidationRuleare interfaces; the application assembles the concrete set. - One annotation —
@KompotComponentMarker, and KSP writes the polymorphic registration and the renderer entry. - Forms — validation, visibility and cross-field rules run client-side; a server-relevant change asks for a targeted patch, and a server-computed value lands in a bound read-only field rather than an editable one.
- Server-driven theming over open string tokens, down to text colour.
- Per-user live updates — a screen names its own channel.
- Wizards as pure functions —
(session, transition, draft) -> session. - Compose renderers for the standard, form, wizard and image components, plus a Material3 design system with surface roles a brand overrides.
Install
repositories { maven("https://reposilite.kotlin.website/snapshots") }
val kompotVersion = "0.33.1.88"
dependencies {
implementation(platform("io.github.youndie:kompot-bom:$kompotVersion"))
implementation("io.github.youndie:kompot-core")
implementation("io.github.youndie:kompot-standard")
implementation("io.github.youndie:kompot-ktor")
}
A version carries the CI run number, so any two publishes differ; the BOM makes a mixed pair of versions impossible to write down.
The wire is a specification
The JSON Schema of every protocol module is generated from the very SerialDescriptors the responses are encoded with, and both the schemas and the written specification travel inside the published artefact — the numbered rules resolve from the jar, by id. Two conformance kits hold the two sides: kompot-tck walks a running server over HTTP with twelve checks, and kompot-client-tck is a corpus of eighteen cases any client answers through a seven-operation adapter, with a coverage report naming the rules nothing holds yet. Every release is read back from the repository by proba, and the verdict badge is written by the run that published it.
Limitations
- Your own components need your own renderers; the SwiftUI side is yours entirely.
- The live-update transport (SSE or WebSocket) is the application's.
- Business validation belongs to the server; the client highlights the field a refusal names.
- The Compose half pairs Compose Multiplatform 1.11.1 with material3
1.11.0-alpha07; mixing Compose lines fails at runtime, not at resolution. iosX64is unreachable for the Compose renderers —compose.runtimestopped publishing it. Device and Apple-silicon simulator targets are covered; the protocol modules carry all three iOS targets.