React Native

React Native Vector Icons Showing Box or Question Mark Icon on Release Build

· by DebuggedIt

Quick answer

Icons rendering correctly in development but showing as a box or question mark specifically in a release build almost always means the actual font files (which...

Icons rendering correctly in development but showing as a box or question mark specifically in a release build almost always means the actual font files (which vector icon libraries use to render icons as font glyphs) aren't being correctly bundled into the release build — development mode is often more forgiving about font loading than a genuine production release build.

The Problem

Using react-native-vector-icons (or a similar font-based icon library) shows the correct icons during development, but a release build shows a generic "missing glyph" box or question mark symbol in place of every icon.

Why It Happens

Vector icon libraries typically work by bundling icon font files (.ttf) and referencing specific character codes within those fonts to render each icon — this requires the font files to actually be included in your app's final compiled bundle, which is a separate concern from the JavaScript code that references the icons. Common causes of this failing specifically for release builds:

  • The font linking step (historically requiring explicit native configuration, though newer React Native versions with autolinking handle much of this automatically) wasn't completed correctly, or was completed for debug builds but not verified specifically for release configuration
  • iOS specifically requires font files to be explicitly listed in Info.plist under UIAppFonts, and a missing entry here — even if the font file itself is physically present in the build — prevents iOS from actually being able to load and use it
  • Android requires font files to be present in the correct android/app/src/main/assets/fonts/ directory, and a build configuration or asset-bundling step that doesn't correctly include this directory in the release build specifically (while somehow still working in debug) can produce exactly this platform-specific discrepancy
  • Metro's asset bundling configuration not correctly including font file extensions in what it considers bundleable assets, particularly relevant if using a custom Metro configuration that might have inadvertently narrowed the default asset extension list

The Fix

For iOS, confirm every font file used is explicitly listed in Info.plist:

<key>UIAppFonts</key>
<array>
    <string>MaterialIcons.ttf</string>
    <string>FontAwesome.ttf</string>
    <!-- every specific font file your app actually uses -->
</array>

If you're using react-native-vector-icons, its installation instructions typically include a step to run a script that automatically adds every bundled font to this list — confirm this step was actually completed and the resulting Info.plist genuinely reflects every font your app uses, since a manual edit or an interrupted setup script can leave this incomplete.

For Android, confirm the font files are actually present in the correct assets directory, and that your build.gradle correctly includes this directory as part of the app's asset bundling:

// android/app/build.gradle
apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle")

This Gradle configuration automatically copies the vector icon library's font files into the correct assets location as part of the build process — confirm this line is present and correctly included in your build configuration, since its absence is a very common cause of icons failing specifically in a way that can differ between debug and release build variants depending on exactly how and when assets get bundled.

After confirming both platform-specific configurations are correct, perform a genuinely clean rebuild, since font linking issues are particularly prone to being masked by stale cached build artifacts from a previous, differently-configured build attempt:

# iOS
cd ios
rm -rf build
pod install
cd ..
npx react-native run-ios --configuration Release

# Android
cd android
./gradlew clean
cd ..
npx react-native run-android --variant=release

Confirm you're actually referencing valid icon names that exist within the specific font you're using — a typo in an icon name can also produce a similar "missing glyph" visual symptom, though this would typically also fail in development mode, unlike a genuine release-only font-bundling issue, which is a useful distinguishing clue between these two different possible root causes.

Still Not Working?

If font configuration appears correct on both platforms but the issue persists specifically in release builds, check whether your app's ProGuard/R8 configuration (Android) is inadvertently stripping or renaming something related to font asset loading, similar to how ProGuard can cause other release-specific issues covered in a related Hermes/ProGuard crash topic — add explicit keep rules for any font-loading-related classes your icon library uses if you suspect this is a factor, since minification specifically targeting release builds is a common category of "works in debug, breaks in release" issue across several different symptom types, not just icon rendering specifically.