Just want to check if someone else did this before...
# compose
j
Just want to check if someone else did this before. But I am thinking about having two iOSApp and two AndroidApp refer to same shared CMP Gradle modules in same repo. Like core modules and such. However gets complicated with things like navigation and such. No issue with things like design system. It quickly becomes messy it feels like. Any ideas how to approach this? Most of the things will be same, and want to share as much things as possible can.
s
I haven't done iOS, but having JVM, Android, and JS use the same Compose module is fine. I quickly dropped JS because it was awful, but it worked. If you use something like Decompose, you can share your navigation between the apps that have similar navigation. It doesn't feel messy at all. In my case, I have about 10 source files with actual/expect implementations/definitions in each source set.
j
Feels like we talk about different things. I have multiple targets like Desktop, Wasm etc as well. However want two different apps sharing same common modules. Sharing same navigation then one app would be able to use same navigation screens that the other app having, causing major bugs, that I want to avoid šŸ™‚
In my case app A is user app, and app B is admin app. Dont want to mix everything, such as authentection logic and screen can navigate to šŸ™‚
But both apps is multiplatform šŸ™‚
s
Are they built from the same project?
j
Thats what I am thinking about, how to have them inside same repo but different apps šŸ™‚ I mean no issue having androidApp1 androidApp2, iosApp1 iosApp2 in same folder structure and do include them in settings.build.gradle etc. But the main issue becomes how to decide which features that should be shared vs not.
I think I would need much more granular modules, like one module for core:formatting, one for core:firebase, core:navigation1 etc where each app shared module need to declare a component cherry pick and setup configs for each system. Like this component allowed to navigate to these screens or such.
Like in my case I am using library Circuit, it has interface Screen so I can use same navigation host container, but I cannot use same subset class. And for each screen how declare the flows. I dont currently check if screen navigate to is a screen I am allowed to navigate to, I expect all classes using same screen specification inside my core module, being part of the same app šŸ™‚
s
Seems like you have a pretty good grasp on it.
c
I’ve had some experience with this over the years in standard Android apps, and more recently trying to make this work in a Compose Multiplatform app. It’s really difficult to actually achieve this and still keep things clean, and you’ll end up with conditional logic all over the place, and find it difficult to keep features as separate as you want to. If you’re building a true ā€œwhite-labelā€ app, it’s not bad, but as soon as you start needing different features between the apps, things break down quickly. But does that mean you shouldn’t do it, and just maintain two different apps? I’m honestly not sure about that yet. Depending on how similar or different the apps are, you might find it easier to just maintain two separate codebases, or find ways to keep the apps’ features similar enough to make one codebase work
j
Copy code
Seems like you have a pretty good grasp on it.
I wouldnt say that, as so much questions how to split modules into smaller quantified things I can share. Like design system components is very isolated and state less and hence easy to re-use. But things like formatting, navigation, fetch data and such can differ a lot between apps, even if most things should be same šŸ™‚
Another idea I have is making hybride code, where you can login as admin into the same app, but feels like security issues šŸ˜„
if user.role == admin, show this UI šŸ˜„
@Casey Brooks Yeah plus one on that, especially the tooling, publish modules and such in larger companies šŸ˜› My app in this case is quite small relative speaking. But I would think there should be more things except design systems and navigation things that can be shared thats very agnostic from app context šŸ™‚ However isolating things, so cannot use things by mistake or start sharing like authentication storage implementation isntead of the interface of it, can be very tricky šŸ˜›
c
The challenge is that you try to think of the app in terms of ā€œgeneric core modulesā€ and ā€œapp specific modulesā€, and use DI and configuration files to wire up the app-specific stuff to help the core modules. But those configurations and DI graphs are difficult to understand and require a lot of boilerplate, and ultimately things are never quite so clean and separated in the code as you expect in your mind. I think where I’m landing is that the stuff that is truly shared is relatively little, and the cost of trying to share is is higher than the cost of maintaining duplicated code across 2 apps;
j
Another problem I realize is how I should split Res class from CMP resources plugin šŸ˜„ As I would need to be using two different shared modules, but those shared modules can have core modules both re-using between each other, but different DI and component setup. Also if the effort is always moving things across Gradle modules just to isolate all the time, feels like wasting time try sharing code. Instead just treat the apps different and copy paste design system and such between šŸ˜„ This also touching topic of why using multiplatform to begin with, what can I share between all platforms/targets šŸ˜„
c
KMP makes sense because the apps’ features are the same, so you can safely share all the logic across the different targets and make a lot of assumptions in the shared code about how it will be used. Things are different when you’re talking about different apps, because the logic and features aren’t going to be the same on each.
j
Also its interesting when scaling these things, sometimes as you say it can be worth duplicating code, as not should be same anyway. However I think design system should be same in a company, so that is the thing I am thinking about is the main module to share. As I want the admin vs user app should look exactly the same šŸ˜› So could be worth creating a Github repo or such only for the design system maybe, to avoid the hussle of pinpoint relative directories in Gradle config šŸ˜„
The logic and features nope, not same, but mostly same in my case from database level, like same pojos how data looks like from admin vs user side of things. Or how to format dates/time šŸ™‚
Also having a lot of utils for like Coroutines and such I would like to share, or my common VIewmodel solution šŸ˜›
Another issue I realize is, that I would like to have admin app target desktop, but user app target iOS + Android. Then it will not work, as I need to implement desktopMain everywhere, even if not used šŸ˜„
z
I may be simplifying your case a bit, but wouldnt you get most of the way there by simply pulling out libraries for what you intend to and can share, then setting up the different apps using them? Similar to what you (I think) are doing with the design system already, although probably more challenging with regards to how things may or may not overlap between the apps. Its much harder than what Im doing with frontend & backend sharing the same multiplatform code, but I think the same principles can apply.
j
Yeah design system feels no brainer. But feels bad if I cant share more 😁 I am almost leaning to have just a separate admin page if user has admin role. To avoid maintain another app. If I change my mind probably easy if do admin as feature module.
šŸ‘šŸ½ 1