Hey folks, does anyone know of a decent guide on h...
# multiplatform
a
Hey folks, does anyone know of a decent guide on how to write JVM-only Kotlin code in a way that eventually is conducive to porting into Multiplatform? I feel like there’s a few big-picture things like: • Use Kotlin stdlib instead of Java wherever possible (e.g. Collections), and • Use KMP-friendly libraries instead of JVM-only ones wherever possible (e.g.,
kotlinx.serialization
vs Jackson/Moshi,
kotlinx.coroutines
vs RxJava) But I also feel like there are some slightly more advanced topics like increasing modularization to isolate code that’s already platform agnostic (or close to it) into a separate Gradle module so you can start KMP-ifying it without doing something like fully migrating off of RxJava if you’re using it I feel like I have an intuitive sense for most of this, but am looking for something to send over to some coworkers who’re working on backend services where they eventually want some parts to be able to run client-side via KMP
c
My approach is to start with. KMP project with a JVM target. That will give you a clear idea of what is JVM specific vs not. You can start by adding things like your models and maybe some algorithms in the common code while leaving other areas in the JVM sourceset.
💯 1
4
If you dont want to use KMP to start with, modularization is another great approach. At the end of the day, what you are looking for is a way to determine what has dependencies on JVM-specific code vs not. Breaking up your codebase into modules would also allow you break up some dependencies so when you migrate to KMP you can do it on a gradual basis.
y
Not an expert - but maybe also understanding the bigger platform differences. Like I keep getting reminded by others you just can't have blocking methods in JS, it's not just a performance code smell. Or charsets.
Understanding which fundamental libraries will differ and need to be extracted (image editing would be the one that springs to mind).
m
While structural patterns for example coroutines can be nasty while converting a project into KMP, other stuff is more or less easy to catch - for example I would recommend use only KMP friendly mocking libs while writing tests or use no lib at all and write them by hand...more importantly you should write tests...while keeping the code decoupled as much as possible. The rest should follow then like dependency injection/delegation and so on. I gone through that topic 3-times now and tight coupling was always the biggest trouble caused so much pain. In terms of coroutines - same here - write tests. Most of all write a couple of meaning full integration tests. They will help you to spot freezing errors for example (even if the new MM will hopefully prevent that from happening when it is production ready).
d
Agree with @CRamsan: Develop as a KMP project with only a JVM target, starting today! This is a low-effort configuration change in your project and will keep you on track.
x
Start your project multiplatform-ready and then gradually introduce new platforms as you find the need
1
g
Unfortunately with only JVM target, IDEA will continue to offer completion with JVM stuff, and even if it's red in the IDE it will compile and run fine. I had to add another target on my KMP project to understand that
runBlocking
from coroutines was actually JVM only, I thought it was just an IDE issue for weeks. I've the feeling that adding another target just to run the common tests is another option that forces to learn those little multiplatform things. OR maybe there is some lint rules that can block misusage and fail the build?
t
I agree with all the folks here saying do KMP with only JVM target!
Also, expect some architectural change when you add that second platform. It’s just bound to happen in some way. Don’t expect the porting cost to be zero. If you expect there to be porting cost, and then there isn’t any great! Definitely a place to underpromise (underexpect) and overdeliver (let KMP surprise you)
For something more specific, since you mentioned your plans to take backend code and run it on the frontend, I would recommend focusing on separation of IO and Business Logic. DDD or Hexagonal Architecture may help but they could also steer you down the wrong path. Backend and frontend will have separate code for creating these business objects. Mostly because I expect backend to get the data from a lower-level data access than the frontend. But they can share the code that runs the business logic from there.