Skip to main content

Splash Screen

KMPStarterKit ships a native launch screen on both Android and iOS — no third‑party library. Each platform uses its own built‑in mechanism, so the splash appears instantly at cold start before the Compose UI loads.

Android

Uses the official androidx.core:core-splashscreen API.

  • Theme Theme.App.Starting in androidApp/src/main/res/values/styles.xml.
  • The background is @color/windowBackgroundColorthe same as the app window — so the splash hands off to your UI with no color flash. The icon is the adaptive launcher icon @mipmap/ic_launcher. (The system masks the splash icon to a circle; adaptive icons are built for that, so it stays crisp and uncropped — a full-bleed brand logo would lose its corners. The native theme also can't reference Compose resources, only res/ ones.) Your brand logo (ic_logo) is shown uncropped by the in-app Compose splash (the onboarding loading screen).
  • Wired via android:theme="@style/Theme.App.Starting" on AppActivity, plus installSplashScreen() (before super.onCreate()) in App.android.kt. After launch, postSplashScreenTheme hands off to AppTheme.

To keep the splash on screen while the app finishes loading:

installSplashScreen().setKeepOnScreenCondition { !isReady }

iOS

Uses the declarative UILaunchScreen key in iosApp/iosApp/Info.plist (iOS 14+, no storyboard, no .xcodeproj changes).

iOS can't point a launch screen at the AppIcon set, so the splash logo is a single image you replace:

  • LogoiosApp/iosApp/Assets.xcassets/ic_logo.imageset/ — three files, ic_logo.png (1x), ic_logo@2x.png, ic_logo@3x.png
  • BackgroundiosApp/iosApp/Assets.xcassets/SplashBackground.colorset
Size the logo in points, not pixels

A launch image is drawn centred at its point size and is never scaled to fit the screen. The three scale slots are what stop pixels being read as points: the set ships at 120 pt (120 / 240 / 360 px), about a third of the width of a 390 pt iPhone.

Drop a 512 px logo into the 1x slot and iOS renders it at 512 pt, wider than any iPhone, so it overflows and gets clipped. Regenerate all three instead, and keep transparency so the logo works over the splash background in both light and dark mode:

cd iosApp/iosApp/Assets.xcassets/ic_logo.imageset
sips -Z 120 logo.png --out ic_logo.png
sips -Z 240 logo.png --out ic_logo@2x.png
sips -Z 360 logo.png --out ic_logo@3x.png

Leave Contents.json alone — it maps those filenames to the 1x / 2x / 3x slots.

The Info.plist keys reference those by name:

<key>UILaunchScreen</key>
<dict>
<key>UIColorName</key>
<string>SplashBackground</string>
<key>UIImageName</key>
<string>ic_logo</string>
<key>UIImageRespectsSafeAreaInsets</key>
<true/>
</dict>

Rebrand checklist

PlatformBackgroundLogo
AndroidwindowBackgroundColor (colors.xml) — same as the app window@mipmap/ic_launcher — the adaptive launcher icon (circle-masked)
iOSSplashBackground.colorsetic_logo.imageset/ — your brand logo at 120/240/360 px

Tip: keep the iOS SplashBackground color in sync with your Android windowBackgroundColor (the app window background) so both platforms look identical and transition seamlessly.

The brand logo shown right after the native splash (the in-app Compose splash, sign-in, and onboarding) is designsystem/.../composeResources/drawable/ic_logo.webp. Replace that one file to rebrand the in-app logo across all platforms. The iOS launch screen can't read Compose resources, so it needs its own copy in ic_logo.imageset/ — resized to the three scales above rather than copied across at full size.