im using the jetbrains cmp nav3 ```rememberNavBac...
# multiplatform
u
im using the jetbrains cmp nav3
Copy code
rememberNavBackStack(Screen.Home)
this compiles fine on android but fails on ios with
Argument type mismatch: actual type is 'Screen.Home', but 'SavedStateConfiguration' was expected.
I get the point of the problem, but what I dont get is WHY does android compile fine? I'd expect both to fail, no? navigating inside the function brings me to
Copy code
@Composable
public fun rememberNavBackStack(
    configuration: SavedStateConfiguration,
    vararg elements: NavKey,
)
so again, configuration parameter mandatory
e
CleanShot 2026-06-14 at 3 .18.55@2x.png
u
are you in commonMain?
e
In common main, you should have access to only the
SavedStateConfiguration
one. If that is not the case then something is wrong somewhere.
u
yet android compiles fine
i.e. I'd expect that yes and android compilation to fail
e
Does it show an error in the IDE? I would expect yes.
u
yes it's underlined
👍🏾 1
e
Android does not fail probably because when compiling the android sourceSet that signature is available to the compiler.
u
why, I dont see it in the compose nav3 lib
(unless i looking wrong)
e
The android target of the nav3 library has it (or rather it depends on android nav3, which has it)
Thats what I showed in first screen shot
u
but isnt that showing the vanilla android artifact?
I'd expect
org.jetbrains.androidx.navigation3:navigation3-runtime
e
Yeah if android nav3 is a dependency of CMP nav3 then its declarations will be transitively available.
u
thats suprising, since afaik its a fork
but okay I dont know details
e
Its not (exactly) a fork
u
so they fork it, and then depend on it as well, doooes not compute
e
Yes something like that.
Because Google/Android provide a complete android implementation for the KMP library in question, it wont make sense for JB to maintain a copy or fork. The pragmatic approach is to delegate the android target to the android implementation
u
last time I was checking, its was a normal fork, then sync the core stuff and then have additions in the other module
but okay I could forget
e
In reality most of the androidx libraries are increasingly multiplatform, so the work from JB really is to define implementations for the other platforms (ios, wasm, jvm)
u
but it does explain the issue
OT: how on earth do you maintain the saved configuration thing for all the screen keys? seems like impossible task & runtime crash festival
e
> how on earth do you maintain the saved configuration Dependency Injection X Multibinding would be the proper way for KMP apps. Maintain some sort of registry object, register the serializers across modules, use it to construct a
SSC
just before you call
rNBS
u
whats ssc rnbs
e
SavedStateConfiguration, rememberNavBackStack, sorry on mobile so trying not to type too much
u
ah, okay well multibinding won't help you really, its by design additive - theres nothing to tell you you forgot to add a multibinding entry
e
Yes of course but thats the only solution. Personally I would make it a part of defining my screen objects (either via custom linting or annotation processor or compiler plugin or dependency injection plugin)
u
part of defining how? but yea I think linting is the only way ugh
but thats gonna such hard, to get all the keys from all projects, then figure out whats actually included in the current app (could be multiple)
e
You can bake it directly into your entryProvider dsl. Basically when anyone in the company does
Copy code
EntryProvider {
  entry<MyScreen> { ... }
  entry(MyScreen.serializer()) { ... }
}
you'd pick up the serializer at that point. The first
entry
api can be for android (and jvm) because those platforms can use reflection, The second one is for other platforms where reflection is not possible. Havent tried this myself, just thinking aloud.
u
hmm I dont hate that
pretty clever
but I'd need to somehow change the receiver of the entryprovider so paramless one is not available
e
In my former company, I also had a custom entry provider dsl but it was android only so no need for them to manually supply serializer, I just used reflection directly.
Yes I always recommend not to depend directly on the Nav3 apis
u
but that did you do with the serializer instance? was it just a marker for lint to pickup?
e
Or any libraries direct APIs, always have some redirection of your own (if you are working at the platform level for instance) because it may happen that you need to swap out the 3p library someday
> but that did you do with the serializer instance? was it just a marker for lint to pickup? No it went into my registry and saved state configuration. Its used for saving & restoring the keys during process death
u
i mean thats hard to do in partice here since your keys will extend
NavKey
e
Your keys do not have to extend NavKey
u
okay so the configuration thing was dynamic, constructed at runtime?
e
I answered the same in some other thread, not sure if in this slack or another
Yup.
u
pretty cleva!
e
I was going for pragmatic more than clever. There are other directions that I went with our platforms navigation that are different from Nav3 for instance (even though entire thing is still based on nav3)
u
btw what about resources, do you use
composeResources
?
e
I have but not in this app. Within a design system library. What is the relation to Nav3? 🤔
u
no relation, I'm actually exactly biulding a design lib and I want to impose CMP on it, even though the non android artifacts will not just yet be built/used the reasoning was just to constrain the devs, and supposedly it has 0 overhead on android
1
e
Yes your reasoning is correct. I did the same
u
but I'm now looking at the resources and does change it to objects and lazy bla bla, for hundreds of icons I feel like it will downgrade the runtime a bit (?)
e
Don't Personally I wouldn't use for icons. Just text & other files. If your company has design resources I would say create an icon font and use instead. Second best option would be what we did before that is to level
val Airplane by lazy { ImageVector.Builder(...).build() }
although this is only for simple icons. Anything complex (eg flags) should probably be loaded and cached (Coil) or via lottie (if animated)