Skip to main content

How to Configure App Icons and Splash Screens in React Native

· 9 min read
Mobile Developer
Last updated on August 14, 2025

configuring app icons

App icons and splash screens are essential for branding and user experience in React Native applications. The app icon represents your app on a user’s device, while the splash screen ensures a polished loading experience during startup. This guide provides a step-by-step process to configure app icons and splash screens for iOS and Android using Expo SDK 51 and [email protected], compatible with React Native 0.75.4 (July 2025). It assumes basic knowledge of JavaScript and React Native, with no prior native configuration experience required.

For prebuilt solutions, explore templates at Instamobile or Dopebase.

By the end, you’ll have a React Native app with a custom app icon and splash screen, optimized for development, staging, and production environments on both platforms.


Prerequisites

Before starting, ensure you have the following installed:

  • Node.js (v20.x or later, LTS recommended): Download from nodejs.org.
  • npm (v10.x or later, included with Node.js).
  • Expo CLI: For streamlined React Native project setup.
  • Android Studio (2024.3.2 or later): For Android development, with Android SDK 35 and NDK r25+.
  • Xcode (16+): For iOS development (macOS only). iOS builds require Xcode 16+ (iOS 18 SDK) to comply with App Store submission requirements after April 24, 2025.
  • A code editor like VS Code.
  • Git: For cloning repositories or managing code.
  • A 1024x1024 PNG image for the app icon and a 2000x2000 PNG image for the splash screen (transparent background recommended).

Step 1: Set Up the React Native Project

  1. Install Expo CLI globally to simplify React Native development:

    npm install -g expo-cli
  2. Create a new project called MyApp:

    expo init MyApp

    Select the blank (TypeScript) template for a type-safe setup. Expo SDK 51 supports React Native 0.75.4 (July 2025) with the New Architecture enabled.

  3. Navigate to the project directory:

    cd MyApp
  4. Install react-native-bootsplash for splash screen management:

    npm install [email protected]
  5. Update app.json to exclude incompatible dependencies:

    {
    "expo": {
    "install": {
    "exclude": ["react-native-reanimated@~3.10.0"]
    }
    }
    }

Summary: This step sets up a new React Native project with Expo SDK 51 and installs react-native-bootsplash for splash screen configuration.


Mega Bundle Sale is ON! Get ALL of our React Native codebases at 90% OFF discount 🔥

Get the Mega Bundle

Step 2: Configure the App Icon

App icons must be 1024x1024 PNG images without rounded corners or transparency, as the operating system applies masking. Expo CLI and EAS Build simplify icon generation, but manual steps are provided for bare workflows.

iOS Configuration

  1. Create a 1024x1024 PNG icon using tools like App Icon Generator. Save it as icon.png in assets/images. Optionally, create dark mode variants (icon-dark.png).
  2. Update app.json to specify the icon:
    {
    "expo": {
    "icon": ".https://docs.instamobile.io/assets/images/icon.png",
    "ios": {
    "icon": {
    "any": ".https://docs.instamobile.io/assets/images/icon.png",
    "dark": ".https://docs.instamobile.io/assets/images/icon-dark.png"
    }
    }
    }
    }
    EAS Build generates all required icon sizes (e.g., 180x180, 120x120).
  3. For bare workflows, open ios/MyApp.xcworkspace in Xcode, navigate to Images.xcassets > AppIcon, and drag icon.png into the appropriate slots.

Android Configuration

  1. Use the same 1024x1024 PNG icon, optionally creating adaptive icon layers (foreground and background) in Android Studio’s Image Asset Studio.
  2. Update app.json:
    {
    "expo": {
    "icon": ".https://docs.instamobile.io/assets/images/icon.png",
    "android": {
    "adaptiveIcon": {
    "foregroundImage": ".https://docs.instamobile.io/assets/images/icon-foreground.png",
    "backgroundColor": "#ffffff"
    }
    }
    }
    }
    EAS Build generates all required sizes (e.g., mipmap-mdpi, mipmap-xhdpi).
  3. For bare workflows, copy icons to android/app/src/main/res/mipmap-* folders and update android/app/src/main/AndroidManifest.xml:
    <application
    android:icon="@mipmap/ic_launcher"
    android:roundIcon="@mipmap/ic_launcher_round">

Summary: App icons are configured in app.json for Expo-managed projects or manually in Xcode and Android resource folders for bare workflows, ensuring platform-specific compatibility.


Step 3: Configure the Splash Screen

Splash screens display during app startup and should feature a centered logo on a solid background for fast loading. The react-native-bootsplash library provides robust control for both platforms.

Prepare the Splash Screen Image

Create a 2000x2000 PNG image with a transparent background, ensuring no critical elements are near the edges to account for safe areas. Save it as splash-icon.png in assets/images. Use tools like Figma for design consistency.

iOS Configuration

  1. Generate splash screen assets:
    npx react-native generate-bootsplash assets/images/splash-icon.png \
    --platforms=ios \
    --background=#ffffff \
    --logo-width=200
    This creates BootSplash.storyboard and assets in ios/MyApp/Images.xcassets.
  2. Update app.json:
    {
    "expo": {
    "splash": {
    "image": ".https://docs.instamobile.io/assets/images/splash-icon.png",
    "backgroundColor": "#ffffff",
    "resizeMode": "contain",
    "dark": {
    "image": ".https://docs.instamobile.io/assets/images/splash-icon-dark.png",
    "backgroundColor": "#000000"
    }
    }
    }
    }
  3. For bare workflows, open BootSplash.storyboard in Xcode, add an ImageView with splash-icon from Images.xcassets, set Content Mode to Aspect Fit, and center it using constraints. Update Info.plist to set UILaunchStoryboardName to BootSplash.
  4. Update ios/MyApp/AppDelegate.mm to initialize the splash screen:
    #import "AppDelegate.h"
    #import <React/RCTBundleURLProvider.h>
    #import <React/RCTRootView.h>
    #import "RNSplashScreen.h"

    @implementation AppDelegate

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
    RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"MyApp" initialProperties:nil];
    rootView.backgroundColor = [UIColor whiteColor];
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    UIViewController *rootViewController = [UIViewController new];
    rootViewController.view = rootView;
    self.window.rootViewController = rootViewController;
    [self.window makeKeyAndVisible];
    [RNSplashScreen show];
    return YES;
    }
    @end

Android Configuration

  1. Generate splash screen assets:
    npx react-native generate-bootsplash assets/images/splash-icon.png \
    --platforms=android \
    --background=#ffffff \
    --logo-width=200
    This generates assets in android/app/src/main/res/drawable and a BootSplash theme.
  2. Update android/app/src/main/res/layout/launch_screen.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:src="@drawable/bootsplash_logo"
    android:scaleType="centerCrop" />
    </RelativeLayout>
  3. Update android/app/src/main/AndroidManifest.xml:
    <manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application
    android:name=".MainApplication"
    android:label="@string/app_name"
    android:icon="@mipmap/ic_launcher"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:allowBackup="false"
    android:theme="@style/AppTheme">
    <activity
    android:name=".SplashActivity"
    android:theme="@style/BootTheme"
    android:label="@string/app_name">
    <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    </activity>
    <activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
    android:windowSoftInputMode="adjustResize"
    android:exported="true" />
    </application>
    </manifest>
  4. Update android/app/src/main/java/com/myapp/MainActivity.java:
    package com.myapp;
    import com.facebook.react.ReactActivity;
    import android.os.Bundle;
    import com.zoontek.rnbootsplash.RNBootSplash;

    public class MainActivity extends ReactActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    RNBootSplash.init(this, R.style.BootTheme);
    super.onCreate(savedInstanceState);
    }
    }

Hide Splash Screen

Update src/App.tsx to hide the splash screen after loading:

import { useEffect } from 'react';
import { View, Text } from 'react-native';
import SplashScreen from 'react-native-bootsplash';

export default function App() {
useEffect(() => {
const init = async () => {
await new Promise(resolve => setTimeout(resolve, 2000)); // Simulate loading
await SplashScreen.hide({ fade: true });
};
init();
}, []);

return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Welcome to MyApp!</Text>
</View>
);
}

Summary: Splash screens are configured using react-native-bootsplash and app.json for Expo, or manually with storyboards and layouts for bare workflows, ensuring a smooth startup experience.


Step 4: Configure Staging and Production Environments

To distinguish staging and production builds, use unique icons and splash screens for each environment.

  1. Update app.config.ts for dynamic configuration:

    import { ConfigContext, ExpoConfig } from 'expo/config';

    export default ({ config }: ConfigContext): ExpoConfig => ({
    ...config,
    name: process.env.APP_ENV === 'staging' ? 'MyApp Staging' : 'MyApp',
    icon: process.env.APP_ENV === 'staging' ? '.https://docs.instamobile.io/assets/images/icon-staging.png' : '.https://docs.instamobile.io/assets/images/icon.png',
    splash: {
    image: process.env.APP_ENV === 'staging' ? '.https://docs.instamobile.io/assets/images/splash-icon-staging.png' : '.https://docs.instamobile.io/assets/images/splash-icon.png',
    backgroundColor: '#ffffff',
    resizeMode: 'contain',
    },
    });
  2. iOS Configuration:

    • In Xcode, duplicate the app target (MyAppMyApp-Staging).
    • Create separate Images.xcassets folders for each target (e.g., Images-Staging.xcassets).
    • Add unique icons and splash images for each environment.
    • Update Info.plist for each target to reference the correct BootSplash storyboard.
  3. Android Configuration:

    • In android/app/build.gradle, define product flavors:
      android {
      flavorDimensions "default"
      productFlavors {
      staging {
      dimension "default"
      applicationIdSuffix ".staging"
      resValue "string", "app_name", "MyApp Staging"
      }
      production {
      dimension "default"
      resValue "string", "app_name", "MyApp"
      }
      }
      }
    • Create separate resource folders (e.g., android/app/src/staging/res/drawable, android/app/src/production/res/drawable) with unique icons and splash images.

Summary: Environment-specific icons and splash screens are configured using app.config.ts for Expo or separate targets/flavors for bare workflows, enabling clear differentiation between staging and production.


Step 5: Build and Test

  1. Generate native projects:

    npx expo prebuild
  2. Build for iOS:

    npx expo run:ios
  3. Build for Android:

    npx expo run:android

    Use preview or production builds to test splash screens, as Expo Go may override custom configurations.

  4. Test staging vs. production:

    • For iOS, select the MyApp-Staging target in Xcode.
    • For Android, run gradlew assembleStagingDebug or assembleProductionRelease.
    • Verify that the correct icons and splash screens appear for each environment.

Summary: Build and test the app to ensure icons and splash screens display correctly across platforms and environments, using EAS Build for Expo or native tools for bare workflows.


Step 6: Enhance and Optimize

  • Use expo-dynamic-app-icon to change icons programmatically for testing or branding.
  • Integrate expo-custom-assets for animated splash screens, as detailed in Expo’s 2025 documentation.
  • Optimize splash screen duration by preloading assets (e.g., fonts, APIs) in App.tsx.
  • Ensure icons are simple and splash screens are minimal to avoid visual clutter. Test on multiple devices for proper scaling.

Summary: Enhance the app with dynamic icons, animations, and optimized loading to improve user experience and maintainability.


Troubleshooting Tips

  • iOS Caching Issues: Clear derived data (rm -rf ~/Library/Developer/Xcode/DerivedData) if icons or splash screens don’t update.
  • Android Scaling Issues: Use centerCrop or centerInside in launch_screen.xml to prevent distortion across devices.
  • Library Linking: Run npx pod-install for iOS or sync Gradle for Android if react-native-bootsplash fails.
  • Expo Build Issues: Ensure app.json or app.config.ts is correctly formatted and EAS Build is configured.

Looking for a custom mobile application?

Our team of expert mobile developers can help you build a custom mobile app that meets your specific needs.

Get in Touch

Conclusion

You’ve configured app icons and splash screens for a React Native app using Expo SDK 51 and [email protected], ensuring compatibility with React Native 0.75.4 (July 2025). The setup supports iOS 18 SDK (Xcode 16+) and Android SDK 35, with distinct configurations for staging and production environments. For faster development, explore prebuilt templates at Instamobile or Dopebase, which include production-ready icon and splash screen setups. Refer to Expo’s documentation and react-native-bootsplash for advanced features like animations.

Additional Resources