# Android app size and lib\_FoundationICU.so

**URL:** <https://forums.swift.org/t/android-app-size-and-lib-foundationicu-so/78399>\
**Category:** Android\
**Tags:** android, icu\
**Created:** [March 9, 2025, 5:26pm UTC](https://forums.swift.org/t/android-app-size-and-lib-foundationicu-so/78399 "2025-03-09T17:26:02Z")\
**Posts on this page:** 1\
**Showing post:** 13

<div class="post-metadata">

**Author:** ![Finagolfin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/finagolfin/32/34388_2.png) [@Finagolfin](https://forums.swift.org/u/Finagolfin)\
**Post date:** [March 16, 2025, 1:02pm UTC](https://forums.swift.org/t/android-app-size-and-lib-foundationicu-so/78399/13 "2025-03-16T13:02:54Z")

</div>

> [@marcprux](#):
>
> Exclude i18n altogether: if code just imports `FoundationEssentials` and eschews `FoundationInternationalization`, then the APK size would be reduced drastically. This is the most obvious solution, but is also the most obvious one to dismiss out of hand: apps need support for localization.

In the general case, they do need localization, but what percentage of apps will stick localized strings or time/date lookups in their natively compiled Swift code? Probably not many. You may want to default to a build setting that disables `FoundationInternationalization` altogether, so those who don't need localization/calendars in Swift can benefit from excluding it.

> [@marcprux](#):
>
> Implement a `lib_FoundationICUAndroidNDK.so` replacement library that uses the existing `libicu.so`: aside from only being present in Android 12 (API 31) and higher (as per [ICU4C on Android](https://developer.android.com/guide/topics/resources/internationalization#icu4c)) and thereby only being available on ~45% of devices (as per Android Studio's API market share estimator), the Android [ICU4C NDK Reference](https://developer.android.com/ndk/reference/group/icu4c) shows that the API subset they expose is insufficient for the needs of `FoundationInternationalization`: it has none of the `udat_*`, `unum_*`, or `ucurr_*` needed for date/time formatting and parsing, nor any `ucal_*` calendar functions.

For those who need localization or other libicu-based APIs, this seems like your best bet to reduce app size due to native code. It would require figuring out exactly what APIs are in the most minimal official Android libicu, then only adding the missing "`udat_*`, `unum_*`, or `ucurr_*` needed for date/time formatting and parsing... any `ucal_*` calendar functions" plus `ualoc_*` back to your `lib_FoundationICUAndroidNDK.so`.

Only "~45% of devices" may have this system `libicu.so`, but [the Play store has required that app updates target API 33 or later for the last six months](https://developer.android.com/google/play/requirements/target-sdk). I don't know what type of backward compatibility they provide: have you looked to see if Play Services or some other system update also provides a `libicu.so` to older devices to keep such native code updates running?

> [@marcprux](#):
>
> However, this would require implementing support via JNI, and incurring a bridging trip for each any every localization call. I fear that the performance implications could be significant.

I suspect that very few apps are doing localization or time/calendar lookups on the hot path, so I doubt performance will matter. But yeah, manually writing this bridging code, even based on [JavaKit from swift-java](https://github.com/swiftlang/swift-java), is probably not worth it.

> [@marcprux](#):
>
> Could these be somehow compressed further? Or could a significant size reduction be realized by excluding some rare-but-large locales from that file? I haven't explored this option yet.

[This was discussed several years ago](https://forums.swift.org/t/icu-usage-in-swift/20473) and eventually led to [the work to bring Unicode tables into the stdlib and remove the libicu dependency there](https://github.com/swiftlang/swift/pull/40340). Unfortunately, this has not been done for Foundation, but there were some ideas discussed in that earlier thread.

> [@marcprux](#):
>
> But one immediate benefit is that the app would only need to contain one single instance of the data file, rather than repeating it N times for each supported architecture.

This seems like something you could immediately implement, ie have `lib_FoundationICU.so` load this data from a local file at first access rather than have it hard-coded in each arch-specific library. This would give you the biggest gain on Android for the least work and could likely be upstreamed back to Foundation, behind an optional build setting if nothing else.

> [@marcprux](#):
>
> this opens the possibility of performing some "thinning" of the ICU data to only include those locales that are supported by the containing app. This is what Flutter does to keep its bundled ICU data size as minimal as possible. This thinning could be done as a post-processing step by the packaging tool for the app.

Yep, once it is separated out, you could also add a tool for this.

---

_[View the full topic](https://forums.swift.org/t/android-app-size-and-lib-foundationicu-so/78399)._
