Skip to main content

Migrate from Jetpack Compose

ViewCompose is Compose-inspired, but it is not a Compose compatibility layer. A successful migration preserves ownership, lifecycle, and observable behavior rather than replacing similarly named functions. Use this section to identify semantic gaps before moving a screen to the native Android View renderer.

Last verified: 2026-08-22

Re-verification owner: maintainers of the Kernel, UI Foundation, Android Engine, Android aggregate, and navigation module families

Verified source and target states

The target is the following independently versioned ViewCompose set:

Module familyArtifactsVerified version
State and compositionviewcompose-runtime, viewcompose-ui-foundationruntime 0.1.0-alpha02; UI Foundation 0.1.0-alpha01
UI and renderingviewcompose-ui-contract, viewcompose-renderer-android, viewcompose-constraintlayout-androidxcontract 0.1.0-alpha03; renderer/ConstraintLayout 0.1.0-alpha01
Android ownershipviewcompose-android, viewcompose-material3-android, viewcompose-host-android, viewcompose-lifecycle-androidx, viewcompose-viewmodel-androidxaggregates/integrations 0.1.0-alpha01; host 0.1.0-alpha03
Navigationviewcompose-navigation-core, viewcompose-navigation-androidcore 0.1.0-alpha02; Android 0.1.0-alpha01
Animationviewcompose-animation-core, viewcompose-animationboth 0.1.0-alpha04

The immutable release revisions are recorded in gradle/viewcompose-publishing.properties.

The upstream semantic baseline is:

Dependency familyVersion
Compose Runtime, UI, and Foundation1.11.4
Activity1.13.0
Lifecycle2.11.0
SavedState1.5.0
Navigation 22.9.8
Navigation 31.1.4

The repository's executable comparison baseline remains Compose 1.7.8, Activity 1.12.4, Lifecycle 2.8.7, and Kotlin 2.0.21, as declared in gradle/libs.versions.toml. Official Android documentation and release notes establish the newer upstream semantics; local source, tests, and compiled samples establish ViewCompose behavior. Passing a local comparison against 1.7.8 does not prove parity with 1.11.4.

No performance equivalence is claimed. Any future performance comparison must state devices, build modes, workloads, warm-up, sampling, and statistical treatment.

Choose the migration path

Source concernStart hereDecide before implementation
State, recomposition, keys, effects, or saveable stateState, recomposition, and restorationState owner, restart boundary, identity, effect commit point, and restoration lifetime
Layout, Modifier, density, locals, insets, or Android View outputLayout, Modifier, and environmentMeasurement engine, modifier folding, logical edges, local invalidation, and inset owner
Activity, Fragment, existing View host, lifecycle, ViewModel, or Android interopHosts, lifecycle, and Android interopRoot owner, disposal boundary, installed owners, replay-safe work, and release cleanup
Navigation 2 or Navigation 3NavigationSource navigation model, route identity, owner scope, hidden-session policy, and Back integration
Image loadingImage loadingSource types, loader ownership, request policy, and recycled-View disposal
Lazy collections and pagersLazy collection revisions and reuseSemantic revisions, mounted-tree reuse, interop reset/release, and TabRow/Pager hard cuts
Component DSL aliases, interaction feedback, TextField wrappers, or alpha-only content animationDSL contract convergenceVariant replacement, indication ownership, typed input profiles, and Crossfade naming
Physics, Animatable, content/visibility transitions, seeking, bounds, shared motion, or animation toolingAnimationDuration versus physical semantics, velocity, subtree identity, geometry owner, and inspection activation

Read more than one page when a boundary crosses concerns. For example, rememberSaveable in a navigation destination requires both the state/restoration and navigation ownership contracts.

Consolidated capability matrix

This matrix is a coarse migration decision aid. The linked page owns the detailed contract and evidence. Status terms have one meaning across all pages:

  • Supported — the migration-relevant behavior exists with repository evidence.
  • Partially supported — the main use case exists, but an important API or semantic boundary is narrower or different.
  • Intentionally different — ViewCompose deliberately uses another ownership or execution model, so code must be redesigned.
  • Unsupported — no corresponding public capability exists in this release.
DomainCapabilityStatusMigration decisionDetails
StateMutable state, mutation policies, and read observationSupportedPreserve state ownership; do not depend on Compose callback counts or threads.State
StateDerived state and snapshot transactionsPartially supportedReview equal-result suppression, nesting, conflicts, and thread rules.State
StateSnapshot collections and snapshotFlowPartially supportedsnapshotFlow is available; snapshot collections still use immutable values in MutableState.State
CompositionCompiler-generated restart, stability, and strong skippingIntentionally differentChoose explicit ViewCompose groups and place reads at the smallest update boundary.Recomposition
CompositionPositional remember and keyed identityPartially supportedKeep call order stable and do not rely on ordinary keyed-sibling movement during reorder.Identity
EffectsSideEffect, DisposableEffect, LaunchedEffect, and produceStateSupportedMove external work to committed effects and make failure cleanup explicit.Effects
RestorationrememberSaveable, Saver, and host restorationPartially supportedPrefer automatic keys, keep values small, and install services explicitly for custom hosts.Restoration
LayoutBuilt-in containers, size, fill, and parent dataPartially supportedRevalidate behavior against Android View measurement and LayoutParams.Layout
LayoutGeneral custom measurementUnsupportedUse a built-in container, ConstraintLayout, or a lifecycle-owned Android ViewGroup.Custom measurement
ModifierPadding, margin, ordering, and renderer foldingIntentionally differentNormalize chains and apply each modifier family's documented resolution rule.Modifier folding
ModifierStructural equality and renderer reuseSupportedUse semantic stable keys; a fresh callback object is not necessarily an update signal.Modifier equality
ModifierApplication-defined Modifier.Node lifecycleUnsupportedUse supported modifiers, interop, or a reviewed UI-contract and renderer feature.Modifier.Node
EnvironmentDensity and font scaleSupportedRetain logical dp/sp values and convert only at the renderer boundary.Environment
EnvironmentLocales, layout direction, and logical/physical edgesSupportedUse relative APIs for start/end intent, retain physical APIs for deliberate left/right behavior, and test RTL output.Environment
EnvironmentUiLocal as a CompositionLocal replacementIntentionally differentBack changing locals with observable state; local lookup alone does not invalidate readers.UiLocal
InsetsSystem bars, IME, and nested consumptionPartially supportedAssign one owner per edge and verify mixed View/ViewCompose handling.Insets
InteropViewCompose AndroidView callback lifecycleIntentionally differentSeparate replay-safe update/reset, post-transaction commit, and permanent-release cleanup.Android View interop
HostingActivity and Fragment rootsPartially supportedAccount for internally owned sessions and the Fragment owner/disposal mismatch.Standard hosts
HostingExisting-container renderIntoPartially supportedInstall every required owner and dispose the returned session explicitly.Custom host
OwnershipGeneral UI-scoped ViewModels and inherited CreationExtrasPartially supportedVerify destination/graph factory inputs; no arbitrary-subtree provider is available.Owners
SessionExplicit rendering, frame scheduling, and terminal disposalIntentionally differentTreat RenderSession as the owner of composition, native tree, overlays, and cleanup.Sessions
InteropDirect ViewBinding and Fragment-in-tree APIsUnsupportedKeep Fragment ownership outside the render tree and manage inflated XML explicitly.Unsupported interop
NavigationController, destination, and multiple-stack ownershipIntentionally differentTranslate desired state transitions rather than Navigation 2 or 3 API names.Navigation model
NavigationGraphs, typed routes, and stack operationsPartially supportedUse supported primitive NavValue arguments and one transactional command.Routes and transactions
NavigationEntry/graph owners and Lifecycle 2.11 factory inheritanceSupportedPreserve the inherited parent Factory/extras and keep repeated-route stack owners isolated.Entry ownership
NavigationDestination lifecycle and adaptive panesIntentionally differentAllow multiple resumed entries and do not infer sole visibility from RESUMED.Lifecycle
NavigationHidden destination composition retentionPartially supportedMake background work lifecycle-aware; hidden sessions retain effects and native Views.Retention
NavigationDeep linksPartially supportedReplace action/MIME rules; undeclared query values are tolerated but cannot affect navigation policy.Deep links
NavigationSave/restore, system Back, and Predictive BackSupportedRecreate live objects after restore and retain device validation in the release procedure.Restoration and Back
NavigationDirect NavigationEvent integrationUnsupportedKeep direct dispatcher-owner, forward-event, test-fake, and Preview needs outside ViewCompose.NavigationEvent
AnimationDuration sampling, target-as-state, autonomous transitions, fade/size visibility, Crossfade, and content-size animationPartially supportedUse only the current documented subset and do not treat the duration-bearing SpringSpec as physical.Animation
AnimationPhysical spring, decay, seekable transitions, bounds, shared motion, and timeline inspectionUnsupportedFollow the accepted phased contract; planned APIs are not migration targets until released.Animation

Migration sequence

  1. Record the source Compose, Activity, Lifecycle, SavedState, and Navigation versions.
  2. Inventory state, lifecycle, ViewModel, navigation, and durable-data owners before changing UI declarations.
  3. Mark compiler restart boundaries, layout-measurement assumptions, modifier ordering, logical edges, locals, and inset ownership.
  4. Classify every required capability using the matrix above. Stop and redesign any unsupported dependency before implementation begins.
  5. Move one independently testable screen or subtree. Do not mix a host rewrite, navigation model rewrite, and persistence rewrite without separate behavioral assertions.
  6. Compile the target code and verify recomposition, configuration recreation, process recreation, RTL, insets, Android View rollback, Back, and lifecycle behavior that applies to the screen.
  7. Re-run the comparison when a listed upstream or ViewCompose version changes.

Executable migration anchors

Documentation snippets are not a second source of truth. Use these compiled repository examples:

The root qaQuick task compiles these sample source sets or the tests that consume them. It also runs verifyMigrationPairedSamples, which rejects missing, extra, reordered, or stale paired snippets in both canonical English pages and required Chinese mirrors. Device-only restoration and Predictive Back evidence remains governed by the procedures linked from the state/restoration comparison and navigation guide.

Known contract gaps

Do not strengthen a capability label until source documentation, implementation, and executable evidence agree on these points:

  • Equal-result and nested derived state plus read-only snapshot nesting need focused regression coverage.
  • Repeated size/padding rules, nested inset consumption, and native-view callback identity need broader executable coverage.
  • Lifecycle 2.11.0 arbitrary UI scopes do not have ViewCompose parity evidence.
  • A fresh Predictive Back device run remains narrower than the full semantic baseline.

Re-verification must review official upstream documentation first, then immutable ViewCompose source contracts, tests, compiled samples, and applicable device procedures. A signature match or API-name similarity is never sufficient evidence.