A dashboard-mounted phone showing Google Maps turn-by-turn navigation with a large red Maine Coon cat riding in the passenger seat.

Turn-by-Turn, the Google Way: The React Native Navigation SDK

The Orange Cat
The Orange Cat

If you have ever tried to build "navigation" in a React Native app, you probably know the trap. You drop in a map, call the Directions API, render a polyline, and... that is a picture of a route. It does not talk. It does not follow the driver. It does not reroute when someone misses a turn or hits traffic. Building the rest yourself — the audio engine, maneuver parsing, off-route detection, the camera that tilts and swings to heading-up — is a genuinely enormous undertaking.

@googlemaps/react-native-navigation-sdk is Google's official answer to that problem. It is a thin React Native bridge over the native Android and iOS Google Maps Navigation SDK — the same engine that powers turn-by-turn guidance in real driver, delivery, and rideshare apps. You get the genuine Google navigation experience as React components, complete with voice prompts, lane guidance, speed limits, ETA, traffic-aware rerouting, multi-stop trips, and even Android Auto and CarPlay projection. It is aimed squarely at logistics, field-service, and fleet apps that need actual navigation, not a route preview.

What You Get Out of the Box

This library is not a styling toolkit for drawing routes. It hands you a fully productized navigation engine, maintained by Google. The headline capabilities:

  • Real turn-by-turn guidance with audio and visual prompts ("In 300 feet, turn right onto Market Street").
  • Traffic-aware routing and automatic rerouting — off-route recalculation and traffic detours are included, with no extra billing for reroutes.
  • Multi-waypoint trips that progress through stops with continueToNextDestination().
  • Navigation simulation so you can test guidance from your desk without driving anywhere.
  • Camera perspective control — heading-up tilt, north-up, or full route overview.
  • Speed limit display, incident reporting, and arrival detection.
  • Android Auto and CarPlay support via dedicated controllers.
  • Route tokens, letting you feed a pre-computed route from the Routes API instead of routing live.

A quick reality check before you get excited: this SDK requires React Native 0.79+ with the New Architecture (Fabric and TurboModules) enabled. That is mandatory — old-architecture apps cannot use it. It is also not compatible with Expo Go (you need a custom dev client or bare workflow), and it leans on a Google Cloud project with billing and the Navigation SDK enabled. We will come back to the gotchas, but it is worth knowing up front that this is a serious, native-heavy integration.

Getting It Installed

Add the package with your manager of choice:

npm install @googlemaps/react-native-navigation-sdk
yarn add @googlemaps/react-native-navigation-sdk

The package itself has no runtime dependencies — it is native code plus TypeScript bindings — but the native side needs attention. On Android you will need minSdkVersion 24 or higher, Core Library Desugaring enabled, Jetifier on, and newArchEnabled=true. On iOS you need 16.0+, the New Architecture flags in your Podfile, and your API key registered in AppDelegate. You also need location permissions (and background-location permissions if you want navigation to continue while the app is backgrounded). The repo ships a sample app that demonstrates the full permission dance using react-native-permissions, which is the fastest way to see a correct setup.

Wrapping Your App in the Navigation Context

Everything starts with NavigationProvider. It supplies navigation state to the tree, configures the mandatory Terms and Conditions dialog, and controls what happens when the user swipes the app away mid-trip.

import {
  NavigationProvider,
  TaskRemovedBehavior,
} from '@googlemaps/react-native-navigation-sdk';

export default function App() {
  return (
    <NavigationProvider
      termsAndConditionsDialogOptions={{
        title: 'Terms and Conditions',
        companyName: 'Your Company Name',
        showOnlyDisclaimer: false,
        uiParams: {
          backgroundColor: '#FFFFFF',
          titleColor: 'rgba(0,0,0,1)',
        },
      }}
      taskRemovedBehavior={TaskRemovedBehavior.CONTINUE_SERVICE}
    >
      {/* the rest of your app */}
    </NavigationProvider>
  );
}

Two details matter here. The Terms and Conditions dialog is not optional decoration — Google requires the user to accept before any guidance can start, and the provider is where you brand it. And taskRemovedBehavior set to CONTINUE_SERVICE keeps navigation alive when the app is dismissed from the recents list, which is exactly what a delivery driver expects when they swipe away to answer a call.

Starting a Trip: The Canonical Flow

Navigation runs through an imperative controller you grab from the useNavigation hook. The flow is always the same four beats: accept terms, initialize the session, set destinations, then start guidance.

import {
  useNavigation,
  TravelMode,
} from '@googlemaps/react-native-navigation-sdk';

function TripScreen() {
  const { navigationController } = useNavigation();

  async function beginTrip() {
    const accepted =
      await navigationController.showTermsAndConditionsDialog();
    if (!accepted) return;

    await navigationController.init();

    const waypoint = {
      title: 'Destination',
      position: { lat: 37.4220679, lng: -122.0859545 },
    };

    await navigationController.setDestinations([waypoint], {
      travelMode: TravelMode.DRIVING,
      avoidFerries: false,
      avoidTolls: false,
    });

    await navigationController.startGuidance();
  }

  // ... render a NavigationView and a "Go" button
}

That is genuinely all it takes to put real voice-guided navigation on screen. setDestinations accepts an array, so a multi-stop route is just a longer list of waypoints. The routingOptions object is where you express preferences like avoiding tolls or ferries, and choosing the travel mode.

Reacting to the Drive with Listeners

A trip is a stream of events, and the SDK exposes setters for all of them. The most important is arrival, because that is where multi-stop logic lives.

const {
  navigationController,
  setOnArrival,
  setOnRouteChanged,
  setOnNavigationReady,
  removeAllListeners,
} = useNavigation();

useEffect(() => {
  setOnArrival((event) => {
    if (event.isFinalDestination) {
      navigationController.stopGuidance();
    } else {
      navigationController.continueToNextDestination();
    }
  });

  setOnRouteChanged(() => console.log('Route recalculated'));
  setOnNavigationReady(() => console.log('Navigation ready'));

  return () => removeAllListeners();
}, []);

Notice the pattern: when the driver reaches a stop that is not the final one, you call continueToNextDestination() and the SDK seamlessly advances to the next leg. Beyond these, you have setOnLocationChanged, setOnRawLocationChanged, setOnTurnByTurn, setOnTrafficUpdated, and setOnStartGuidance for fine-grained control. Always tear listeners down with removeAllListeners() in your cleanup to avoid leaks across screens.

Testing Without Leaving Your Chair

Here is the feature that will save your sanity: the built-in simulator. You do not have to physically drive a route to verify that guidance, arrival, and rerouting behave correctly.

// Race along the active route at 5x speed
navigationController.simulator.simulateLocationsAlongExistingRoute({
  speedMultiplier: 5,
});

// Teleport to a specific coordinate
navigationController.simulator.simulateLocation({
  lat: 37.7749,
  lng: -122.4194,
});

// Freeze the simulation in place
navigationController.simulator.pauseLocationSimulation();

Crank the speed multiplier to watch a whole multi-stop trip play out in seconds, jump to an arbitrary point to test arrival logic, or pause mid-route to inspect the UI state. This turns navigation development from a logistical nightmare into something you can iterate on the same way you iterate on any other component.

Choosing the Right Map Component

The package gives you two surfaces. NavigationView is the full experience: the turn-by-turn header, the map, the speed limit badge, recenter controls, the works. MapView is a bare map with no navigation chrome — useful for a destination-picker screen or an order-overview map.

There is a clever bonus to MapView. Both this SDK and the popular react-native-maps library pull in the native Google Maps SDK, which is a classic recipe for native dependency conflicts. Google's recommended mitigation is simply to use this package's MapView for your plain-map needs instead of mixing in react-native-maps. One native Google Maps dependency, no conflict.

Knowing What You Are Signing Up For

Two things deserve a clear-eyed mention before you commit. First, billing. The Navigation SDK is pay-as-you-go, charged per destination you send to the SDK. The first 1,000 destinations each month are free, and beyond that it is roughly $25 per 1,000 (about $0.025 each) with volume discounts. Importantly, there is no charge to start guidance and no charge for reroutes — once a destination is billed, all the traffic detours and off-route recalculations are included. This is a meaningfully different cost model from "free map loads," so model it against your trip volume.

Second, this is beta software, pre-1.0 (version 0.16.x at the time of writing), published and owned by Google. Expect possible breaking changes before v1.0, budget for the non-trivial native setup, and remember that Android and iOS implementations differ slightly under the hood, so test both platforms.

If your needs are lighter — you just want a map with markers and a route preview — react-native-maps plus the Routes API is the friendlier, Expo-compatible choice. If you need heavy custom map styling or offline navigation, Mapbox's navigation SDK is the comparable rival (Google's engine is online-only). But when you specifically want the exact Google Maps navigation UX, Google's road and traffic data, first-party support, and CarPlay/Android Auto out of the box, this is the package that delivers it without you maintaining a navigation engine forever.

Wrapping Up

@googlemaps/react-native-navigation-sdk is one of those rare libraries that collapses an entire category of hard problems into a handful of method calls. The four-step flow — accept terms, init, set destinations, start guidance — gives you production-grade turn-by-turn navigation, and the simulator makes it pleasant to build against. The cost is real native setup, the New Architecture requirement, and per-destination billing. For logistics, rideshare, delivery, and field-service apps that need the genuine article rather than a route drawn on a map, that is a trade well worth making. Buckle up, point it at a waypoint, and let Google do the driving directions.