/react-native-bootsplash

🚀 Show a bootsplash during app startup. Hide it when you are ready.

Primary LanguageJavaMIT LicenseMIT

🚀 react-native-bootsplash

npm version npm Platform - Android and iOS MIT styled with prettier

Show a bootsplash during app startup. Hide it when you are ready.

iOS demo android demo

Support

version react-native version
3.0.0+ 0.63.0+
2.0.0+ 0.60.0+

For 0.59-, you should use jetify -r

Installation

$ npm install --save react-native-bootsplash
# --- or ---
$ yarn add react-native-bootsplash

Don't forget going into the ios directory to execute a pod install.

🆘 Manual linking

Because this package targets React Native 0.60.0+, you will probably don't need to link it manually. Otherwise if it's not the case, follow this additional instructions:

👀 See manual linking instructions

iOS

Add this line to your ios/Podfile file, then run pod install.

target 'YourAwesomeProject' do
  #
  pod 'RNBootSplash', :path => '../node_modules/react-native-bootsplash'
end

Android

  1. Add the following lines to android/settings.gradle:
include ':react-native-bootsplash'
project(':react-native-bootsplash').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-bootsplash/android')
  1. Add the implementation line to the dependencies in android/app/build.gradle:
dependencies {
  // ...
  implementation project(':react-native-bootsplash')
}
  1. Add the import and link the package in MainApplication.java:
import com.zoontek.rnbootsplash.RNBootSplashPackage; // <- add the RNBootSplashPackage import

public class MainApplication extends Application implements ReactApplication {

  // …

  @Override
  protected List<ReactPackage> getPackages() {
    @SuppressWarnings("UnnecessaryLocalVariable")
    List<ReactPackage> packages = new PackageList(this).getPackages();
    // …
    packages.add(new RNBootSplashPackage());
    return packages;
  }

  // …
}

Setup

Assets generation

In order to speed up the setup, we provide a CLI to generate assets, create the Android Drawable XML file and the iOS Storyboard file automatically ✨.

$ npx react-native generate-bootsplash --help
# --- or ---
$ yarn react-native generate-bootsplash --help

The command can take multiple arguments:

react-native generate-bootsplash <logoPath>

Generate a launch screen using an original logo file

Options:
  --background-color <color>  color used as launch screen background (in hexadecimal format) (default: "#fff")
  --logo-width <width>        logo width at @1x (in dp - we recommand approximately ~100) (default: 100)
  --assets-path [path]        path to your static assets directory (useful to require the logo file in JS)
  -h, --help                  output usage information

Full command usage example

yarn react-native generate-bootsplash assets/bootsplash_logo_original.png \
  --background-color=F5FCFF \
  --logo-width=100 \
  --assets-path=assets

This tool relies on the naming conventions that are used in the /example project and will therefore create the following files:

android/app/src/main/res/drawable/bootsplash.xml
android/app/src/main/res/values/colors.xml (creation and edition)
android/app/src/main/res/mipmap-hdpi/bootsplash_logo.png
android/app/src/main/res/mipmap-mdpi/bootsplash_logo.png
android/app/src/main/res/mipmap-xhdpi/bootsplash_logo.png
android/app/src/main/res/mipmap-xxhdpi/bootsplash_logo.png
android/app/src/main/res/mipmap-xxxhdpi/bootsplash_logo.png

ios/YourProjectName/BootSplash.storyboard
ios/YourProjectName/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo.png
ios/YourProjectName/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo@2x.png
ios/YourProjectName/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo@3x.png

# Only if --assets-path was specified
assets/bootsplash_logo.png
assets/bootsplash_logo@1,5x.png
assets/bootsplash_logo@2x.png
assets/bootsplash_logo@3x.png
assets/bootsplash_logo@4x.png

iOS

⚠️ Only .storyboard files are supported (Apple will deprecate other methods in April 2020).

Edit the ios/YourProjectName/AppDelegate.m file:

#import "AppDelegate.h"

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>

#import "RNBootSplash.h" // <- add the header import

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  //
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];

  [RNBootSplash initWithStoryboard:@"BootSplash" rootView:rootView]; // <- initialization using the storyboard file name

  return YES;
}

Set the BootSplash.storyboard as launch screen file:

Drag and drop the file Create folder reference Set as Launch Screen File

Android

  1. Edit the android/app/src/main/java/com/yourprojectname/MainActivity.java file:
import android.os.Bundle; // <- add this necessary import

import com.facebook.react.ReactActivity;
import com.zoontek.rnbootsplash.RNBootSplash; // <- add this necessary import

public class MainActivity extends ReactActivity {

  // …

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    RNBootSplash.init(R.drawable.bootsplash, MainActivity.this); // <- display the generated bootsplash.xml drawable over our MainActivity
  }

As Android will not create our main activity before launching the app, we need to display a different activity at start, then switch to our main one.

  1. Edit the android/app/src/main/res/values/styles.xml file:
<resources>

  <!-- Base application theme -->
  <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Your base theme customization -->
  </style>

  <!-- Add the following lines (BootTheme should inherit from AppTheme) -->
  <style name="BootTheme" parent="AppTheme">
    <!-- set the generated bootsplash.xml drawable as activity background -->
    <item name="android:background">@drawable/bootsplash</item>
  </style>

</resources>
  1. Edit the android/app/src/main/AndroidManifest.xml file:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.rnbootsplashexample">

  <!---->

  <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=".MainActivity"
      android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
      android:label="@string/app_name"
      android:windowSoftInputMode="adjustResize"
      android:exported="true"
      android:launchMode="singleTask">
      <!-- ⚠️ add android:exported="true" and android:launchMode="singleTask" above -->
      <!-- remove the <intent-filter> from .MainActivity -->
    </activity>

    <!-- add the following lines (use the theme you created at step 2) -->
    <activity
      android:name="com.zoontek.rnbootsplash.RNBootSplashActivity"
      android:theme="@style/BootTheme"
      android:launchMode="singleTask">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>

    <!---->

  </application>

</manifest>

API

hide()

Method type

type hide = (config?: { fade?: boolean }) => Promise<void>;

Usage

import RNBootSplash from "react-native-bootsplash";

RNBootSplash.hide(); // immediate
RNBootSplash.hide({ fade: true }); // fade

show()

Method type

type show = (config?: { fade?: boolean }) => Promise<void>;

Usage

import RNBootSplash from "react-native-bootsplash";

RNBootSplash.show(); // immediate
RNBootSplash.show({ fade: true }); // fade

getVisibilityStatus()

Method type

type VisibilityStatus = "visible" | "hidden" | "transitioning";
type getVisibilityStatus = () => Promise<VisibilityStatus>;

Usage

import RNBootSplash from "react-native-bootsplash";

RNBootSplash.getVisibilityStatus().then((status) => console.log(status));

Real world example

import React, { useEffect } from "react";
import { Text } from "react-native";
import RNBootSplash from "react-native-bootsplash";

function App() {
  useEffect(() => {
    const init = async () => {
      // …do multiple sync or async tasks
    };

    init().finally(async () => {
      await RNBootSplash.hide({ fade: true });
      console.log("Bootsplash has been hidden successfully");
    });
  }, []);

  return <Text>My awesome app</Text>;
}

🤙 A more complex example is available in the /example folder.

Guides

Handle deep linking (on Android)

If you want to correctly handle deep linking with this package, you should edit the android/app/src/main/AndroidManifest.xml file like this:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.rnbootsplashexample">

  <!---->

  <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=".MainActivity"
      android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
      android:label="@string/app_name"
      android:windowSoftInputMode="adjustResize"
      android:exported="true"
      android:launchMode="singleTask">
      <!-- ⚠️ add android:exported="true" and android:launchMode="singleTask" above -->
      <!-- remove the <intent-filter> from .MainActivity -->
    </activity>

    <activity
      android:name="com.zoontek.rnbootsplash.RNBootSplashActivity"
      android:theme="@style/BootTheme"
      android:launchMode="singleTask">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>

      <!-- add your deep linking instructions inside the RNBootSplashActivity declaration -->
      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="YOUR APP SCHEME" /> <!-- replace this with your custom scheme -->
      </intent-filter>
    </activity>

    <!---->

  </application>

</manifest>

Testing with Jest

Testing code which uses this library required some setup since we need to mock the native methods.

To add the mocks, create a file jest/setup.js (or any other file name) containing the following code:

jest.mock("react-native-bootsplash", () => {
  return {
    hide: jest.fn().mockResolvedValueOnce(),
    show: jest.fn().mockResolvedValueOnce(),
    getVisibilityStatus: jest.fn().mockResolvedValue("hidden"),
  };
});

After that, we need to add the setup file in the jest config. You can add it under setupFiles option in your jest config file:

{
  "setupFiles": ["<rootDir>/jest/setup.js"]
}

🕵️‍♂️ Comparison with react-native-splash-screen

  • If react-native-splash-screen encourages you to display an image over your application, react-native-bootsplash way-to-go is to design your launch screen using platforms tools (Xcode layout editor and Android drawable resource).

  • It should not prevent you from seeing red screen errors.

  • Hiding the launch screen is configurable: fade it out or hide it without any animation at all (no fade needed if you want to animate it out!).