react-native-bootsplash icon indicating copy to clipboard operation
react-native-bootsplash copied to clipboard

Double Splash Image

Open objectiveSee opened this issue 5 months ago • 6 comments
trafficstars

Before submitting a new issue

  • [x] I tested using the latest version of the library, as the bug might be already fixed.
  • [x] I tested using a supported version of react native.
  • [x] I checked for possible duplicate issues, with possible answers.

Bug summary

Issue: I'm experiencing a double splash screen issue in my Expo project using react-native-bootsplash. Both Expo's auto-generated splash and bootsplash are showing simultaneously.

My Setup:

// app.json
{
  "expo": {
    "icon": "./assets/images/app-logo.png",
    "plugins": [
      ["react-native-bootsplash", { "assetsDir": "assets/bootsplash" }]
    ]
  }
}
// package.json
"expo": {
  "autolinking": {
    "exclude": ["expo-splash-screen"]
  }
}

Problems:

  1. Expo automatically generates a splash screen when an icon field is present, creating conflicting splash themes in android/app/src/main/res/values/styles.xml:

    • Theme.App.SplashScreen (Expo's auto-generated)
    • BootTheme (react-native-bootsplash)
  2. Getting this warning in app.json for the react-native-bootsplash plugin line:

    We couldn't find a package.json in your project. Are you sure you are running it inside a React Native project?
    

My Solution: I added an empty splash configuration to disable Expo's auto-generation:

// app.json
{
  "expo": {
    "icon": "./assets/images/app-logo.png",
    "splash": {},
    "plugins": [
      ["react-native-bootsplash", { "assetsDir": "assets/bootsplash" }]
    ]
  }
}

Questions:

  1. Is "splash": {} the correct/recommended way to disable Expo's automatic splash screen generation when using react-native-bootsplash?
  2. What causes the package.json warning for the plugin, and how should it be resolved?
  3. Should these solutions be documented in the Expo setup section?

Library version

6.3.9

Environment info

"devDependencies": {
    "@react-native-community/cli": "latest",
  }

Steps to reproduce

  1. …
  2. …

Reproducible sample code

See code above

objectiveSee avatar Jun 09 '25 13:06 objectiveSee

@objectiveSee Can you publish your full app.json?

zoontek avatar Jun 09 '25 16:06 zoontek

@zoontek here ya go!

{
  "expo": {
    "name": "MyApp",
    "slug": "my-app",
    "scheme": "myapp",
    "version": "1.0.0",
    "orientation": "portrait",
    "userInterfaceStyle": "automatic",
    "icon": "./assets/images/app-icon.png",
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "newArchEnabled": true,
    "jsEngine": "hermes",
    "assetBundlePatterns": [
      "**/*"
    ],
    "android": {
      "icon": "./assets/images/app-icon-android.png",
      "package": "com.example.myapp",
      "adaptiveIcon": {
        "foregroundImage": "./assets/images/app-icon-android-foreground.png",
        "backgroundImage": "./assets/images/app-icon-android-background.png"
      }
    },
    "ios": {
      "icon": "./assets/images/app-icon-ios.png",
      "supportsTablet": true,
      "bundleIdentifier": "com.example.myapp",
      "appleTeamId": "XXXXXXXXXX",
      "infoPlist": {
        "ITSAppUsesNonExemptEncryption": false,
        "UIBackgroundModes": ["remote-notification"],
        "NSSupportsLiveActivities": true
      },
      "entitlements": {
        "aps-environment": "production"
      }
    },
    "web": {
      "favicon": "./assets/images/app-favicon.png",
      "bundler": "metro"
    },
    "plugins": [
      "expo-localization",
      "expo-font",
      [
        "react-native-bootsplash",
        {
          "assetsDir": "assets/bootsplash"
        }
      ],
      "@bacons/apple-targets"
    ],
    "experiments": {
      "tsconfigPaths": true
    },
    "extra": {
      "eas": {
        "projectId": "00000000-0000-0000-0000-000000000000"
      }
    }
  }
}

objectiveSee avatar Jun 13 '25 23:06 objectiveSee

OK, all good here. Your package.json?

zoontek avatar Jun 14 '25 05:06 zoontek

{
  "name": "project-name",
  "version": "0.0.1",
  "private": true,
  "main": "index.tsx",
  "scripts": {
    "compile": "tsc --noEmit -p . --pretty",
    "lint": "eslint . --fix",
    "validate": "tsc --noEmit -p . --pretty && eslint . --fix && jest",
    "lint:check": "eslint .",
    "patch": "patch-package",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:maestro": "maestro test -e MAESTRO_APP_ID=com.example.app -e IS_DEV=true .maestro/flows",
    "test:maestro:ci": "maestro test -e MAESTRO_APP_ID=com.example.app -e IS_DEV=false .maestro/flows",
    "adb": "adb reverse tcp:9090 tcp:9090 && adb reverse tcp:3000 tcp:3000 && adb reverse tcp:9001 tcp:9001 && adb reverse tcp:8081 tcp:8081",
    "postinstall": "patch-package",
    "build:ios:sim": "eas build --profile development --platform ios --local",
    "build:ios:dev": "eas build --profile development:device --platform ios --local",
    "build:ios:preview": "eas build --profile preview --platform ios --local",
    "build:ios:prod": "eas build --profile production --platform ios --local",
    "build:android:sim": "eas build --profile development --platform android --local",
    "build:android:dev": "eas build --profile development:device --platform android --local",
    "build:android:preview": "eas build --profile preview --platform android --local",
    "build:android:prod": "eas build --profile production --platform android --local",
    "start": "expo start --dev-client",
    "android": "expo run:android",
    "ios": "expo run:ios",
    "web": "webpack serve --mode development",
    "build:web": "webpack --mode production",
    "serve:web": "npx serve dist",
    "prebuild:clean": "npx expo prebuild --clean"
  },
  "dependencies": {
    "@expo-google-fonts/space-grotesk": "^0.2.2",
    "@expo/metro-runtime": "~4.0.0",
    "@react-navigation/bottom-tabs": "^7.2.0",
    "@react-navigation/native": "^7.0.14",
    "@react-navigation/native-stack": "^7.2.0",
    "@shopify/flash-list": "^1.7.3",
    "@tanstack/react-query": "^5.80.6",
    "@xstate/react": "^5.0.5",
    "apisauce": "3.0.1",
    "date-fns": "^4.1.0",
    "expo": "^52.0.44",
    "expo-application": "~6.0.1",
    "expo-audio": "~0.3.5",
    "expo-build-properties": "~0.13.1",
    "expo-file-system": "~17.0.1",
    "expo-font": "~13.0.1",
    "expo-linear-gradient": "~14.0.2",
    "expo-linking": "~7.0.2",
    "expo-localization": "~16.0.0",
    "expo-splash-screen": "~0.29.10",
    "expo-status-bar": "~2.0.0",
    "expo-system-ui": "~4.0.3",
    "i18next": "^23.14.0",
    "intl-pluralrules": "^2.0.1",
    "jotai": "^2.12.5",
    "p-limit": "^6.2.0",
    "react": "18.3.1",
    "react-dom": "18.3.1",
    "react-i18next": "^15.0.1",
    "react-native": "0.76.9",
    "react-native-bootsplash": "^6.3.8",
    "react-native-drawer-layout": "^4.0.1",
    "react-native-gesture-handler": "~2.20.2",
    "react-native-keyboard-controller": "^1.12.7",
    "react-native-mmkv": "3.1.0",
    "react-native-reanimated": "~3.16.1",
    "react-native-safe-area-context": "4.12.0",
    "react-native-screens": "~4.4.0",
    "react-native-web": "~0.19.6",
    "react-native-web-refresh-control": "^1.1.2",
    "react-native-web-webview": "^1.0.2",
    "xstate": "^5.19.4"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@babel/plugin-proposal-class-properties": "^7.18.6",
    "@babel/plugin-proposal-object-rest-spread": "^7.20.7",
    "@babel/preset-env": "^7.27.2",
    "@babel/preset-react": "^7.27.1",
    "@babel/preset-typescript": "^7.27.1",
    "@babel/runtime": "^7.20.0",
    "@testing-library/react-native": "^12.5.2",
    "@types/jest": "^29.2.1",
    "@types/react": "~18.3.12",
    "babel-jest": "^29.2.1",
    "babel-loader": "^10.0.0",
    "eslint": "^8.57.0",
    "eslint-config-expo": "~8.0.1",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-prettier": "^5.2.1",
    "eslint-plugin-react-native": "^4.1.0",
    "eslint-plugin-reactotron": "^0.1.2",
    "file-loader": "^6.2.0",
    "html-webpack-plugin": "^5.6.3",
    "jest": "^29.2.1",
    "jest-expo": "~52.0.1",
    "patch-package": "^8.0.0",
    "postinstall-prepare": "1.0.1",
    "prettier": "^3.3.3",
    "react-test-renderer": "18.2.0",
    "reactotron-core-client": "^2.9.4",
    "reactotron-react-js": "^3.3.11",
    "reactotron-react-native": "^5.0.5",
    "reactotron-react-native-mmkv": "^0.2.6",
    "ts-jest": "^29.1.1",
    "ts-node": "^10.9.2",
    "typescript": "~5.3.3",
    "url-loader": "^4.1.1",
    "webpack": "^5.99.9",
    "webpack-cli": "^6.0.1",
    "webpack-dev-server": "^5.2.1"
  },
  "engines": {
    "node": ">=18"
  },
  "expo": {
    "autolinking": {
      "exclude": ["expo-splash-screen"]
    }
  },
  "packageManager": "yarn@latest"
}

objectiveSee avatar Jun 24 '25 20:06 objectiveSee

  1. Remove "splash": {} from your app.json
  2. Uninstall expo-splash-screen (remove the dependency), recreate a build

zoontek avatar Jun 25 '25 04:06 zoontek

Thanks, I wasn't sure whether expo-splash-screen was required as a dependency or something like that. It makes sense that we don't need it at all.

objectiveSee avatar Jun 25 '25 15:06 objectiveSee

@zoontek We are seeing two images in the storyboard file when the assets are generated using both logo and --brand arguments. Is this expected, and should we use the logo parameter only?

hari avatar Jun 27 '25 13:06 hari

@hari That's expected, one image for the logo, the other for the brand.

zoontek avatar Jun 27 '25 13:06 zoontek

Thanks for the confirmation @zoontek

hari avatar Jun 27 '25 14:06 hari

@objectiveSee Is this solved on your side?

zoontek avatar Jun 27 '25 15:06 zoontek

Updated to reflect latest Expo setup: https://github.com/zoontek/react-native-bootsplash/commit/c6a502f6d898bcb8878985c72b62df944938b331

zoontek avatar Jun 29 '25 08:06 zoontek