@baeckerherz/expo-mapbox-navigation
v1.0.6
Published
Expo module for turn-by-turn navigation (Mapbox Navigation SDK v3) on iOS and Android. Alpha. Single MapboxNavigation component, Expo config plugin.
Maintainers
Readme
@baeckerherz/expo-mapbox-navigation
Expo module for turn-by-turn navigation on iOS and Android using Mapbox Navigation SDK v3 (iOS) / Android. Single MapboxNavigation component, Expo config plugin for credentials, no vendored binaries. Minimal alternative to existing community wrappers.
Alpha — iOS is working in our builds; Android is not yet working (dependency resolution / Mapbox Maven). We need help to get Android over the line. APIs may change. Contributions welcome. Open an issue or reach out.
Package summary: Expo config plugin + native module; Mapbox Navigation SDK v3; iOS (SPM) and Android (Maven, drop-in NavigationView); turn-by-turn driving/walking/cycling; requires Expo ≥51, React Native ≥0.74, Mapbox public + secret tokens; alpha stage; TypeScript API via MapboxNavigation component.
Table of contents
- Prerequisites
- Installation
- Usage
- API
- Architecture
- Why this exists
- Comparison
- Status
- Contributing
- License
- Sponsors
Prerequisites
- Mapbox account with Navigation SDK access
Mapbox requires two tokens (create both in your Mapbox tokens page):
| Token | Prefix | Purpose |
|-------|--------|---------|
| Public (access) token | pk.xxx | Used by the app at runtime: map tiles, Directions API, voice, etc. Set as mapboxAccessToken in the plugin. |
| Secret (downloads) token | sk.xxx | Used only at build time: Gradle (Android) and SPM (iOS) use it to download the Navigation SDK from Mapbox. Must have Downloads:Read scope. Not used by the app at runtime. |
The same secret token is used for both platforms. For EAS Build, one EAS secret (e.g. MAPBOX_DOWNLOADS_TOKEN or MAPBOX_SECRET_TOKEN) can back both: iOS needs it in ~/.netrc for SPM; Android needs it in gradle.properties (the plugin writes it from mapboxSecretToken) and, when using centralized repo resolution, as env var MAPBOX_DOWNLOADS_TOKEN.
iOS: Add the secret token to
~/.netrcso SPM can download the SDK (local dev and EAS Build):machine api.mapbox.com login mapbox password YOUR_SECRET_TOKENAndroid: The plugin writes
mapboxSecretTokentoandroid/gradle.propertiesasMAPBOX_DOWNLOADS_TOKENso Maven can download the SDK. For EAS Build, also setMAPBOX_DOWNLOADS_TOKENas an EAS secret so the build can authenticate.
Installation
npx expo install @baeckerherz/expo-mapbox-navigationAdd the plugin in app.config.ts (or app.json). Prefer environment variables for tokens so you don’t commit secrets:
plugins: [
["@baeckerherz/expo-mapbox-navigation/plugin", {
mapboxAccessToken: process.env.MAPBOX_ACCESS_TOKEN,
mapboxSecretToken: process.env.MAPBOX_SECRET_TOKEN,
navigationSdkVersion: "3.5.0",
}],
]Rebuild native projects:
npx expo prebuild --clean
npx expo run:ios
npx expo run:androidUsage
import { MapboxNavigation } from '@baeckerherz/expo-mapbox-navigation';
<MapboxNavigation
coordinates={[
{ latitude: 47.2692, longitude: 11.4041 },
{ latitude: 48.2082, longitude: 16.3738 },
]}
locale="de"
onRouteProgressChanged={(e) => {
console.log(e.nativeEvent.distanceRemaining);
}}
onCancelNavigation={() => navigation.goBack()}
onFinalDestinationArrival={() => console.log('Arrived!')}
style={{ flex: 1 }}
/>API
Props
Route
| Prop | Type | Description |
|------|------|-------------|
| coordinates | Array<{ latitude, longitude }> | Route waypoints (min 2). First = origin, last = destination. |
| waypointIndices | number[] | Indices in coordinates that are full waypoints (with arrival notification). Others are via-points. Must include first and last. |
| routeProfile | string | Routing profile. iOS: "mapbox/driving-traffic" (default), "mapbox/driving", "mapbox/walking", "mapbox/cycling". Android: omit "mapbox/" prefix. |
Localization
| Prop | Type | Description |
|------|------|-------------|
| locale | string | BCP 47 language for voice and UI (e.g. "de", "en-US"). Default: device locale. |
| mute | boolean | Mute voice guidance. Default: false. |
Appearance
| Prop | Type | Description |
|------|------|-------------|
| mapStyle | string | Mapbox style URL. Example: "mapbox://styles/mapbox/navigation-night-v1". |
| themeMode | "day" \| "night" \| "auto" | Day (default), night, or auto by time. |
| accentColor | string | Primary accent (hex). Example: "#007AFF". |
| routeColor | string | Route line color (hex). Overrides accentColor for the line. |
| bannerBackgroundColor | string | Instruction banner background (hex). |
| bannerTextColor | string | Instruction banner text (hex). |
Events
| Event | Payload | Description |
|-------|---------|-------------|
| onRouteProgressChanged | { distanceRemaining, durationRemaining, distanceTraveled, fractionTraveled } | Progress along the route. |
| onCancelNavigation | — | User cancelled. |
| onWaypointArrival | { waypointIndex } | Reached an intermediate waypoint. |
| onFinalDestinationArrival | — | Reached final destination. |
| onRouteChanged | — | Route recalculated (reroute). |
| onUserOffRoute | — | User left the route. |
| onError | { message } | Navigation error. |
Architecture
iOS — SPM via config plugin
Mapbox Navigation SDK v3 is SPM-only. The Expo config plugin injects SPM package references into the Xcode project at prebuild. Version bumps are a single string change; no vendored xcframeworks.
Android — Drop-in NavigationView
We wrap the Nav SDK v3 NavigationView directly instead of rebuilding the UI.
Both — Expo Module APIexpo-modules-core for native bridging: Fabric/New Architecture, type-safe props and events, and compatibility with Expo and bare React Native.
Why this exists
Existing wrappers have major drawbacks:
- @badatgil/expo-mapbox-navigation: Vendored
.xcframeworkon iOS (fragile; manual rebuild per SDK update). Android uses ~30 custom Kotlin components (~1100 LOC) instead of Mapbox’s drop-in view. - @homee/react-native-mapbox-navigation: Unmaintained (no activity since 2022), Nav SDK v2.1.1, no Expo, crashes on Android 13+.
Comparison
| | This module | @badatgil/expo-mapbox-navigation | @homee/react-native-mapbox-navigation | |---|---|---|---| | iOS | SPM via config plugin | Vendored .xcframeworks | CocoaPods, Nav SDK v2 | | Android | Drop-in NavigationView | Custom UI (~1100 LOC) | Custom UI (~500 LOC) | | Nav SDK | v3 | v3 | v2 (legacy) | | Expo Module API | Yes (Fabric-ready) | Yes | No | | Multi-waypoint | Yes | Yes | No | | Maintenance | Active | Semi-active | Abandoned |
Status
Alpha. Platform status:
| Platform | Status | Notes | |----------|--------|-------| | iOS | Working (Alpha) | SPM via config plugin; tested in our project builds. | | Android | Not yet working | Mapbox Maven / dependency resolution issues; help wanted to fix. |
Goals: reliable SPM injection (iOS), drop-in NavigationView/NavigationViewController, event bridging. We want more feedback and testing. For prerelease we may publish under the alpha npm tag.
Help wanted — especially to get Android builds working (Gradle, Mapbox repo auth, or switching to ui-components if the drop-in artifact is unavailable).
Known risks
- Android: Build and dependency resolution need community input.
- Licensing: Mapbox Navigation SDK requires a commercial Mapbox license; this wrapper does not change that.
Contributing
We welcome contributors and maintainers. If you work on Expo native modules, Mapbox SDKs, or React Native tooling, we’d love your help. If you or your company use this package, we’d love to hear from you (issues, discussions, or [email protected]) — it helps us prioritize and justify ongoing work.
Project layout: src/ (TypeScript API), ios/ (Swift + podspec), android/ (Kotlin + build.gradle), plugin/ (Expo config plugins), example/ (test app).
Run the example:
git clone https://github.com/baeckerherz/expo-mapbox-navigation.git
cd expo-mapbox-navigation && yarn install
cd example && yarn install
npx expo prebuild --clean
npx expo run:ios --device # or: npx expo run:androidThe example navigates from your location to Innsbruck Hauptbahnhof with German voice guidance.
Open an issue or submit a PR to get started.
License
Who uses this
We’d like to list teams and projects using this package (with your permission). If you’re using it, open an issue or email [email protected].
Sponsors
Bäckerherz — Founding sponsor. They build and use this module; the project exists thanks to their investment in open-source Expo tooling.
TourenFlow — Intelligent tour planning and route optimization.
To support the project or work with us: [email protected].
