Reviving react-native-mapbox-navigation in 2026

- The original package is still version
2.0.1 and declares React Native 0.66.4 as its development dependency.- The fork added a cross-platform
waypoints prop and native route construction for intermediate stops.- The fork's current repository has no published release, and its visible commit history stops in August 2024. Pinning the default branch is therefore not a safe production dependency strategy.
- The old advice to downgrade React Native because Mapbox supported only NDK 21 is obsolete. Mapbox Navigation SDK v3 now supports NDK 23 and NDK 27 artifacts.
- React Native 0.87 is the current stable release in August 2026, and modern React Native runs only on the New Architecture. A legacy native view wrapper needs a proper Fabric and Codegen migration.
- The fork's Android build still uses Mapbox
3.3.0-rc.1, while current Mapbox installation examples use stable 3.28.x dependencies.- The fork's iOS podspec targets iOS 12.4 and Mapbox Navigation
~> 3.2.1. Current Mapbox Navigation v3 requires iOS 14+, Swift 5.9+ and Xcode 15+, with Swift Package Manager as the documented installation route.- Treat the fork as reference code or a starting point. Audit, migrate and test it against an explicit version matrix before using it in production.
Mapbox provides full Navigation SDKs for Android and iOS, but it does not maintain an official React Native wrapper for turn-by-turn navigation. That leaves React Native teams with three realistic options: write and maintain native bindings, adopt a community wrapper, or fork an existing package and take ownership of its native code.
That third path is what led me to react-native-mapbox-navigation. The original package offered a useful drop-in navigation view, but its React Native, Android, and iOS assumptions were aging. I forked it to modernize parts of the native build, add waypoint support, and keep a real application moving.
The work remains a useful case study, but the ecosystem has moved again. In 2026, the fork should not be presented as a current, install-and-forget package. This article explains what the fork changed, what those changes taught me and what must be updated before using the same approach with a current React Native application.
Why Fork react-native-mapbox-navigation?
The original @homee/react-native-mapbox-navigation package solved a genuine problem: it exposed Mapbox's native turn-by-turn navigation UI as a React Native component on Android and iOS.
Its JavaScript API was simple:
<MapboxNavigation
origin={[-97.760288, 30.273566]}
destination={[-97.918842, 30.494466]}
onArrive={() => console.log("Arrived")}
/>However, the package metadata still points to React Native 0.66.4 for development, TypeScript 4.3.5, and a test command that exits with “no test specified.” Its original iOS podspec targets Mapbox Navigation 2.1.1. Those facts do not make the code useless, but they show that compatibility cannot be inferred from the broad peer dependency of react-native: "*".
The immediate needs behind the fork were practical:
- make the native projects build with a newer application toolchain;
- allow an application to supply intermediate waypoints;
- keep the Android and iOS JavaScript APIs consistent; and
- expose the new prop through TypeScript.
That scope is important. The work revived the package for a particular project and version combination. It did not permanently solve compatibility with every future React Native and Mapbox release.
What the Fork Changed
1. More flexible Android build configuration
The Android module was changed so the host application could provide Kotlin and Android SDK versions. The library falls back to its own properties when the host does not define them:
def kotlin_version = rootProject.ext.has("kotlinVersion")
? rootProject.ext.get("kotlinVersion")
: project.properties["MapboxNavigation_kotlinVersion"]
def getExtOrIntegerDefault(name) {
return rootProject.ext.has(name)
? rootProject.ext.get(name)
: project.properties["MapboxNavigation_" + name].toInteger()
}This is better than hard-coding every version inside a reusable native module because the consuming React Native application should own the final Android toolchain.
The current fork contains these fallback values:
MapboxNavigation_compileSdkVersion=33
MapboxNavigation_kotlinVersion=1.9.22
MapboxNavigation_minSdkVersion=21
MapboxNavigation_targetSdkVersion=33It also contains Android Gradle Plugin 7.2.2 and Gradle Wrapper 7.3.3. Earlier revisions experimented with other Gradle versions, but the current repository does not use the Gradle 8.2 wrapper described in the previous version of this article.
These numbers are historical configuration, not recommendations for a new 2026 library. A maintained package should test against the toolchain generated by the supported React Native releases and avoid forcing an older Android Gradle Plugin on the host project.
2. A waypoint prop on Android
The core feature added by the fork was multi-stop navigation. JavaScript sends an array of coordinates, and the native view manager converts them into Mapbox Point objects.
The coordinate order is [longitude, latitude], matching GeoJSON and the existing origin and destination props.
@ReactProp(name = "waypoints")
fun setWaypoints(
view: MapboxNavigationView,
waypointsArray: ReadableArray?
) {
val points = mutableListOf<Point>()
if (waypointsArray != null) {
for (index in 0 until waypointsArray.size()) {
val coordinate = waypointsArray.getArray(index) ?: continue
if (coordinate.size() < 2) continue
val longitude = coordinate.getDouble(0)
val latitude = coordinate.getDouble(1)
points.add(Point.fromLngLat(longitude, latitude))
}
}
view.setWaypoints(points)
}The navigation view then builds one ordered route:
private fun startRoute() {
val coordinates = mutableListOf<Point>()
origin?.let(coordinates::add)
coordinates.addAll(waypoints.orEmpty())
destination?.let(coordinates::add)
if (coordinates.size < 2) {
sendErrorToReact("A route requires an origin and destination")
return
}
findRoute(coordinates)
}This produces the expected order:
origin → waypoint 1 → waypoint 2 → destinationThe original implementation then passed that list to Mapbox RouteOptions. The design is still valid, but the surrounding callback and route APIs must match the exact Mapbox Navigation SDK version in the project.
3. Equivalent waypoint handling on iOS
On iOS, the prop was exported from Objective-C:
RCT_EXPORT_VIEW_PROPERTY(waypoints, NSArray<NSArray>)The Swift view converted the React Native arrays into Mapbox Waypoint objects:
var routeWaypoints = [originWaypoint]
for item in waypoints {
guard
let coordinate = item as? NSArray,
coordinate.count == 2,
let longitude = (coordinate[0] as? NSNumber)?.doubleValue,
let latitude = (coordinate[1] as? NSNumber)?.doubleValue
else {
continue
}
routeWaypoints.append(
Waypoint(
coordinate: CLLocationCoordinate2D(
latitude: latitude,
longitude: longitude
)
)
)
}
routeWaypoints.append(destinationWaypoint)This kept the JavaScript contract consistent across platforms. A caller did not need separate Android and iOS waypoint formats.
Let’s Build Your React Native App Together!
We build powerful React Native apps that run smoothly on iOS and Android — fast, reliable, and ready to scale.
The fork originally calculated routes with APIs such as Directions.shared.calculate, MapboxNavigationService and the older NavigationViewController initializer. Current Mapbox Navigation v3 uses a different provider-based architecture, including MapboxNavigationProvider, MapboxRoutingProvider and NavigationRoutes. The waypoint conversion can be retained, but the route-calculation and presentation layers need a v3 rewrite.
4. TypeScript support
The public prop was added to the source typings:
export type Coordinate = [longitude: number, latitude: number];
export interface MapboxNavigationProps {
origin: Coordinate;
destination: Coordinate;
waypoints?: Coordinate[];
}That may appear small, but it prevents a common integration failure: native code supports a feature while the JavaScript package rejects or hides it from TypeScript users.
Using the waypoint prop
The final React Native call remains straightforward:
const origin: [number, number] = [-97.760288, 30.273566];
const destination: [number, number] = [-97.918842, 30.494466];
const waypoints: [number, number][] = [
[-97.8012, 30.3104],
[-97.8621, 30.4027],
];
<MapboxNavigation
origin={origin}
waypoints={waypoints}
destination={destination}
onError={({ nativeEvent }) => {
console.error(nativeEvent.message);
}}
/>Validate coordinate length and range before sending the values to native code. A longitude must be between -180 and 180, while a latitude must be between -90 and 90.
The 2026 Compatibility Reality
The most important update to this article is that several earlier conclusions are no longer true.
| Area | Fork repository | Current ecosystem | Practical conclusion |
| React Native | Development dependency 0.66.4 | React Native 0.87 is current in August 2026 | Compatibility with a current app is unproven |
| Architecture | Legacy RCT_EXPORT_VIEW_PROPERTY bridge, plus partial Android New Architecture configuration | React Native 0.82+ runs only on the New Architecture | Complete a Fabric and Codegen migration |
| Android build | AGP 7.2.2, Gradle 7.3.3, SDK 33 | Current React Native uses a newer Android toolchain | Align with the host app rather than pinning the old plugin |
| Android Mapbox | Multiple 3.3.0-rc.1 modules | Official examples use stable Mapbox Navigation 3.28.x | Replace release candidates and migrate changed APIs |
| Android NDK | Previous article described an NDK 21 ceiling | Mapbox v3 supports NDK 23 and NDK 27 artifacts | Do not downgrade React Native for the old NDK issue |
| iOS platform | iOS 12.4 | Mapbox Navigation v3 requires iOS 14+ | Raise the deployment target |
| iOS dependency | CocoaPods MapboxNavigation ~> 3.2.1 | Current v3 installation is documented with Swift Package Manager | Rework dependency integration and native APIs |
| Releases and tests | No fork release; package test script exits | Production libraries need repeatable artifacts and CI | Pinning a branch is insufficient |
The NDK issue is no longer the blocker
The previous article said React Native 0.72.6 used NDK 23 while Mapbox supported only NDK 21, leaving developers to downgrade React Native or wait.
That advice should now be removed. Mapbox's current Android Navigation SDK documentation supports NDK 23 and dedicated NDK 27 artifacts. The NDK 27 artifacts are intended for applications that require 16 KB page-size support.
The modern Android problem is broader version alignment: React Native, the Android Gradle Plugin, Kotlin, the JDK, compile SDK, Mapbox modules and NDK artifacts must be tested as one matrix.
React Native's New Architecture changes the bridge
React Native enabled the New Architecture by default in 0.76. React Native 0.82 removed the option to run the Legacy Architecture, and 0.84 onward continued deleting legacy implementation classes. React Native 0.87 is the current stable release as of August 17, 2026.
The fork's Android Gradle file contains a conditional New Architecture block, but the package metadata does not define a complete Codegen contract, and the iOS view still uses the legacy export macro. That is not enough evidence to claim full compatibility with React Native 0.87.
A maintained version should define a typed native component specification and generate the native interface through React Native Codegen. It must then be tested in Bridgeless mode on both platforms.
Mapbox Navigation v3 is a real migration
Changing a dependency string from Mapbox 2.x to 3.x is not a complete upgrade. Mapbox Navigation v3 reorganized route calculation, navigation lifecycle and UI integration on both Android and iOS.
For iOS, current Mapbox documentation requires Swift 5.9+, Xcode 15+ and iOS 14+. It documents Swift Package Manager for Navigation v3 and routes requests through MapboxNavigationProvider and a routing provider.
For Android, current installation examples use modular com.mapbox.navigationcore dependencies. All selected Mapbox modules should use a compatible stable version. A mix of old adapters, release candidates and current modules can compile but fail at runtime because transitive MapboxCommon, Maps SDK or native binaries do not align.
What a Real 2026 Revival Requires
1. Publish a supported version matrix
Before changing code, choose exact versions for:
- React Native;
- Android Gradle Plugin and Gradle;
- Kotlin and JDK;
- Android compile and target SDKs;
- NDK artifact family;
- Mapbox Navigation, Maps and Common components;
- Xcode, Swift and iOS deployment target; and
- CocoaPods or Swift Package Manager strategy.
“Works with React Native” is not a useful compatibility statement for a native navigation library. Document the tested combinations and reject unsupported ones where possible.
2. Build a Fabric Native Component
Define the props and events in a Codegen specification. At minimum, include:
origin,destinationandwaypoints;- route simulation and voice settings;
- location and route-progress events;
- arrival, cancellation and error events; and
- commands for starting, stopping or replacing a route when those operations cannot be expressed as props.
The native Android view manager and iOS component should implement the generated interface instead of depending only on legacy bridge macros.
3. Migrate Android to stable Mapbox v3 APIs
Replace 3.3.0-rc.1 modules with one tested stable Mapbox version. Use NDK 27 artifacts when the Android release must support 16 KB memory pages; otherwise follow Mapbox's documented NDK 23 path.
Review every observer and lifecycle operation. Navigation views can mount, unmount and remount as React screens change. Registering observers repeatedly without unregistering them can create duplicate events, retained views and difficult-to-reproduce crashes.
At minimum, test:
- route request cancellation;
- activity recreation and backgrounding;
- permission changes;
- rerouting and arrival at intermediate waypoints;
- mounting and unmounting the React component repeatedly; and
- a signed release build on physical arm64 devices.
4. Rebuild the iOS integration around Mapbox v3
Raise the deployment target to iOS 14 or higher and use the current Mapbox v3 installation path. Replace the older Directions.shared.calculate and navigation-service construction with the v3 provider and routing APIs.
Also remove forced casts such as as! CLLocationDegrees from values received across the JavaScript boundary. Validate every coordinate and emit a structured error instead of crashing the application.
The embedded NavigationViewController must follow normal UIKit containment rules and be removed cleanly when the React view unmounts:
navViewController?.willMove(toParent: nil)
navViewController?.view.removeFromSuperview()
navViewController?.removeFromParent()
navViewController = nil5. Add automated tests and CI
The current package has no meaningful test command. A production revival needs several layers:
- TypeScript tests for prop validation and event shapes;
- Android unit tests for coordinate conversion and route assembly;
- iOS unit tests for waypoint conversion and invalid input;
- sample-app build jobs for supported React Native versions;
- Android debug and release builds;
- iOS simulator and archive builds; and
- device-level smoke tests for navigation lifecycle behavior.
Let’s Build Your React Native App Together!
We build powerful React Native apps that run smoothly on iOS and Android — fast, reliable, and ready to scale.
Mapbox requires authenticated artifacts, so CI must provide the Downloads:Read token through encrypted secrets. Never commit the secret download token to the repository. The public access token can be shipped in the app, but it should still be scoped and rotated according to Mapbox's token guidance.
6. Release immutable versions
Installing directly from a moving master branch makes the application build non-reproducible. If a fork has not published an npm release, pin an audited commit:
npm install "github:sarafhbk/react-native-mapbox-navigation#<audited-commit-sha>"Replace the placeholder with the exact commit your team reviewed and tested. For ongoing maintenance, publish semantic versions, release notes and a compatibility table.
Should You Use the Fork Today?
The honest answer depends on the application.
| Situation | Recommendation |
| Maintaining the older app for which the fork was created | It may remain useful if the complete native build is already tested and stable |
| Starting a React Native 0.87 application | Do not assume compatibility; complete the New Architecture and Mapbox v3 migration first |
| Needing waypoint implementation ideas | Use the fork as reference code for the cross-platform prop and coordinate conversion |
| Shipping safety-critical or high-volume navigation | Own the native integration, version matrix, observability and device test suite |
| Wanting a dependency with automatic upgrades | The fork is not currently maintained or released at that level |
The fork's value is the engineering pattern it demonstrates: a small JavaScript API can coordinate two complex native SDKs. Its risk is the same pattern in reverse: every Mapbox, React Native, Gradle, Kotlin, Swift or Xcode change can affect the wrapper.
What I Learned From the Work
React Native reduces duplication at the product layer, but it does not remove native ownership. A turn-by-turn navigation component crosses location permissions, background execution, audio, native view-controller lifecycle, Android observers, binary SDK distribution and platform-specific routing APIs.
The most useful lesson was not a particular Gradle or Kotlin version. It was learning to treat the wrapper as a native product with a JavaScript interface.
That means:
- defining a narrow, typed cross-platform contract;
- keeping coordinate semantics identical on Android and iOS;
- validating at the JavaScript and native boundaries;
- isolating platform-specific lifecycle code;
- testing the complete dependency matrix; and
- being explicit about what is historical, supported or experimental.
The waypoint feature was a successful extension of the package. The next revival, however, requires more than updating a few version numbers. It requires a maintained Fabric component built around current Mapbox Navigation v3 APIs.
Conclusion
Forking react-native-mapbox-navigation helped close a real functionality gap. The work introduced cross-platform waypoint support, improved Android version configurability and showed how to route React Native props into Mapbox's native navigation views.
In 2026, that fork is best treated as a case study and migration starting point. The old NDK limitation has been resolved upstream, while newer challenges have taken its place: React Native's New Architecture, Mapbox Navigation v3, iOS 14+, Swift Package Manager, stable Android modules and repeatable CI.
If I were reviving the library again today, I would begin with a React Native Codegen specification and a tested version matrix. I would then rebuild the Android and iOS implementations around stable Mapbox v3 APIs before publishing an immutable release. That creates a wrapper a team can maintain, rather than another temporary combination of version pins.
Frequently Asked Questions
Does Mapbox provide an official React Native Navigation SDK?
No. Mapbox provides native Navigation SDKs for Android and iOS, but not an official React Native turn-by-turn wrapper. React Native teams must maintain native bindings or evaluate community packages carefully.
Can I use this fork with React Native 0.87?
Do not assume that it works. The repository still reflects older React Native tooling and legacy bridge patterns. React Native 0.87 requires the New Architecture, so test a proper Fabric migration first.
Is the React Native and Mapbox NDK conflict still relevant?
The old NDK 21 limitation is no longer current. Mapbox Navigation SDK v3 supports NDK 23 and dedicated NDK 27 artifacts, including an option for Android 16 KB page-size support.
Does the fork support intermediate waypoints?
Yes. It adds a waypoints prop using [longitude, latitude] pairs and inserts those points between the origin and destination on Android and iOS. Current Mapbox v3 APIs still require migration.
How should I install an unreleased GitHub fork?
Pin an exact reviewed commit rather than a moving branch, retain the commit in your lockfile and reproduce Android and iOS release builds in CI. Re-audit before changing that commit.



