Released documentation snapshot. This immutable manual describes
viewcompose-ui-contract:0.1.0-alpha01from source revisionfbe1614d. For current guidance, open the current module catalog.
UI Contract
viewcompose-ui-contract defines the platform-neutral model shared by ViewCompose DSL modules and
renderers: immutable virtual nodes and node specifications, ordered modifiers, environment values,
layout units, interaction contracts, and renderer-connected state for lazy collections and pagers.
Use it directly when building a custom renderer, host bridge, tooling integration, or reusable API
that exposes ViewCompose contract types. Application UI normally receives it transitively through
viewcompose-widget-core.
This module does not compose a DSL tree, create Android View instances, reconcile nodes, schedule
frames, or integrate Android lifecycle and saved state. Those responsibilities belong to the
runtime, widget, renderer, and host modules.
Artifact and stability
dependencies {
implementation("com.viewcompose:viewcompose-ui-contract:0.1.0-alpha01")
}
- Stability: Alpha. Source and binary compatibility may change between alpha releases.
- Platform: Kotlin/JVM, compiled with the Java 11 toolchain; no Android SDK or AndroidX dependency.
- Direct ViewCompose dependencies:
viewcompose-text-coreas an API dependency, plusviewcompose-runtimeandviewcompose-graphics-coreas implementation dependencies. - Transitively exposed contract family: the platform-neutral text document and editing model from
viewcompose-text-core. - Build baseline for this release: Kotlin 2.0.21.
Minimal contract usage
val gap = VNode(
type = NodeType.Spacer,
key = "content-gap",
spec = EmptyNodeSpec,
modifier = Modifier
.size(24.dp)
.testTag("content-gap"),
)
This creates a renderer-neutral semantic node. A compatible renderer resolves NodeType.Spacer,
validates its EmptyNodeSpec, interprets the modifier chain in order, and owns any native object
created for the node.
Principal APIs
VNodeandNodeTypedefine immutable tree content and renderer dispatch.NodeSpecand its concrete property snapshots define the supported renderer inputs.Modifiercarries ordered layout, drawing, interaction, semantics, focus, and parent-data elements.UiEnvironmentValuescaptures density, locale tags, and logical layout direction for a subtree.LazyListStateand pager state bridge platform scrolling to observable runtime state.FocusRequesterandNestedScrollDispatcherdefine explicit renderer attachment boundaries for focus and nested scrolling.- The unit, shape, graphics, key-input, gesture, semantics, and tooling packages complete the platform-neutral vocabulary used across ViewCompose modules.
The complete generated reference is available under the
viewcompose-ui-contract API tree.
Because the current line is alpha, the documentation site intentionally does not expose a stable
latest alias.
Contract and lifecycle rules
VNode.typeandVNode.specare a registry-level pair. Construction is intentionally cheap and does not validate compatibility; a renderer must reject an unsupported pair deterministically.- A node specification is an immutable render snapshot. Callbacks may capture mutable application state, but the spec itself must not be used as a native-object owner.
- Modifier order is semantic. Layout and parent-data collection, visual decoration, input, semantics, and drawing phases consume the ordered elements according to their documented phase rules; reordering elements may change behavior.
UiEnvironmentValuesis captured on every VNode subtree. A renderer must use the captured values instead of consulting unrelated process-global density, locale, or direction state.LazyListState, pager state, focus requesters, and nested-scroll dispatchers attach to one current renderer connector. Hosts must detach old connectors during replacement or disposal.- State and connector commands are thread-confined to the owning renderer thread. Android integrations use the main thread, and callbacks run synchronously unless a concrete contract says otherwise.
AndroidViewNodeProps.updateandonResetare replay-safe transaction callbacks. External one-shot work belongs inonCommit; resource cleanup belongs inonRelease.
Collection prefetch, native cache sizing, motion, and shared-pool values are renderer hints rather than semantic state. A platform may clamp or ignore an unsupported optimization without changing the declared content.
Related documentation
- Node specifications and renderer registration
- Modifier architecture
- Current architecture and module boundaries
- Lazy collection guide
- Focus and input guide
- Nested scrolling guide
- Source documentation and API comment standard
Compatibility notes
The 0.1.0-alpha01 line establishes the first public renderer contract. Adding a NodeType, a
concrete NodeSpec, or a modifier element can require a renderer update even when application DSL
source remains unchanged. Custom renderers should fail clearly for unknown contracts and should not
persist enum ordinals, sealed-subtype names, tooling metadata, native view identities, or callback
instances as long-lived external data.