Skip to main content
The User Location feature allows you to track and display the user’s current location on the map. You can customize the appearance, listen to location updates, and control the tracking behavior.

Components

There are two main ways to display user location:
  1. UserLocation - Customizable React component with full control over appearance
  2. LocationPuck - Native location puck with optimized performance

Basic Usage

1

Import the components

import { MapView, Camera, UserLocation } from '@rnmapbox/maps';
2

Add UserLocation to your map

<MapView style={{ flex: 1 }}>
  <Camera followUserLocation followZoomLevel={16} />
  <UserLocation visible={true} />
</MapView>

UserLocation Component

The UserLocation component provides a customizable way to display the user’s location with full React Native rendering capabilities.

Props

PropTypeDescription
visiblebooleanWhether the location icon is visible. Default: true
animatedbooleanWhether location icon is animated between updates. Default: true
onUpdate(location: Location) => voidCallback triggered on location update
onPress() => voidCallback triggered when location icon is pressed
minDisplacementnumberMinimum movement in meters before GPS location is updated. Default: 0
showsUserHeadingIndicatorbooleanShow arrow indicating device direction. Default: false
renderModeUserLocationRenderModeRender mode: 'normal' or 'native'. Default: 'normal'
requestsAlwaysUsebooleanRequest always location permission (iOS only)
androidRenderMode'normal' | 'compass' | 'gps'Android-specific render mode
childrenReactElementCustom location icon components

Tracking Location Updates

Listen to location changes using the onUpdate callback:
import { useState } from 'react';
import { Text } from 'react-native';
import { MapView, Camera, UserLocation, Location } from '@rnmapbox/maps';

const LocationTracker = () => {
  const [location, setLocation] = useState<Location>();

  return (
    <>
      <MapView style={{ flex: 1 }}>
        <UserLocation onUpdate={(newLocation) => setLocation(newLocation)} />
        <Camera followUserLocation followZoomLevel={16} />
      </MapView>

      {location && (
        <View>
          <Text>Latitude: {location.coords.latitude}</Text>
          <Text>Longitude: {location.coords.longitude}</Text>
          <Text>Heading: {location.coords.heading}</Text>
          <Text>Speed: {location.coords.speed}</Text>
          <Text>Accuracy: {location.coords.accuracy}</Text>
        </View>
      )}
    </>
  );
};

Setting Minimum Displacement

Control how often location updates are triggered:
<UserLocation
  minDisplacement={10} // Update only after moving 10 meters
  onUpdate={(location) => console.log('User moved 10m', location)}
/>
Setting a higher minDisplacement value reduces battery usage by decreasing the frequency of location updates.

LocationPuck Component

For better performance with native rendering, use LocationPuck:
import {
  MapView,
  Camera,
  LocationPuck,
  UserTrackingMode,
  Images,
  Image,
} from '@rnmapbox/maps';

const NativeUserLocation = () => {
  return (
    <MapView style={{ flex: 1 }}>
      <Images>
        <Image name="customPin">
          <View
            style={{
              width: 20,
              height: 20,
              borderRadius: 10,
              backgroundColor: 'blue',
              borderColor: 'white',
              borderWidth: 2,
            }}
          />
        </Image>
      </Images>

      <Camera
        followUserLocation={true}
        followUserMode={UserTrackingMode.Follow}
        followZoomLevel={16}
      />

      <LocationPuck
        topImage="customPin"
        visible={true}
        pulsing={{
          isEnabled: true,
          color: 'blue',
          radius: 50.0,
        }}
        scale={['interpolate', ['linear'], ['zoom'], 10, 1.0, 20, 4.0]}
      />
    </MapView>
  );
};

LocationPuck Props

PropTypeDescription
topImagestringName of image to use as the top layer
bearingImagestringImage shown when bearing is enabled
shadowImagestringShadow image below the puck
visiblebooleanWhether the puck is visible
pulsing{ isEnabled: boolean, color: string, radius: number }Pulsing animation configuration
scaleExpressionScale expression based on zoom level
puckBearing'heading' | 'course'Type of bearing to display
puckBearingEnabledbooleanEnable bearing indicator

Custom Location Icon

Customize the appearance by passing custom children:
import { UserLocation, CircleLayer } from '@rnmapbox/maps';

const CustomUserLocation = () => (
  <UserLocation visible={true}>
    <CircleLayer
      id="userLocationCircle"
      style={{
        circleRadius: 12,
        circleColor: '#3498db',
        circleStrokeWidth: 3,
        circleStrokeColor: '#ffffff',
      }}
    />
  </UserLocation>
);

Following User Location

Combine with Camera to follow the user’s location:
<Camera
  followUserLocation={true}
  followZoomLevel={16}
/>
<UserLocation visible={true} />

User Tracking Modes

ModeDescription
UserTrackingMode.FollowCamera follows user location
UserTrackingMode.FollowWithHeadingCamera follows location and rotates to match device heading
UserTrackingMode.FollowWithCourseCamera follows location and rotates to match movement direction

Platform-Specific Features

iOS

Always Location Permission:
<UserLocation
  requestsAlwaysUse={true}
  onUpdate={(location) => console.log(location)}
/>

Android

Render Modes:
<UserLocation
  androidRenderMode="compass" // 'normal' | 'compass' | 'gps'
  visible={true}
/>
  • normal - Simple circle
  • compass - Triangle with heading indicator
  • gps - Large arrow shape

Performance Considerations

  • Use LocationPuck for better performance when you don’t need custom React Native views
  • Set appropriate minDisplacement to reduce update frequency
  • Consider using UserLocationRenderMode.Native for optimal performance

Permissions

Ensure you have location permissions configured: iOS (Info.plist):
<key>NSLocationWhenInUseUsageDescription</key>
<string>We need your location to show it on the map</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We need your location to track your position</string>
Android (AndroidManifest.xml):
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Always request location permissions at runtime before enabling user location tracking.

Reference

  • Source: src/components/UserLocation.tsx:1
  • Source: src/components/LocationPuck.tsx:1
  • Location Manager: src/modules/location/locationManager.ts:1

Build docs developers (and LLMs) love