React Native 0.87 deprecated ImageBackground, DrawerLayoutAndroid and UTFSequence. SafeAreaView was deprecated earlier, in 0.81. All four still work. They log a warning, and React Native's code says they "will be removed in a future release". After that, importing them from 'react-native' gives you undefined, and every screen that renders one crashes.
I run a health check on 653 open-source React Native and Expo apps (the set I use to test NativeKeel). Here is how many import these from 'react-native':
| API | Apps | Files |
|---|---|---|
SafeAreaView |
123 | 423 |
ImageBackground |
85 | 203 |
DrawerLayoutAndroid |
1 | 1 |
UTFSequence |
0 | 0 |
That is 183 of 653 apps (28%). Among the 358 apps already on React Native 0.76 or newer, it is 87 (24%), so this is not just old code.
Both fixes are small. Here they are.
SafeAreaView: it never did anything on Android
The core SafeAreaView "is currently only applicable to iOS devices" (React Native docs). On Android it is a plain View.
That used to be fine, because Android drew your app below the status bar. It no longer is. Apps that target Android 15 (API level 35) are edge-to-edge by default: the status bar and navigation bar are transparent, and your content draws behind them unless you apply insets. Google Play now requires new apps and updates to target API level 36, so every app that ships an update runs edge-to-edge on Android 15 and newer devices.
So the core SafeAreaView is not only deprecated: on current Android it lets your header slide under the status bar.
The replacement is react-native-safe-area-context, which handles both platforms:
npx expo install react-native-safe-area-context # Expo
npm install react-native-safe-area-context # bare React Native
Wrap the root of your app once. Expo Router already does this for you.
import { SafeAreaProvider } from 'react-native-safe-area-context';
export default function App() {
return (
<SafeAreaProvider>
<RootNavigator />
</SafeAreaProvider>
);
}
Then change the import on each screen:
- import { SafeAreaView, View, Text } from 'react-native';
+ import { View, Text } from 'react-native';
+ import { SafeAreaView } from 'react-native-safe-area-context';
It takes an edges prop when you only want some of the insets, for example edges={['top']} on a screen that has a bottom tab bar. For a custom header, useSafeAreaInsets() gives you the numbers.
One detail from the scan: 52 apps already use react-native-safe-area-context somewhere and still import the core SafeAreaView on other screens. Those screens behave differently on Android. Search for both imports.
ImageBackground: five lines of your own
React Native's docs now say: "Use a View with an absolutely positioned Image instead." That is what ImageBackground always was inside. A drop-in component:
import type { ReactNode } from 'react';
import { Image, StyleSheet, View, type ImageProps, type ImageStyle, type StyleProp, type ViewStyle } from 'react-native';
type Props = Omit<ImageProps, 'style'> & { style?: StyleProp<ViewStyle>; imageStyle?: StyleProp<ImageStyle>; children?: ReactNode };
export function Background({ style, imageStyle, children, resizeMode = 'cover', ...image }: Props) {
return (
<View style={style}>
<Image {...image} resizeMode={resizeMode} style={[StyleSheet.absoluteFill, imageStyle]} />
{children}
</View>
);
}
Then replace <ImageBackground with <Background. If you used borderRadius on the ImageBackground, add overflow: 'hidden' to the outer style so the image is clipped too. If you already use expo-image, the same pattern works with its Image and contentFit="cover".
DrawerLayoutAndroid and UTFSequence
-
DrawerLayoutAndroid→react-native-drawer-layout, which also works on iOS. -
UTFSequence→ write the Unicode escape directly, e.g.''.
Finding them in your app
A grep for the names will find most of them, but it misses imports split across lines and finds the safe-area-context version too. NativeKeel lists each one with its file and line, and adds the fix to the upgrade plan:
npx nativekeel
It runs locally (your code is not uploaded), has no dependencies, and is open source. If it reports something wrong for your app, I would like to hear about it: https://github.com/AlicanAkyol/nativekeel
Numbers are from a scan of 653 open-source React Native and Expo apps on GitHub (libraries excluded), October 2026. From an earlier scan: We scanned 470 open-source React Native apps. Here is what breaks them.
Top comments (0)