Cross-Platform Maps in React Native: Android, iOS, and Web

All source code and example project is available here: https://github.com/AndreiMaksimovich/react-native-maps-web–demo

AndroidiOSWeb

Give it a try: https://demos.amaxsoftware.com/01.react-native-maps-web/

The Problem

Maps are one of the most common features found in modern applications. In React Native, the default choice for maps is react-native-maps. While it works well on iOS and Android, it doesn’t provide support for the web. In fact, none of the popular, well-established map libraries currently offer proper web build support.

Notice: There is a library called teovillanueva/react-native-web-maps, but it hasn’t been well maintained recently and still offers only very limited functionality.

The Goal

Our objective was to build a simple extension/wrapper for the widely used, de facto standard react-native-maps library. The extension should be as non-intrusive as possible while providing essential features that work seamlessly across Android, iOS, and Web. Specifically, it should:

  1. Display maps consistently on Android, iOS, and Web
  2. Expose an API for basic map interactions, such as changing the camera location
  3. Support displaying map markers
  4. Support polylines for routes
  5. Show the user’s location along with device heading/direction

The Solution

Maps

A simple straightforward way to achieve cross-platform map support is by extending the existing library with our own wrapper. The wrapper proxies the original functionality on Android and iOS, while providing custom components that replicate the same behavior on the Web, with identical or extended properties.

Base Libraries

  • For Android and iOS, we rely on react-native-maps.
  • For the Web, we use vis.gl/react-google-maps.

Project Structure

  • /src/react-native-maps-web/index.ts – Exports components in the same style as react-native-maps. This ensures dependencies can be easily swapped manually, refactored, or aliased in a web bundler.
  • Each proxied component (e.g., Component.tsx) has a web counterpart (Component.web.tsx) that is automatically used when building for web.
  • /src/react-native-web/Types.ts – Defines extended types and properties. Web-specific options are prefixed with web. For example, MapView includes webGoogleMapsApiKey, which is required only for the web implementation (whereas iOS uses a prebuild hardcoded configuration and Android uses its manifest file).

Map Control
The MapView component exposes a mapRef, giving access to the map controller for programmatic interactions. The base interface is defined in Types.ts (Map), with platform-specific implementations in MapRN.ts and MapWeb.ts.

User Location

User location is handled through a custom provider located in /src/foreground-location-provider/.

  • Android & iOS – Powered by the expo-location library.
  • Web – Uses the built-in navigator.geolocation API.

Although expo-location technically works on the web, we found it to be buggy and unreliable, which is why we opted for a native browser implementation instead.

Device Heading

Device heading data comes from another custom provider in /src/device-heading-provider/.

  • Android & iOS – Implemented with react-native-compass-heading.
  • Web – Uses the AbsoluteOrientationSensor API.