Mastering React Native Google Maps with Expo

A practical guide to integrating React Native Google Maps in Expo. Learn to set up API keys, add custom markers, optimize performance, and ship your app.

Profile photo of RishavRishav
20th Feb 2026
Featured image for Mastering React Native Google Maps with Expo

Before you write a single line of map code, you need to get two things right: choosing your Expo workflow and setting up your Google Maps API keys. Getting this foundation solid from the get-go is the difference between a smooth project and hours of painful debugging down the line.

Trust me, these initial steps will dictate how you build, manage, and scale your app's location features. Let's walk through them.

Choosing Your Expo Workflow: Managed vs. Bare

Your first big decision is which Expo workflow to use. This choice boils down to how much control you need over the native iOS and Android projects.

For most projects, especially if you're new to this, the Expo Managed Workflow is the way to go. It handles all the tricky native configuration for you, letting you focus entirely on your React Native code. You can still use powerful libraries like react-native-maps thanks to Expo's config plugins, which inject the necessary native code during the build process.

On the other hand, if your app absolutely requires a specific native library that doesn't have a config plugin, or you need to dive into custom Swift or Kotlin code, you'll have to use the Expo Bare Workflow. This gives you full access to the underlying native projects, just like a standard React Native CLI setup.

This decision tree should make it crystal clear:

Expo map workflow decision tree illustrating options for custom native code requirements.Expo map workflow decision tree illustrating options for custom native code requirements.

As you can see, it really just comes down to whether you need to write custom native code yourself.

Building powerful, location-aware apps is more important than ever. The global mobile app market is projected to skyrocket to $1.2 trillion by 2035, with users spending a mind-boggling 4.2 trillion hours on mobile apps this year alone. A slick map experience can be a huge differentiator in this crowded space. You can learn more about mobile app growth trends to see why getting this right matters.

Expo Workflow Comparison For Map Integration

Here’s a side-by-side look at the Expo Managed vs. Bare workflow to help you choose the right approach for your Google Maps project.

FeatureExpo Managed WorkflowBare Workflow
Native Code AccessNo direct access. Native modifications are handled by Expo config plugins.Full access to native iOS (/ios) and Android (/android) projects.
Ease of UseMuch simpler setup and faster development. Expo handles all native build configurations.More complex. Requires familiarity with Xcode and Android Studio for native dependencies.
Best ForDevelopers who want to focus on React Native code and avoid native complexity.Projects requiring custom native modules or libraries without existing config plugin support.
react-native-mapsWorks perfectly using the provided config plugin.Works great, but you'll manage the native installation and configuration yourself.
Build ProcessBuilds are run on Expo's cloud service (EAS Build) or locally with EAS CLI.You can build locally with Xcode/Android Studio or use EAS Build.
FlexibilityLess flexible for deep native customizations.Maximum flexibility to integrate any native library or write custom native code.

For our react-native-maps integration, the Managed Workflow is more than capable and is the recommended path unless you have a very specific, non-negotiable need for custom native code.

Securing Your Google Maps API Keys

With your workflow decided, it’s time to get your API keys from the Google Cloud Console. Think of these keys as your app's passport to Google's mapping services—you absolutely must protect them.

Inside your Google Cloud project, you need to enable two crucial APIs:

  • Maps SDK for Android
  • Maps SDK for iOS

Forgetting one is a classic rookie mistake. If you do, your map will work on one platform but show up as a blank screen on the other, leaving you scratching your head. Enable both from the start.

Pro Tip: Do not, under any circumstances, leave your API keys unrestricted in a production app. An exposed, unrestricted key is a huge security hole and can lead to a nasty surprise on your billing statement if someone else gets ahold of it.

Once your keys are generated, you have to lock them down. For Android, you'll restrict the key by your app's package name and its SHA-1 signing certificate fingerprint. For iOS, you'll restrict it by your app's bundle identifier. This ensures that only your app—and nobody else's—can use your credentials. It's a non-negotiable step for any serious project.

Integrating And Configuring React Native Maps

A laptop displays code next to a smartphone showing a map on a wooden desk, with 'Configure Maps' text.A laptop displays code next to a smartphone showing a map on a wooden desk, with 'Configure Maps' text.

Alright, with your API keys ready and your workflow decided, it's time for the fun part: actually getting a map to show up in your Expo app. The key to this whole operation is the react-native-maps library. It’s the go-to package for bridging your React Native code with the native Google Maps SDKs.

Nailing this setup is probably the most important step in the entire process. A small slip-up here often leads to those head-scratching moments with blank maps or mysterious build failures. Let's get it right from the start.

Installing the library is a breeze. Just pop open your terminal in the project's root directory and run this command:

npx expo install react-native-maps

A quick but crucial tip: always use expo install instead of npm or yarn. Expo's command ensures you get a version of the library that's been tested and confirmed to work with your specific Expo SDK version. This simple choice helps you dodge a whole category of frustrating version-mismatch bugs.

Letting Expo Config Plugins Do The Heavy Lifting

In the old days, using a library with native code like react-native-maps in an Expo Managed project meant you had to "eject"—a one-way trip that complicated everything. This is where Expo's config plugins are an absolute game-changer.

Think of them as little scripts that automatically tweak your native project files (for Xcode and Android Studio) during the build. This gives you all the power of native modules without ever having to touch the native code yourself. For react-native-maps, the plugin handles linking the SDKs and, most importantly, injecting your API keys where they need to go.

To get it working, you just need to update your app.json or app.config.js file. You'll add react-native-maps to the plugins array and plug in your API keys.

{ "expo": { "plugins": [ [ "react-native-maps", { "androidApiKey": "YOUR_ANDROID_API_KEY", "iosApiKey": "YOUR_IOS_API_KEY" } ] ], "android": { "permissions": [ "android.permission.ACCESS_FINE_LOCATION" ] }, "ios": { "infoPlist": { "NSLocationWhenInUseUsageDescription": "We need your location to show you on the map." } } } }

This snippet accomplishes three critical tasks at once:

  • It activates the react-native-maps plugin.
  • It securely provides your API keys to the native build processes.
  • It proactively adds the location permissions we'll need for showing the user's location later on.

Rendering Your First Map

Now for the payoff—seeing that map render on your device. The library gives us a primary component, <MapView>, to do just this.

Let's create a straightforward component that displays a full-screen map centered on a specific location. You’ll be surprised how little code it takes to get a fully interactive map running.

Here’s a basic example you can drop into a new screen in your app to get started.

import React from 'react'; import MapView, { PROVIDER_GOOGLE } from 'react-native-maps'; import { StyleSheet, View } from 'react-native';

export default function App() { return ( <MapView provider={PROVIDER_GOOGLE} // Essential for using Google Maps on iOS style={styles.map} initialRegion={{ latitude: 37.78825, longitude: -122.4324, latitudeDelta: 0.0922, longitudeDelta: 0.0421, }} /> ); }

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

Pay close attention to the provider={PROVIDER_GOOGLE} prop. This is a must-have, as iOS will default to Apple Maps without it. The initialRegion prop simply tells the map where to point when it first loads.

After adding this code, you'll need to run a build (npx expo prebuild is a good way to sync your native files, followed by npx expo run:ios or npx expo run:android). Seeing that beautiful, interactive Google Map appear is your green light—you're officially ready to start building out more advanced features.

Adding Core Interactive Map Features

A hand holds a smartphone displaying an interactive map application with a red pin on a city street.A hand holds a smartphone displaying an interactive map application with a red pin on a city street.

A static map is a decent start, but your app truly comes to life with interactivity. This is the turning point where it goes from a simple image to a dynamic, location-aware tool. Let's get our hands dirty and implement the most common features that make a React Native Google Maps integration genuinely useful.

Displaying The User's Location

Showing the user's current location is a foundational feature for almost any map-based app, whether it's for ride-sharing or local discovery. Thankfully, the <MapView> component makes this surprisingly simple with a single boolean prop.

Just set showsUserLocation={true}, and the map will automatically request the necessary permissions and pop that familiar blue dot right on the user's current position.

Of course, this only works if you've configured the location permissions in your app.json like we did earlier. The beauty here is that the library, working in tandem with Expo, handles the native permission dialogs for you.

You can take it a step further by adding followsUserLocation={true}. This tells the map to automatically pan to keep the user centered. It's perfect for turn-by-turn navigation or any app where the user's live position is the star of the show.

With just a couple of lines, you’ve provided immediate value and a clear point of reference for your user. Now, let's start populating the map with our own data.

Placing Custom Markers

Markers are the bread and butter of interactive maps. They let you highlight specific points of interest—restaurants, delivery drop-offs, photo locations, you name it. The react-native-maps library gives us the <Marker> component for exactly this job.

You'll nest the <Marker> component inside your <MapView>. At a minimum, it needs a coordinate prop, which is just an object containing a latitude and longitude.

Here’s a quick look at how to drop a single, static marker onto the map.

import MapView, { Marker, PROVIDER_GOOGLE } from 'react-native-maps';

// Inside your component... <MapView provider={PROVIDER_GOOGLE} style={styles.map} initialRegion={...}

<Marker coordinate={{ latitude: 34.052235, longitude: -118.243683 }} title={"Los Angeles City Hall"} description={"A historic landmark in downtown LA."} /> Using the title and description props is a fantastic shortcut. It automatically creates a basic callout—that little info window—that appears when a user taps the marker. It's a quick and clean way to add context.

A common pitfall I've seen countless times is trying to render too many markers at once. Throwing thousands of individual markers on a map will absolutely tank performance, especially on older devices. We'll solve this with clustering later, but for now, just be mindful of how much data you're trying to show.

Adding Interactivity with Callouts

The default callout is fine, but you'll often want more control over its look and feel. For that, we can turn to the <Callout> component, which lets you render any custom React Native view you want inside that info window.

This opens up a ton of possibilities. You can toss in buttons, images, or custom-styled text to build a much richer user experience.

For example, if you're building a real estate app, a custom callout could show a property photo, the price, and a "View Details" button.

import { Text, View, Button } from 'react-native'; import MapView, { Marker, Callout } from 'react-native-maps';

// ... <Marker coordinate={{ latitude: 40.7128, longitude: -74.0060 }}

<Callout onPress={() => alert('Viewing details!')}> <Text style={{ fontWeight: 'bold' }}>NYC Apartment Price: $2,500/mo