Does anyone know whether there's any work being do...
# webassembly
t
Does anyone know whether there's any work being done on using wasm as a library within a kotlin project? The use case that we have is that we currently have to support multiple platforms (Android,iOS,Web) and that we'd like to reduce the duplication that we currently have in our business logic. Ideally we'd like to write this logic in a language which supports targeting wasm (e.g. Rust, Swift or even Kotlin), generate bindings from it for all our target platforms and then call them from our host in Kotlin/Swift/JavaScript.
🧵 1
From what I understand this would require having a wasm runtime for each of these platforms and generating glue code based on the specification (e.g. WIT files) which wraps calls to the runtime in a type-safe manner.
Alternatively, Rust for example allows generating either JavaScript bindings using wasm-bindgen or Kotlin and Swift bindings for native code using uniffi, but I don't think all three is currently viable
And we'd miss the benefits of safety, sandboxing and determinism that wasm/wasi would provide
d
Are you asking to HOST the WASM in the JVM process (or alternative native platform) ? This means your WASM binary blob is consumed at runtime by your application ? Isn't this a matter for the individual native platform to provide information on how to run a WASM binary blob inside another native platform application. Does the Apple platform allow this to occur, outside of their controlled Safari/browser use case ? are not 3rd party binaries they can not inspect against the platform terms ? But for the other platforms I'm sure WASM hosting and consuming is on the way, there may even be an initiative to provide a common IDL (interface definition language) to describe the blobs external interfaces with metadata
r
I think JB is doing this with skiko in compose multiplatform. There is static
skiko.wasm
library and it's somehow used by the kotlin project on the js and wasm target. You could probably check compose sources to find out how it works.
👍 1
t
That is correct Darryl. There might be other/better approaches to the problem, but how I currently see it I'd like to have the host (e.g. the JVM process on Android) to make calls into the wasm blob using some runtime, whether that be system provided or bundled in the application. The part about Apple I'm not sure about but that would definitely be important to check out. I was kind of assuming that running wasm blobs would be fine as long as the runtime itself only interprets instead of using a JIT compiler (not that we have this choice), given that native libraries are also allowed (which are binary blobs as well). Is the part about the common IDL a reference to the WASI spec's component model or is this something else? If you have any references which indicate that e.g. Android is experimenting with this approach I'd love to read more about it.
d
I'm slightly confused by the description of the requirements: reducing duplication in business logic is exactly what Kotlin Multiplatform is for. Are you saying you're wanting to use Kotlin/WASM only, then integrate its binary output with a multiplatform approach that falls outside of the Kotlin Ecosystem? Or put another way; is there any reason you can't solve the whole problem using Kotlin Multiplatform on each target? Then the pieces should fall together far more easily.
t
Good that you mention it, but I'm under the assumption that KMP for web currently requires you to create your UI in Compose Multiplatform. We already have working clients written in each platform's respective native language/frameworks and we'd like to keep it that way. Using wasm would ideally allow us to keep all our client code as is, except that we could replace a lot of the code that is now duplicated between the clients with a single WASM blob for all of them. Additionally, and I'm not sure if this assumption is correct, I think migrating to KMP would require us to move the code for all our different platforms into a single monorepo managed by KMP and force us to use an Intellij-based editor for all our clients. We'd especially like to avoid the monorepo part.
d
Happily, it's an incorrect assumption that you'd need to use Compose Multiplatform for the View layer. KMP is a language feature distinct from any library, and you can share as much or as little code as you like by compiling for multiple targets. In your case, it sounds like you want to share all the business logic, where that includes at least some of the presentation logic.
What UI architecture or pattern are you following, do you have ViewModels or a MVI/Reducer going on?
t
We don't necessarily need presentation logic in the shared library (i.e. sharing just the API calls and response models would be a decent start) although that might be something we'd want to work towards at some point. As for the architectures, these vary quite a bit from platform to platform and not all platforms have a nice distinction between view and business logic. Our tech stack includes view/compose for Android, view for AndroidTV, UiKit for iOS and tvOS, Angular for web and a canvas renderer for smart TVs. If KMP allows us to generate some kind of library which we can easily consume from our clients (preferably with bindings for each language) without having to change IDEs or changing our project structures too much then that would be a good solution for us as well. Best case we'd be able to generate a node module, a kotlin/java jar and a swift library from this shared library without the clients necessarily having to know that the library is not "native" for their platform.
d
Sounds like you're best off starting small with a single unit of common business logic, just to exercise the build mechanics. Define a Kotlin Multiplatform Library project with 3 or 4 targets for each of: • Android (serving both Mobile and TV), will produce
.aar
file • iOS (Again, serving both Mobile and TV) will produce a standard iOS
.framework
containing a dylib • Kotlin/JS - for the web and web-based smart TV - presumably this TV target won't ever get a WASM runtime? Will produce
.js
files / node module. • Kotlin/WASM for more future-facing web? Will produce
.wasm
file
See, KMP compiles multiple times - once for each target platform; rather than producing a single thing you then have to go to unreasonable lengths to consume on each platform (like the original idea of having a WASM runtime in each place). Does that clear anything up?
t
Yes, that does clear things up, thank you! I did not realize that KMP would compile separate artifacts per platform. I'll have to look into trying a simple PoC but this sounds promising!