Hi, I saw one of the messages about the size of a ...
# multiplatform
g
Hi, I saw one of the messages about the size of a single-page app using KMP and Compose, which said it was 24MB. That makes sense since Skia is embedded inside the app. I migrated one of our modules and generated the SDK output using the framework approach — its size was 65MB, and the symbol file was 45MB. It only includes the arm64 architecture. I used the new Kotlin version with the binary small size flag, and the size became 40MB. The debug symbol file was reduced to 30MB. This module contains 15 pages and uses libraries like Kotlin Serialization, Ktor, Koin, DateTime, and Compose. I have a few questions: Is it reasonable for the final app size to reach 100MB? I’ve seen some iOS apps that are even 300MB. Are there still any ways to reduce the app size further? Are debug symbol files necessary for the final release version of the app? Or are they only useful for monitoring tools and can be excluded from the final store build?
1
a
Would you mind sharing, how are you measuring the resulted size? Just as a comparison, let me demonstrate kotlinconf.app , which requires 50MB (depending on the actual device you are targeting with the download). You can checkout the sources here - https://github.com/JetBrains/kotlinconf-app Also, I did a small writeup some time ago on some hints "how to measure stuff". Also there are some straightforward hints on how to minimize the resulted size. Long story short - the minimal library that uses Compose is compiled into somewhat around 3.6 MB.
g
I reviewed the links you shared — thank you! However, I haven’t used the App Thinning Size Report.txt yet to analyze the size. So far, I’ve only checked the release build size manually. I inspected the generated Kotlin module size from the
build/xcode-frameworks
folder, and also checked the final product installed on the simulator from the
Products
folder. According to Apple’s documentation and issue tracker, this might not be the correct way to measure the actual app size. Regarding the module I’m integrating with iOS — I didn’t use the term “export” specifically. But there is one key difference: My module links against a
.a
library (
libsodium
) and also includes a custom library I built via cross-compiling (C++ and Objective-C++), so I’m using the dynamic framework approach (
isStatic = false
) to handle this. The shared module is being linked dynamically. Could this use of dynamic linking be the reason for the increased size? Also, for some context, here’s how my module structure looks:
Copy code
iosApp -> shared -> cppModule
In
cppModule
, I have a Kotlin wrapper around native functions that I exported to Kotlin Native using
@CName
and
def
files. Both
shared
and
cppModule
have
linkerOpts
pointing to
.a
files, and both are configured with
isStatic = false
. I remember that when I tried setting them to
isStatic = true
, I encountered runtime errors. Is there any way to fix this so I can use static linking and potentially reduce the final size?
@Artem Olkov
I also looked into how the Sentry library approached this for multiplatform. What they did was create a Kotlin KMP module that wraps around Objective-C code. However, for the consuming
shared
module, they had two options: 1. Using Swift Package Manager (SPM): 2. The iOS app would dynamically load the binaries, and SPM would fetch the prebuilt
.a
Objective-C Sentry binaries (via CocoaPods integration). 3. Using CocoaPods directly inside the
shared
module
: 4. This allowed the shared module to download the
.a
files at build time and handle the linking internally.
a
Is there any way to fix this so I can use static linking and potentially reduce the final size?
Please open a youtrack ticket with a reproducer for that case(static library compilation with CExport produces runtime errors), so that the team could investigate properly 🙂
g
Thanks