Skip to main content
The MapView component is the core of any Mapbox map in React Native. It renders the map surface and manages the native Mapbox GL implementation underneath.

Basic Usage

At minimum, a MapView requires a style to fill its container:
import { MapView } from '@rnmapbox/maps';
import { StyleSheet } from 'react-native';

const App = () => (
  <MapView style={styles.map} />
);

const styles = StyleSheet.create({
  map: {
    flex: 1,
  },
});

Map Styles

MapView can display different map styles using either a style URL or inline StyleJSON.

Using Style URLs

Mapbox provides several built-in styles:
import { MapView, StyleURL } from '@rnmapbox/maps';

<MapView
  style={styles.map}
  styleURL={StyleURL.Street}  // Default if not specified
/>
Available built-in styles:
  • StyleURL.Street - Mapbox Streets (default)
  • StyleURL.Dark - Mapbox Dark
  • StyleURL.Light - Mapbox Light
  • StyleURL.Outdoors - Mapbox Outdoors
  • StyleURL.Satellite - Mapbox Satellite
  • StyleURL.SatelliteStreet - Satellite Streets hybrid

Custom Style URLs

<MapView
  styleURL="mapbox://styles/username/style-id"
  style={styles.map}
/>

Using StyleJSON

For complete control, provide an inline style object:
const customStyle = {
  version: 8,
  sources: {
    // Your sources
  },
  layers: [
    // Your layers
  ],
};

<MapView
  styleJSON={JSON.stringify(customStyle)}
  style={styles.map}
/>

Map Projection

Control how the map is projected with the projection prop:
<MapView
  projection="globe"  // or "mercator" (default)
  style={styles.map}
/>
The globe projection provides a 3D spherical view of the Earth when zoomed out, transitioning to Mercator at higher zoom levels.

User Interaction

Gesture Controls

Control which gestures are enabled:
<MapView
  style={styles.map}
  zoomEnabled={true}
  scrollEnabled={true}
  pitchEnabled={true}
  rotateEnabled={true}
/>

Fine-grained Gesture Settings

For more control, use the gestureSettings prop:
<MapView
  style={styles.map}
  gestureSettings={{
    doubleTapToZoomInEnabled: true,
    doubleTouchToZoomOutEnabled: true,
    pinchZoomEnabled: true,
    rotateEnabled: true,
    pitchEnabled: true,
    panEnabled: true,
    quickZoomEnabled: true,
  }}
/>

Event Handlers

User Interaction Events

const handlePress = (feature: GeoJSON.Feature) => {
  console.log('Tapped at:', feature.geometry.coordinates);
};

const handleLongPress = (feature: GeoJSON.Feature) => {
  console.log('Long pressed at:', feature.geometry.coordinates);
};

<MapView
  style={styles.map}
  onPress={handlePress}
  onLongPress={handleLongPress}
/>

Camera Events

Map Lifecycle Events

<MapView
  style={styles.map}
  onDidFinishLoadingMap={() => console.log('Map loaded')}
  onDidFinishLoadingStyle={() => console.log('Style loaded')}
  onMapLoadingError={() => console.error('Map failed to load')}
/>

Map Ornaments

<MapView
  style={styles.map}
  attributionEnabled={true}
  attributionPosition={{ bottom: 8, left: 8 }}
  logoEnabled={true}
  logoPosition={{ bottom: 8, right: 8 }}
/>
The Mapbox Terms of Service require attribution to be visible. Only disable if you implement attribution elsewhere in your app.

Compass and Scale Bar

<MapView
  style={styles.map}
  compassEnabled={true}
  compassFadeWhenNorth={true}
  compassPosition={{ top: 100, right: 16 }}
  scaleBarEnabled={true}
  scaleBarPosition={{ top: 8, left: 8 }}
/>

Imperative Methods

Access MapView methods using a ref:
import { useRef } from 'react';
import { MapView } from '@rnmapbox/maps';

const App = () => {
  const mapRef = useRef<MapView>(null);

  const queryFeatures = async () => {
    const point = [100, 100]; // Screen coordinates
    const features = await mapRef.current?.queryRenderedFeaturesAtPoint(point);
    console.log('Features at point:', features);
  };

  const getMapInfo = async () => {
    const zoom = await mapRef.current?.getZoom();
    const center = await mapRef.current?.getCenter();
    const bounds = await mapRef.current?.getVisibleBounds();
    console.log({ zoom, center, bounds });
  };

  return <MapView ref={mapRef} style={styles.map} />;
};

Common Methods

MethodDescription
getZoom()Returns current zoom level
getCenter()Returns center coordinates
getVisibleBounds()Returns visible bounds [ne, sw]
queryRenderedFeaturesAtPoint(point)Get features at screen coordinate
queryRenderedFeaturesInRect(bbox)Get features in bounding box
querySourceFeatures(sourceId, filter)Query source directly
takeSnap(writeToDisk)Capture map snapshot
getPointInView(coordinate)Convert geo to screen coords
getCoordinateFromView(point)Convert screen to geo coords

Performance Optimization

Frame Rate Control

<MapView
  preferredFramesPerSecond={60}  // iOS: preferred, Android: max
  style={styles.map}
/>

Surface View (Android)

<MapView
  surfaceView={true}  // Better performance, default true
  style={styles.map}
/>

Scroll View Integration (Android)

<MapView
  requestDisallowInterceptTouchEvent={true}
  style={styles.map}
/>
When embedding MapView inside a ScrollView on Android, enable requestDisallowInterceptTouchEvent for proper touch handling.

Localization

Localize map labels to user’s language:
<MapView
  style={styles.map}
  localizeLabels={{ locale: 'current' }}  // Uses device locale
/>

// Or specify a locale
<MapView
  localizeLabels={{ 
    locale: 'es',
    layerIds: ['country-label', 'state-label']  // Optional: specific layers
  }}
/>

Complete Example

import { useRef, useEffect } from 'react';
import { StyleSheet, Alert } from 'react-native';
import { MapView, Camera, StyleURL } from '@rnmapbox/maps';

const App = () => {
  const mapRef = useRef<MapView>(null);

  useEffect(() => {
    // Query features after map loads
    const queryMap = async () => {
      const zoom = await mapRef.current?.getZoom();
      console.log('Current zoom:', zoom);
    };
    
    setTimeout(queryMap, 1000);
  }, []);

  const handlePress = (feature: GeoJSON.Feature) => {
    Alert.alert(
      'Map Tapped',
      `Coordinates: ${feature.geometry.coordinates.join(', ')}`
    );
  };

  const handleCameraChanged = (state: MapState) => {
    console.log('Zoom:', state.properties.zoom);
  };

  return (
    <MapView
      ref={mapRef}
      style={styles.map}
      styleURL={StyleURL.Street}
      projection="mercator"
      onPress={handlePress}
      onCameraChanged={handleCameraChanged}
      onDidFinishLoadingStyle={() => console.log('Style loaded')}
      compassEnabled={true}
      scaleBarEnabled={true}
      attributionEnabled={true}
    >
      <Camera
        centerCoordinate={[-74.006, 40.7128]}
        zoomLevel={12}
      />
    </MapView>
  );
};

const styles = StyleSheet.create({
  map: {
    flex: 1,
  },
});

export default App;
  • Camera - Control camera position and animation
  • Sources - Add data sources to the map
  • Layers - Visualize data with layers

Build docs developers (and LLMs) love