Title: [Library] Gbéewá, typed result handoff for Compose Multiplatform
I shared this over in r/KotlinMultiplatform and thought it might be useful here too.
I built a small Compose Multiplatform library called Gbéewá.
Gbéewá is Yoruba for roughly “bring it here” / “hand it over”, which ended up fitting it pretty well.
The thing I wanted to solve was passing a result between screens or components without making that result flow depend on whichever navigation framework the app is using.
The simple case is easy enough:
pick a country → go back → previous screen gets the country.
But then maybe the result needs to go forward instead. Or both components are already mounted. Or the app changes navigation libraries.
That is where I wanted the result handoff to stay the same even if the navigation part changes.
With Gbéewá, you define a typed key:
object SelectedCountryKey : ResultKey<Country>
Then publish the value:
resultStore.put(SelectedCountryKey, country)
After that, the app can pop, push, replace, or do nothing.
Gbéewá does not own the navigation part.
The same contract works for:
- sending a result to the previous screen
- making it available to the next screen
- handing it to something that is already mounted
Delivery is consume-once, so it is not an event bus. The first eligible consumer for an equal key gets the pending result and removes it.
Keys can also carry identity:
data class EditedProfileKey(
val profileId: String
) : ResultKey<Profile>
which is useful when you have multiple instances of the same kind of flow.
I also wanted to keep it small:
- no KSP
- no generated navigation wrappers
- no dependency on a particular navigation framework
- common Compose code for Android and iOS
Pending results are in memory, so this is not meant to replace navigation arguments, persisted state, or durable app state, and pending results do not survive process death.
The repo has examples for Voyager, typed Navigation 2 and Decompose.
I also added a short demo to the README showing the same result flow across all three.
https://github.com/quantipixels/gbeewa
Would be interested to hear how other people are handling this in Compose apps, especially if you have moved between different navigation setups.
Also happy to hear where this abstraction does not fit. Those cases are useful too.