> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/help/llms.txt)

# Getting Started with Maps in React Native

**[@rnmapbox/maps](https://rnmapbox.github.io/)** is a community-maintained React Native wrapper for the Mapbox Maps SDKs for [iOS](https://docs.mapbox.com/ios/maps/) and [Android](https://docs.mapbox.com/android/maps/). It allows you to integrate interactive, customizable maps into your React Native applications. This tutorial will guide you through creating a complete React Native app that showcases core mapping features.

You will learn how to:

-   Add `@rnmapbox/maps` to your React Native project
-   Display a map with a custom camera position
-   Configure the Standard style with custom lighting
-   Display your own data on the map with custom styling
-   Enable user location with a pulsing indicator

The `@rnmapbox/maps` library is maintained by a community of open source contributors and is not an official Mapbox product. It wraps the Mapbox Maps SDKs for iOS and Android, but may not include all features or the latest updates from the underlying SDKs.

By the end of this tutorial, you'll have built a React Native app featuring a map of Rio de Janeiro with a styled basemap, a custom marathon route, and a user location puck.

Your browser doesn't support HTML5 video. Open [link to the video](https://docs.mapbox.com/help/help/assets/medias/tutorials--getting-started-react-native--location-a5b634fdb70a219de2f58ecd7bb90d41.mp4).

## Prerequisites

Before you begin, you'll need:

-   **Mapbox account**: [Sign up](https://account.mapbox.com/auth/signup/) for free or [log in](https://console.mapbox.com/) if you already have an account.
-   **Node.js and npm.** [Download and install](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) the latest version.
-   **A code editor.** For example, [Visual Studio Code](https://code.visualstudio.com/).
-   **iOS and Android development environments set up.** Follow the [React Native Environment Setup guide](https://reactnative.dev/docs/set-up-your-environment?platform=ios#target-os) to set up your development environment for both iOS and Android, including Xcode for iOS and Android Studio for Android.
-   **Familiarity with React Native development.** Beginner experience with [React Native documentation](https://reactnative.dev/docs/getting-started) and JavaScript.

## Scaffold a new React Native project

First, create a new React Native project using the `init` command from the [React Native CLI](https://www.npmjs.com/package/@react-native-community/cli). In the command below, replace `MyMapboxApp` with your desired project name:

```bash
$ npx @react-native-community/cli@latest init MyMapboxApp
```

Once the project is created, open the project in your code editor, make sure the demo app builds and runs correctly for both iOS and Android platforms before proceeding.

### Build and run on iOS

For iOS, navigate to the `ios` directory in your project and install CocoaPods dependencies:

```bash
$ cd ios && pod install
```

Then, run the app on an iOS simulator or device:

```bash
$ npx react-native run-ios
```

### Build and run on Android

For Android, make sure you have an Android emulator running or a device connected. You may want to install [adb](https://developer.android.com/tools/adb) to help manage Android devices.

Run the app on Android with the following command:

```bash
$ npx react-native run-android
```

---

When you run your app, React Native will launch [metro](https://reactnative.dev/docs/metro) to bundle your JavaScript code. For both platforms, you should see the default React Native app screen with the "Welcome to React Native" message.

![](https://docs.mapbox.com/help/assets/ideal-img/tutorials--getting-started-react-native--scaffold-app.58a26f3.480.png)

With the base project set up, you're ready to add `@rnmapbox/maps` and start building your map application.

## Install and configure @rnmapbox/maps

Before you can start coding with @rnmapbox/maps, you need to add it as a dependency in your React Native project and add some configurations for both the iOS and Android platforms.

### Add the dependency

```bash
$ npm install @rnmapbox/maps
```

### iOS configuration

Update your Podfile at `ios/Podfile` to include the Mapbox SDK. In the `target` block for your app, add the following `pre-install` and `post-install` hooks. Your clean react native project will already have `post-install` hooks, so add the full `pre-install` hook code and include the `$RNMapboxMaps.post_install(installer)` line inside the existing `post_install` block:

```ruby
...
target 'MyMapboxApp' do
  ...
  // highlight-start
  pre_install do |installer|
    $RNMapboxMaps.pre_install(installer)
  end
  // highlight-end

  post_install do |installer|
    // highlight-start
    $RNMapboxMaps.post_install(installer)
    // highlight-end
    # ... other post install hooks
  end
  ...
end
...
```

Navigate to the `ios` directory and use CocoaPods to install the iOS dependencies.

```bash
$ cd ios && pod install
```

Next, add your Mapbox access token to the iOS project. Open the `ios/{YourProjectName}/Info.plist` file and add the following key-value pair inside the `<dict>` element, replacing `YOUR_MAPBOX_ACCESS_TOKEN` with a public access token from your Mapbox account:

```xml
...
// highlight-start
<key>MBXAccessToken</key>
<string>YOUR_MAPBOX_ACCESS_TOKEN</string>
// highlight-end
...
```

To enable the location tracking puck on iOS, add the following keys to `Info.plist` to define the purpose of location access in your app:

```xml
...
// highlight-start
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app uses location to show your position on the map.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app uses location to show your position on the map.</string>
// highlight-end
...
```

### Android configuration

First, add the Mapbox maven repository to your `android/settings.gradle`. Add the full `dependencyResolutionManagement` block below to the end of your `settings.gradle` file:

```gradle
...
// highlight-start
dependencyResolutionManagement {
	repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
	repositories {
		google()
		mavenCentral()
		maven { url = uri("https://api.mapbox.com/downloads/v2/releases/maven") }
	}
}  
// highlight-end
```

Next, add your Mapbox access token. In Android development, the Mapbox access token is typically defined as a [string resource](https://developer.android.com/guide/topics/resources/providing-resources). Create a new file named `mapbox_access_token.xml` in the `android/app/src/main/res/values` directory with the following content, replacing `YOUR_MAPBOX_ACCESS_TOKEN` with your actual access token:

```xml
<resources>
    <string name="mapbox_access_token">YOUR_MAPBOX_ACCESS_TOKEN</string>
</resources>
```

Finally, set location permissions. To enable the location tracking puck on Android, add the following permissions to your `android/app/src/main/AndroidManifest.xml` file:

```xml
...
// highlight-start
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
// highlight-end
...
```

---

With `@rnmapbox/maps` installed and your access token and permissions configured, you're ready to create your first map!

## Add a map to your app

To add a map to your React Native app, use the `MapView` component. This component serves as the container for your map and allows you to configure various properties such as camera position, style, and interactions.

Replace the contents of `App.tsx` with the following code snippet to create a basic map centered on Rio de Janeiro, Brazil:

```jsx
import { MapView, Camera } from '@rnmapbox/maps';
import { StyleSheet, Platform } from 'react-native';

const App = () => {
  return (
    <MapView
      styleURL={"mapbox://styles/mapbox/standard"}
      style={styles.map}
      projection='globe'
      scaleBarEnabled={false}
      logoPosition={Platform.OS === 'android' ? { bottom: 40, left: 10 } : undefined}
      attributionPosition={Platform.OS === 'android' ? { bottom: 40, right: 10 } : undefined}
    >
      <Camera
        defaultSettings={{
          centerCoordinate: [-43.2268, -22.9358],
          zoomLevel: 12.1,
          pitch: 70,
          heading: -161.81,
        }}
      />
    </MapView>
  );
};

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

export default App;
```

This snippet also imports the `Camera` component to set the initial camera position and orientation using its `defaultSettings` prop. Several props are configured on the `MapView` component to customize the map's appearance and behavior:

-   **`styleURL`**: Specifies the map style to use. Here, the Mapbox Standard style is used.
-   **`style`**: Defines the styling for the map container. The map takes up the full width and height of the screen.
-   **`projection`**: Sets the map projection to "globe" for a 3D globe effect.
-   **`scaleBarEnabled`**: Disables the scale bar display.
-   **`logoPosition` and `attributionPosition`**: Adjusts the position of the Mapbox logo and attribution on Android to avoid overlap with other UI elements.

Note that `logoPosition` and `attributionPosition` include conditional logic to only apply custom positioning on Android. This prevents the logo and attribution from rendering too close to the curved corners of the screen on Android devices. Using the [React Native Safe Area Context library](https://appandflow.github.io/react-native-safe-area-context/) is another option for handling safe area insets across different devices.

### Understanding camera positioning

The `Camera` component accepts props to define the initial view of the map:

-   **`centerCoordinate`**: Coordinates pointing to Copacabana Beach area (-43.18326, -22.90796)
-   **`zoomLevel`**: 12.1 provides a detailed neighborhood view
-   **`heading`**: -161.81 degrees rotates the map for an optimal viewing angle. This is equivalent to the `bearing` property in other Mapbox SDKs.
-   **`pitch`**: 70 degrees tilts the camera for a dramatic 3D perspective

For the `animationDuration` and `animationMode` props, use `0` and `'none'` respectively to disable any animation when the map loads.

This combination of camera settings creates a view that highlights both the urban landscape and natural features like the coastline and Sugarloaf Mountain.

### Running your app

Re-run the iOS and Android apps to see the map in action:

```bash
$ npx react-native run-ios
```

```bash
$ npx react-native run-android
```

If everything is configured correctly, you will see a map displaying Rio de Janeiro, Brazil with a tilted camera angle showing the city's dramatic coastline and mountains.

![](https://docs.mapbox.com/help/assets/ideal-img/tutorials--getting-started-react-native--basic-map.1abd1ec.480.png)

## Configure the Standard style

The [Mapbox Standard style](https://docs.mapbox.com/style-spec/) is a general-purpose style with configurable styling options. In this section, you'll enhance your basic map by adding event handling, style customization, and interactive landmark icons.

To configure Mapbox Standard, add the `StyleImport` component as a child of `MapView`:

```jsx
// highlight-start
import { MapView, Camera, StyleImport } from '@rnmapbox/maps';
// highlight-end
import { StyleSheet, Platform } from 'react-native';

const App = () => {
  return (
    <MapView
       ...
    >
      <Camera
        ...
      />
      // highlight-start
      <StyleImport
        id="basemap"
        existing
        config={{
          lightPreset: 'dawn',
          showLandmarkIcons: 'true'
        }}
      />
      // highlight-end
    </MapView>
  );
};
...
```

The Standard style uses a style import system that allows you to configure various aspects of the map's appearance. The example above sets two configuration properties:

-   **`lightPreset`**: Controls the lighting and time-of-day appearance. Options include `day`, `dawn`, `dusk`, and `night`.
-   **`showLandmarkIcons`**: When enabled, displays interactive icons for notable landmarks.

Read the Standard Style API reference to understand the available [configuration properties](https://docs.mapbox.com/map-styles/standard/api/#configuration-properties).

When you run the app now, you'll notice the map has a warm, golden lighting that simulates dawn lighting conditions, and landmark icons appear on notable buildings and locations around Rio de Janeiro.

![](https://docs.mapbox.com/help/assets/ideal-img/tutorials--getting-started-react-native--styled-map.b88b12c.480.png)

## Add and display your own data

Maps become more valuable when you can display your own data. In this section, you'll add a GeoJSON file containing the Rio de Janeiro Marathon route and display it as a styled line on the map.

### Download and add the GeoJSON asset

First, create an `assets` folder in your project root (at the same level as `lib/`), then download the complete Rio de Janeiro Marathon route data.

Download the marathon route [GeoJSON](https://docs.mapbox.com/help/glossary/geojson/) file and add it to your project as `assets/rio_marathon.json`:

[Download JSON](https://docs.mapbox.com/help/help/data/rio_marathon.json)

This file contains the complete 26.2 mile/42.195 km marathon route through Rio de Janeiro. The route showcases the city's iconic coastline, passing through neighborhoods like Copacabana, Ipanema, and along the scenic Lagoa Rodrigo de Freitas.

### Load and display the data

Next, you will import the GeoJSON file and add its features the map as a GeoJSON source.

Update your `App.tsx` file with the highlighted code:

```jsx
// highlight-start
import { MapView, Camera, StyleImport, ShapeSource, LineLayer } from '@rnmapbox/maps';
import type { LineLayerStyle } from '@rnmapbox/maps';
// highlight-end
import { StyleSheet, Platform } from 'react-native';

// highlight-start
// Load local GeoJSON (Metro supports requiring JSON files directly)
const lineString = require('./assets/rio_marathon.json');

// Mapbox LineLayer style (not a React Native StyleSheet)
const lineLayerStyle: LineLayerStyle = {
  lineColor: '#ff0000',
  lineWidth: 6.0,
};
// highlight-end

const App = () => {
  return (
    <MapView
      styleURL={"mapbox://styles/mapbox/standard"}
      style={styles.map}
      projection='globe'
      scaleBarEnabled={false}
      logoPosition={Platform.OS === 'android' ? { bottom: 40, left: 10 } : undefined}
      attributionPosition={Platform.OS === 'android' ? { bottom: 40, right: 10 } : undefined}
    >
      <Camera
        defaultSettings={{
          centerCoordinate: [-43.2268, -22.9358],
          zoomLevel: 12.1,
          pitch: 70,
          heading: -161.81,
        }}
      />
      <StyleImport
        id="basemap"
        existing
        config={{
          lightPreset: 'dawn',
          showLandmarkIcons: 'true'
        }}
      />
      // highlight-start
      <ShapeSource id="line-source" shape={lineString}>
        <LineLayer id="line-layer" style={lineLayerStyle} slot='middle' />
      </ShapeSource>
      // highlight-end
    </MapView>
  );
};

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

export default App;
```

The snippet above adds three important pieces of code to display the marathon route:

1.  **Import the GeoJSON file**: The `require` function loads the local GeoJSON file as a JavaScript object that can be used as a data source.
    
2.  **Add a `ShapeSource`**: The `ShapeSource` component is a child of `MapView`, with the `shape` prop set to the imported GeoJSON object. Adding a source makes the marathon route data *available* for rendering, but a layer is required to visualize it on the map.
    
3.  **Add a `LineLayer`**: The `LineLayer` component is a child of `ShapeSource`, which applies styling defined in the `lineLayerStyle` object. The line is styled with a red color and a width of 6 pixels, and is placed in the "middle" slot to make sure it renders above the base map but below labels.
    

When using GeoJSON files in a React Native project, make sure the file has a `.json` extension. This allows the React Native bundler to correctly process and include the file in the app bundle, making its contents accessible as an object for use in your code.

### Understanding data sources and layers

As a review, here are the key concepts related to displaying data on Mapbox maps:

**Data Sources**: Sources provide the raw data that layers use for rendering. The [`ShapeSource`](https://rnmapbox.github.io/docs/components/ShapeSource) component accepts GeoJSON data either as a string or from a URL. Sources don't directly affect the map's appearance; they only provide data.

To learn more about sources in Mapbox maps, see the Mapbox Style Specification documentation on [sources](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/).

**Layers**: Layers define how data from sources should be rendered. The [`LineLayer`](https://rnmapbox.github.io/docs/components/LineLayer) component renders line geometries with configurable styling.

See the Mapbox Style Specification documentation on [line layers](https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#line) for all available properties.

**Layer Slots**: The Mapbox Standard style provides predefined slots that help with layer ordering:

-   `bottom`: Below all other layers
-   `middle`: Between background and labels
-   `top`: Above all other layers

When you run the app now, you'll see a red line tracing the marathon route through Rio de Janeiro's streets, overlaid on the styled map with interactive landmarks.

![](https://docs.mapbox.com/help/assets/ideal-img/tutorials--getting-started-react-native--with-data.3904c45.480.png)

## Add user location

Location services help users understand their position relative to map content. @rnmapbox/maps provides a built-in location component that displays the user's current location as a pulsing dot on the map.

You can use the `LocationPuck` component as a child of `MapView` to show the user's location. The permissions for iOS and Android were already added in the previous configuration steps, but Android also requires runtime permission requests, so you'll need to handle that in your app code as well.

Add the highlighted code to your `App.tsx` file:

```jsx
// highlight-start
import { MapView, StyleImport, ShapeSource, LineLayer, Camera, LocationPuck } from '@rnmapbox/maps';
import { StyleSheet, Platform, PermissionsAndroid } from 'react-native';
import { useEffect } from 'react';
// highlight-end
...
// highlight-start
const requestLocationPermission = async () => {
  if (Platform.OS === 'android') {
    try {
      const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
        {
          title: 'Location Permission',
          message: 'This app needs access to your location to show your position on the map.',
          buttonNeutral: 'Ask Me Later',
          buttonNegative: 'Cancel',
          buttonPositive: 'OK',
        },
      );
      return granted === PermissionsAndroid.RESULTS.GRANTED;
    } catch (err) {
      console.warn(err);
      return false;
    }
  }
  return true;
};
// highlight-end
const App = () => {
  // highlight-start
  useEffect(() => {
    requestLocationPermission();
  }, []);
  // highlight-end

  return (
    <MapView
      styleURL={"mapbox://styles/mapbox/standard"}
      style={styles.map}
      projection='globe'
      scaleBarEnabled={false}
      logoPosition={Platform.OS === 'android' ? { bottom: 40, left: 10 } : undefined}
      attributionPosition={Platform.OS === 'android' ? { bottom: 40, right: 10 } : undefined}
    >
      ...
      // highlight-start
      <LocationPuck
        puckBearingEnabled
        puckBearing="heading"
        pulsing={{ isEnabled: true }}
      />
      // highlight-end
    </MapView>
  );
};

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

export default App;
```

Besides adding the [`LocationPuck`](https://rnmapbox.github.io/docs/components/LocationPuck) component, the snippet above includes a function to request location permission at runtime, only on Android devices. The `useEffect` hook calls this function when the component mounts.

You can simulate the device location in both iOS simulators and Android emulators to test the location functionality without needing a physical device. To simulate a location in Rio de Janeiro, use the longitude and latitude coordinates: `-43.2268, -22.9358`.

-   **iOS Simulator**: Use the "Features" > "Location" menu to select a predefined location or create a custom GPX file for more complex routes.
-   **Android Emulator**: Use the "Extended Controls" > "Location" tab to set a specific latitude and longitude or load a GPX/KML file for route simulation.

Your browser doesn't support HTML5 video. Open [link to the video](https://docs.mapbox.com/help/help/assets/medias/tutorials--getting-started-react-native--location-a5b634fdb70a219de2f58ecd7bb90d41.mp4).

## Next steps

**Congratulations!** You've successfully created a React Native app with a Mapbox map. Your app now includes a styled basemap, custom data visualization, and location services.

Your browser doesn't support HTML5 video. Open [link to the video](https://docs.mapbox.com/help/help/assets/medias/tutorials--getting-started-react-native--location-a5b634fdb70a219de2f58ecd7bb90d41.mp4).

### Key concepts covered

-   Add @rnmapbox/maps to your React Native project
-   Display a map with a custom camera position
-   Configure the Standard style with custom lighting
-   Display your own data on the map with custom styling
-   Enable user location with a pulsing indicator

### Expand on your work

Now that you have the fundamentals, here are some ideas to enhance your mapping application:

-   **Add custom markers**: Use the [`MarkerView`](https://rnmapbox.github.io/docs/components/MarkerView) component to add custom markers at specific locations
-   **Add more data layers**: Display additional GeoJSON data like points of interest, boundaries, or real-time data
-   **Customize the location component**: Create custom location puck designs and behaviors
-   **Implement user interactions**: Add gesture handling for map interactions like tapping, dragging, and zooming

**@rnmapbox/maps** is a community-maintained wrapper for the Mapbox Maps SDKs for iOS and Android and may not include the latest features from the underlying Mapbox Maps SDKs for iOS and Android.

Stay informed about updates to the underlying SDKs by following the official Mapbox release notes:

-   [iOS Maps SDK Release Notes](https://github.com/mapbox/mapbox-maps-ios/releases)
-   [Android Maps SDK Release Notes](https://github.com/mapbox/mapbox-maps-android/releases)

If a feature is not yet available in @rnmapbox/maps, consider [contributing to the project](https://github.com/rnmapbox/maps) or reaching out to the maintainers for guidance on adding new features.

### Learn more

> **Related content (related): [@rnmapbox/maps documentation](https://rnmapbox.github.io/)**
> 
> Explore the guides and reference documentation for the @rnmapbox/maps library.

> **Related content (related): [Mapbox Maps SDK for Flutter](https://docs.mapbox.com/flutter/maps/guides/)**
> 
> Another option for building cross-platform mobile apps with Mapbox maps is the official Mapbox Maps SDK for Flutter.