React Native Maps
React Native Maps is a comprehensive, community-maintained library providing native map components for both iOS and Android platforms, allowing developers to integrate highly customizable maps into their React Native applications. It supports popular map services like Apple Maps (MapKit) on iOS and Google Maps on Android, with an optional Google Maps provider for iOS as well. The current stable version is `1.27.2`, and the project demonstrates an active development cadence with multiple bug fix and minor releases occurring monthly or bi-monthly, reflecting continuous maintenance and improvement. Its key differentiator lies in its declarative, React-like API, enabling map features such as Markers, Polylines, Polygons, Circles, Overlays, and Heatmaps to be defined as children of the `<MapView />` component. This approach simplifies map state management and interaction. The library also emphasizes compatibility with both the "Old Architecture" and the newer "Fabric (New Architecture)" of React Native, though specific version requirements apply to each, which are crucial considerations for developers.
Common errors
-
Android app crashes on map interaction or lifecycle events on some devices.
cause Known issues with Android native module lifecycle (`doDestroy`) or rendering logic.fixUpgrade to `react-native-maps@1.26.18` or newer, which includes fixes for crashes related to `doDestroy` and `getFeatureAt`. -
iOS map's bottom inset is incorrect or adjusts unexpectedly during initialization, obscuring UI elements.
cause Automatic bottom inset adjustment during map view initialization on iOS.fixUpgrade to `react-native-maps@1.26.20` or newer, which includes a fix to prevent auto bottom inset adjustment on iOS. -
Markers are not displayed correctly, or they disappear/reappear unexpectedly on Android.
cause Incorrect native handling of marker addition and removal within the Android map view.fixUpgrade to `react-native-maps@1.26.15` or newer, which contains fixes for correctly adding and removing markers on Android.
Warnings
- breaking React Native New Architecture (Fabric) compatibility requires specific `react-native-maps` versions. Upgrading React Native or `react-native-maps` can lead to build failures if versions are not aligned.
- gotcha Using custom React Native views inside `<Marker />` components for rendering custom markers can significantly impact performance, especially with many markers.
- gotcha When providing a custom marker image, using `image={require('path/to/image.png')}` might not scale optimally across different screen densities compared to using `image={{ uri: 'image_asset_name' }}` with properly configured native asset bundles.
- breaking An unstable Android API `MapUIBlock` caused issues prior to version `1.27.0`, leading to potential crashes or unexpected behavior on Android devices.
Install
-
npm install react-native-maps -
yarn add react-native-maps -
pnpm add react-native-maps
Imports
- MapView
const MapView = require('react-native-maps');import MapView from 'react-native-maps';
- Marker
import MapView, { Marker } from 'react-native-maps';import { Marker } from 'react-native-maps'; - PROVIDER_GOOGLE
import MapView, { PROVIDER_GOOGLE } from 'react-native-maps';import { PROVIDER_GOOGLE } from 'react-native-maps';
Quickstart
import React, { useState } from 'react';
import { StyleSheet, View } from 'react-native';
import MapView, { Marker, type Region } from 'react-native-maps';
export default function App() {
const [region, setRegion] = useState<Region>({
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
});
const handleRegionChangeComplete = (newRegion: Region) => {
setRegion(newRegion);
};
return (
<View style={styles.container}>
<MapView
style={styles.map}
region={region}
onRegionChangeComplete={handleRegionChangeComplete}
>
<Marker
coordinate={{ latitude: 37.78825, longitude: -122.4324 }}
title="My Location"
description="A sample marker on the map"
/>
</MapView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
map: {
width: '100%',
height: '100%',
},
});