Hello folks! Yesterday we've released Orbit 12.0.0...
# orbit-mvi
m
Hello folks! Yesterday we've released Orbit 12.0.0! orbit multiplatform Full Release Notes The headline change in this release is the unification of Orbit's container host API. Until now, external state support lived in a parallel universe of types:
ContainerHost
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;
❤️ 4
🎉 4
orbit multiplatform 3
thank you color 3
d
Huge congrats on the release of Orbit MVI 12.0.0! The mature Kotlin Multiplatform and Compose Multiplatform support is a game-changer for shared architecture. With Jetpack Lifecycle 2.11.0 introducing the new granular scoping APIs,
rememberViewModelStoreOwner
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!
m
Thanks for the suggestion @Daniel (danflo) - We don't currently have any plans. Off the top of my head, I think what we already have will work out of the box with these APIs? IIUC they control the viewmodel's lifecycle, while orbit attaches to that lifecycle after instantiation. Do you have a use case or ideas for any improvements around this area? Are you suggesting decoupling the ContainerHost from the underlying ViewModel? I think I need some more examples.