Mikolaj Leszczynski
07/14/2026, 10:59 AMContainerHost sat alongside ContainerHostWithExternalState, Container alongside ContainerWithExternalState, and each pair dragged its own set of factory functions and extensions across the core, compose, viewmodel and test modules.
Choosing to separate your internal and external state meant switching to an entirely different interface hierarchy, and the duplication made every library feature twice as expensive to build and document.
That split is now gone. A single OrbitContainerHost<INTERNAL_STATE, EXTERNAL_STATE, SIDE_EFFECT> interface (backed by a matching OrbitContainer) covers both cases. A host that doesn't need the separation simply uses the same type for both state parameters — OrbitContainerHost<MyState, MyState, MySideEffect> — while a host that wants to keep a rich internal model and expose a lean UI-facing state declares two different types and supplies a transform to the new orbitContainer(initialState, transformState) factory. The container() factory functions on CoroutineScope and ViewModel have been renamed to orbitContainer() to match.
Additionally, we decided to add the Orbit prefix to main library types, as the historical ones were too generic and this was a good opportunity to fix this.
• New: Unified OrbitContainerHost<INTERNAL_STATE, EXTERNAL_STATE, SIDE_EFFECT> API — ContainerHost / ContainerHostWithExternalState are now deprecated typealiases for it. This simplifies the API for consumers as well as making upcoming feature work easier to implement
◦ Replaced container() / withExternalState with the orbitContainer() factory (external state via orbitContainer(initialState, transformState))
◦ Deprecated test() in favor of explicit testWithInternalState() / testWithExternalState() (assertions renamed accordingly, e.g. awaitState → awaitInternalState)
• New: Side effects now have explicit delivery modes: FAN_OUT (default, unchanged behaviour), FAN_OUT_STRICT, and experimental BROADCAST for multi-consumer delivery
• New: Orbit.configureDefaults { } for app-wide container settings
• New: experimental awaitRunOn<T> suspends until state matches a subtype
• runOn / subIntent are stable;Daniel (danflo)
07/15/2026, 5:31 PMrememberViewModelStoreOwner and rememberViewModelStoreProvider, we now have a native way to scope ViewModels directly to specific Composables (such as individual tabs, dialogs, or pager screens).
Since Orbit is built on top of standard ViewModel lifecycles, this natively allows us to automatically clean up MVI containers and cancel the underlying viewModelScope once a Composable leaves the composition.
Are there any official integration guidelines, best practices, or plans to introduce Orbit-specific Compose helpers that streamline using these new APIs with ContainerHost? For instance, resolving a scoped ViewModel and automatically tying the MVI state flow collection to the newly remembered store owner's lifecycle.
Again, thank you for the amazing work on this version!Mikolaj Leszczynski
07/16/2026, 9:50 AM