You swapped in a fresh app icon for your Rork project, ran a build, opened the app on a simulator or device — and the old icon is still staring back at you. If this is the first time you've hit it, welcome to a club every Rork developer ends up in eventually. I've personally tripped over this on almost every app I've shipped.
What makes this issue frustrating is that the cause isn't in one place. It can hide inside Expo configuration, EAS Build cache, the iOS SpringBoard cache, or missing adaptive icons on Android. Even one of these layers being wrong is enough to keep the old icon stuck. Let's walk through each layer with the fastest first checks and the nuclear options for when nothing else works.
Diagnose first — figure out which layer is stuck
Before changing anything, identify where the issue is happening. Two minutes here saves an hour of guessing.
- Simulator shows the new icon, real device shows the old one → device cache problem
- EAS Build artifact already has the old icon baked in → build cache or
app.jsonmismatch - iOS updated, Android did not → adaptive icon configuration missing
- Icon disappeared after pushing an EAS Update (OTA) → OTA never updates icons (more on this below)
This 30-second triage tells you whether to focus on devices, builds, or configuration. The single most common waste of time is rebuilding repeatedly when the actual issue is a cached image on the device, not in the binary at all.
Quick fixes that solve 70% of cases
In my experience, the majority of icon update issues clear up with these three steps.
# 1. Fully uninstall the app
# iOS simulator
xcrun simctl uninstall booted com.example.yourapp
# Android emulator
adb uninstall com.example.yourapp
# 2. Rebuild with the cache cleared
eas build --platform ios --clear-cache --profile preview
eas build --platform android --clear-cache --profile preview
# 3. If you prebuild locally, use --clean
npx expo prebuild --cleanAfter these steps, install the freshly built app on a clean device and the new icon should appear. For the iOS Simulator, Device → Erase All Content and Settings is also worth trying — it wipes every cached image including SpringBoard's icon cache.
iOS in particular caches icons aggressively. Even after uninstalling the app, the cached image can linger, and a device restart is the most reliable way to evict it. On a physical iPhone, a full power-off (hold side button + volume) is more thorough than a soft reboot.
A subtle but important detail: if you only ran eas build without --clear-cache, EAS may reuse a previous build's asset bundle entirely. Always pair the first new-icon build with --clear-cache so the icon files are re-uploaded from your working tree.
Get app.json (or app.config.js) right
Even though Rork generates the project, icon configuration follows standard Expo conventions. Skipping a field here is the most common source of "the new icon isn't showing on Android" complaints.
{
"expo": {
"name": "Your App",
"icon": "./assets/icon.png",
"ios": {
"icon": "./assets/icon-ios.png",
"bundleIdentifier": "com.example.yourapp"
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon-foreground.png",
"backgroundColor": "#FFFFFF"
},
"package": "com.example.yourapp"
}
}
}The critical line is the Android adaptiveIcon. Without it, devices running Android 8.0 and later will keep showing the default Expo placeholder. Place your logo within the center 66% of a 1024×1024 canvas — the outer 17% is the safe zone since OEMs mask icons into circles, squircles, teardrops, and other shapes you can't predict.
A few more things worth checking in this file:
- The PNG should be exactly 1024×1024 with no transparency for
ios.icon. Apple rejects icons with alpha channels during App Store review. - For
android.adaptiveIcon.foregroundImage, transparency is required so the OS can layer it overbackgroundColoror a dynamic theme. - If you use
app.config.jsinstead ofapp.json, double-check that the function actually returns the icon paths. I've seen builds quietly skip icon updates because a config function had a logic error and returnedundefinedfor the icon field.
iOS gotchas — SpringBoard and TestFlight cache layers
iOS has two icon caches that love to mislead developers.
- SpringBoard cache: the home screen icon is cached separately by SpringBoard. Even after you uninstall the app, that cached image can survive. A device restart is the cleanest fix.
- TestFlight cache: TestFlight itself caches icons of installed builds. After you push a new build with a fresh icon, TestFlight may still display the old one. Deleting and reinstalling TestFlight clears it.
The same caching can happen on the App Store side after release. Apple's CDN can take up to 24 hours to fully refresh icon imagery worldwide, so if you're checking right after the version goes live, give it a day before assuming something is broken. If your icon was tied up in a rejection cycle, you might also want to look at our App Store rejection recovery guide.
Android gotchas — adaptive icons and density variants
When Android refuses to update, the cause is almost always adaptive icons.
- Updated
foregroundImagebut notbackgroundColor: Android 8.0+ composites both layers; mismatched updates produce visual oddities. - Missing
monochromeImage: Android 13+ themed icons need a separate monochrome asset to participate in the OS-wide theme tinting. - Stale images in
mipmap-*directories: regenerate the entireandroid/folder withnpx expo prebuild --clean.
For asset generation, I lean on Figma templates that include a circular safe-zone guide. Designing inside that guide guarantees no part of the logo gets cut off on any device shape. Pixel devices clip to a circle, Samsung clips to a squircle, and certain Chinese OEMs use teardrop shapes — design once, render everywhere.
One more Android-specific tip: many launchers (Nova, Lawnchair, etc.) cache icons separately from the system. If a tester reports the old icon and they're using a custom launcher, ask them to clear that launcher's cache before you go hunting for build issues.
EAS Update (OTA) does not refresh icons
This trips up so many developers that it deserves its own section. EAS Update (formerly expo-updates) ships JavaScript bundles and a subset of assets — but not icons, splash screens, or anything compiled into the native binary. Changing your icon requires a new native build, full stop.
If you've been pushing OTA updates and wondering why nothing changes, that's why. Check that you ran eas build for a fresh native artifact. Our EAS Update implementation guide goes deeper into what OTA can and cannot do.
When nothing works — the deep clean
If you've done all of the above and still see the old icon, suspect deeper native build caches.
# iOS: nuke Xcode's DerivedData
rm -rf ~/Library/Developer/Xcode/DerivedData
# Android: clean Gradle
cd android && ./gradlew clean && cd ..
# Rebuild node_modules and native folders from scratch
rm -rf node_modules ios android
npm install
npx expo prebuild --clean
# Then build with cache cleared
eas build --platform all --clear-cacheAfter this, the new icon will almost certainly stick. While you're cleaning up icon issues, if your splash screen flashes white during launch, the splash screen white flash fix covers that adjacent problem.
Verify before assuming success
Once you've rebuilt and reinstalled, run a quick mental checklist before declaring victory:
- Test on at least one real device per platform, not only simulators or emulators
- Check the icon on a fresh app installation (uninstall first, then install — don't update over the old version)
- Look at the icon in the device's app switcher, not just the home screen — they're cached independently on iOS
- For Android, test both the launcher icon and the icon shown in Settings → Apps
If all four locations show the new icon, you're truly done. If even one location shows the old icon, the cache hasn't fully cleared and you'll likely get reports from beta testers about it later.
A note on icon design iteration
A side benefit of fixing the cache pipeline once is that you stop fearing icon changes. I used to put off icon refinements because the build/cache dance was so painful. With these steps reduced to muscle memory, I now iterate on icons during normal development cycles rather than treating them as a one-time decision.
If you're at the design stage rather than the troubleshooting stage, the App Store guidelines for icon design and the Material Design adaptive icon spec are still the best starting points. Both are short reads and worth bookmarking.
Icon updates feel mundane until they block your release. Open your project's app.json right now and confirm adaptiveIcon is fully configured — that single check often saves the next icon swap from turning into an hour of detective work.