Getting started (React Native Navigation SDK)
Contents
The Trimble Maps React Native Navigation SDK wraps the CoPilot Native Nav SDK for Android and iOS. You get turn-by-turn guidance, voice instructions, trip preview, and optional headless navigation while reusing the same @trimblemaps/* packages that power the React Native Maps SDK.
To gain access, contact our Sales team. Your API key must be licensed for Maps SDK and Navigation SDK.
This guide covers installation, authentication, and prerequisites. For your first guided route, see Turn-by-turn navigation.
Packages
Navigation is published as @trimblemaps/navigation-react-native with required peer dependencies. Install and pin one compatible set — do not mix versions across packages.
| Package | Purpose |
|---|---|
@trimblemaps/navigation-react-native
| NavigationView, TripPreviewView, AllInOneView, trips, and navigation session APIs
|
@trimblemaps/account-react-native
| Account initialization and licensing |
@trimblemaps/maps-react-native
| Map rendering inside navigation UI |
@trimblemaps/plugins-react-native
| Route, search, and routing-profile plugins used by navigation |
@trimblemaps/services-react-native
| Routing and webservices support |
Use one compatible range for all five packages — do not use * or mix unrelated version lines. The current release is 1.1.0. Install ^1.1.0 on each package (navigation declares matching peer ranges in package.json).
Packages are published to the Trimble JFrog npm registry, not npmjs.org. After install, confirm peerDependencies in @trimblemaps/navigation-react-native/package.json still match the ranges you use.
Yarn:
yarn add @trimblemaps/navigation-react-native@^1.1.0 \
@trimblemaps/account-react-native@^1.1.0 \
@trimblemaps/maps-react-native@^1.1.0 \
@trimblemaps/plugins-react-native@^1.1.0 \
@trimblemaps/services-react-native@^1.1.0
npm:
npm install @trimblemaps/navigation-react-native@^1.1.0 \
@trimblemaps/account-react-native@^1.1.0 \
@trimblemaps/maps-react-native@^1.1.0 \
@trimblemaps/plugins-react-native@^1.1.0 \
@trimblemaps/services-react-native@^1.1.0
Expo (development build — not Expo Go; see Expo projects):
npx expo install @trimblemaps/navigation-react-native@^1.1.0 \
@trimblemaps/account-react-native@^1.1.0 \
@trimblemaps/maps-react-native@^1.1.0 \
@trimblemaps/plugins-react-native@^1.1.0 \
@trimblemaps/services-react-native@^1.1.0
The navigation example app also uses common React Native libraries for gestures and screens. These are example app dependencies, not additional npm peer requirements of @trimblemaps/navigation-react-native. Add versions that match your React Native or Expo template if your UI needs them:
react-native-gesture-handlerreact-native-reanimatedreact-native-safe-area-contextreact-native-screens
Requirements
| React Native | 0.85.x recommended (minimum 0.80 per package peers) |
| Architecture | New Architecture required (Fabric / TurboModules). Set newArchEnabled=true.
|
| Node | 24+ (some RN templates warn on Node 25; use 24 or 26+ if you see EBADENGINE)
|
| Android | minSdk ≥ 26 for navigation (maps-only apps may use 25; see Maps requirements)
|
| iOS | 15+. Use a physical device or the iOS Simulator on Apple silicon for development. Some Metal-heavy map features may still require a physical device. |
| Access | Trimble Maps API key with Maps and Navigation licenses |
npm registry
@trimblemaps/* packages are published to the public trimblemaps-npm registry on Trimble JFrog. Configure the @trimblemaps scope before install. Full examples are in React Native Maps — npm registry.
For npm:
# .npmrc
@trimblemaps:registry=https://trimblemaps.jfrog.io/artifactory/api/npm/trimblemaps-npm/
Then run yarn install or npm install.
Expo projects
Navigation requires custom native code on both platforms. Expo Go is not supported — use a development build (npx expo run:ios or npx expo run:android).
The @trimblemaps/maps-react-native config plugin adds $RNTM.post_install(installer) during prebuild. The @trimblemaps/navigation-react-native config plugin adds the account, services, plugins, and navigation Podfile hooks ($RNTM_CORE, $RNTM_SERVICES, $RNTP, $RNTN). Add both plugins when you use navigation:
{
"expo": {
"plugins": [
"@trimblemaps/maps-react-native",
"@trimblemaps/navigation-react-native",
[
"expo-build-properties",
{
"android": {
"minSdkVersion": 26,
"extraMavenRepos": [
"https://trimblemaps.jfrog.io/artifactory/android"
]
},
"ios": {
"useFrameworks": "dynamic"
}
}
]
]
}
}
Install expo-build-properties if needed:
npx expo install expo-build-properties
Declare permissions in app.json / app.config.js (android.permissions, ios.infoPlist, and UIBackgroundModes for background location when required).
Recommended order for Expo:
- Configure the npm registry (
.npmrc) and install all five@trimblemaps/*packages. - On macOS, complete iOS Carthage at the app root before
npx expo prebuild. Run prebuild withRNTM_CARTHAGE_BUILD_PATHset (see step 4), or re-runpod installinios/with it set afterward. - Run
npx expo prebuild, thennpx expo run:iosornpx expo run:android.
Do not hand-edit generated native projects for settings that config plugins or expo-build-properties already apply — change app.json / app.config.js and prebuild again.
Android installation
Add the public Trimble JFrog Maven repository so Gradle can resolve native SDK artifacts. Navigation requires minSdk ≥ 26 (maps-only apps may use 25). Use the pattern that matches your React Native template. For Expo, configure Maven and minSdkVersion with expo-build-properties instead of editing Gradle files directly.
allprojects in android/build.gradle
Works with many React Native apps that declare repository blocks on the root project:
allprojects {
repositories {
mavenLocal()
google()
mavenCentral()
maven {
url "https://trimblemaps.jfrog.io/artifactory/android"
}
}
}
settings.gradle (newer Gradle layouts)
If your template centralizes repositories in android/settings.gradle, add the Trimble Maven URL there instead (inside pluginManagement.repositories, dependencyResolutionManagement.repositories, or your project’s equivalent block):
maven {
url "https://trimblemaps.jfrog.io/artifactory/android"
}
Set minSdkVersion = 26 (or higher) in your Android ext block.
The navigation package resolves native artifacts including:
| Component | Version (resolved by package) |
|---|---|
maps-android-sdk
| 2.4.1 |
| Account / services SDKs | 2.2.0 |
navigation:ui and ui-components
| 2.2.0 |
Run yarn install or npm install, then rebuild the Android app.
iOS installation
Navigation requires all five @trimblemaps/* Cartfiles merged, Carthage bootstrap, CocoaPods with RNTM_CARTHAGE_BUILD_PATH set to your Carthage/Build folder, and dynamic frameworks for Trimble xcframeworks. Complete the steps in order. Carthage must finish before pod install.
1. Create a merged Cartfile
After yarn install or npm install, copy binary lines from each package Cartfile under node_modules:
@trimblemaps/account-react-native/Cartfile@trimblemaps/maps-react-native/Cartfile@trimblemaps/plugins-react-native/Cartfile@trimblemaps/services-react-native/Cartfile@trimblemaps/navigation-react-native/Cartfile
Keep one line per framework. When the same framework appears in more than one Cartfile, keep a single line using the higher pinned version — for example TrimbleMapsWebservicesClient is listed in both plugins and services. Package Cartfiles contain only binary lines from Trimble JFrog — do not add third-party github entries (older sample Cartfiles may still list removed dependencies such as Polyline). Use only public Carthage URLs on trimblemaps.jfrog.io unless your license agreement directs otherwise.
Navigation-specific public frameworks include TrimbleMapsNavigation, TrimbleMapsCoreNavigation, and TrimbleMapsNavigationNative (see the navigation package Cartfile for pinned versions).
You can merge with a script from your app root:
for f in node_modules/@trimblemaps/*/Cartfile; do
grep -E '^binary ' "$f"
done | sort -u > Cartfile
2. Run Carthage
From your app root (next to package.json):
carthage bootstrap --platform iOS --use-xcframeworks
Add Carthage/ to .gitignore. See React Native Maps — Run Carthage for Carthage version notes and --project-directory when running from ios/.
3. Podfile, frameworks, and CocoaPods
Set dynamic linking when your template does not already:
export USE_FRAMEWORKS=dynamic
Expo: set "useFrameworks": "dynamic" in expo-build-properties instead of exporting the variable for every shell.
In ios/Podfile post_install, call every Trimble hook that CocoaPods defines for installed packages:
post_install do |installer|
react_native_post_install(installer, config[:reactNativePath], :mac_catalyst_enabled => false)
$RNTM.post_install(installer) if defined?($RNTM) && $RNTM
$RNTM_CORE.post_install(installer) if defined?($RNTM_CORE) && $RNTM_CORE
$RNTM_SERVICES.post_install(installer) if defined?($RNTM_SERVICES) && $RNTM_SERVICES
$RNTP.post_install(installer) if defined?($RNTP) && $RNTP
$RNTN.post_install(installer) if defined?($RNTN) && $RNTN
end
4. Link XCFrameworks for CocoaPods
CocoaPods vendors Trimble XCFrameworks from each package’s ios/Frameworks directory. Each @trimblemaps/* podspec runs a prepare_command during pod install that symlinks frameworks from your Carthage build folder. Set RNTM_CARTHAGE_BUILD_PATH to your app-root Carthage/Build when you run CocoaPods (the navigation pod also accepts RNTN_CARTHAGE_BUILD_PATH):
cd ios
RNTM_CARTHAGE_BUILD_PATH="$(cd .. && pwd)/Carthage/Build" pod install
pod install fails with a clear error if a required framework is missing from that folder. Check that your merged Cartfile includes every framework from all five package Cartfiles and re-run Carthage if needed.
For Expo, set the same variable when you run prebuild:
RNTM_CARTHAGE_BUILD_PATH="$(pwd)/Carthage/Build" npx expo prebuild
See React Native Maps — Link XCFrameworks for the same flow on maps-only apps.
Rebuild after pod install.
Permissions overview
Navigation needs location on both platforms. Declare manifest and plist entries, request runtime permission, and enable iOS background location when you navigate while the app is backgrounded. See Permissions and location.
Authentication
Initialize the account before mounting NavigationView or other navigation UI. Request both licensed features and confirm navigation licensing before starting a session. Run initialization from a useEffect (or similar) — do not use top-level await in a React component file (same pattern as React Native Maps — Authentication).
import { useEffect, useState } from "react";
import {
Account,
AccountManager,
APIEnvironment,
LicensedFeature,
} from "@trimblemaps/account-react-native";
export function App() {
const [ready, setReady] = useState(false);
useEffect(() => {
let cancelled = false;
(async () => {
await AccountManager.initialize(
new Account({
apiKey: "YOUR_TRIMBLEMAPS_API_KEY",
apiEnvironment: APIEnvironment.Production,
licensedFeatures: [
LicensedFeature.MapsSDK,
LicensedFeature.NavigationSDK,
],
}),
);
await AccountManager.awaitInitialization();
const [mapsLicensed, navigationLicensed] = await Promise.all([
AccountManager.isLicensedForMaps(),
AccountManager.isLicensedForNavigation(),
]);
if (!navigationLicensed) {
throw new Error("API key is not licensed for Navigation SDK.");
}
if (!cancelled) {
setReady(mapsLicensed && navigationLicensed);
}
})();
return () => {
cancelled = true;
};
}, []);
if (!ready) {
return null;
}
// Mount NavigationView or request location, then start navigation
return null;
}
TypeScript and Expo
If tsc reports errors inside @trimblemaps/* source files under node_modules (for example 'react-native' has no exported member 'NativeModule' in account or navigation packages), update to package versions that export a top-level "types" condition (current @trimblemaps/* releases). On older builds, set "customConditions": [] in your app’s tsconfig.json so TypeScript uses the published .d.ts files instead of resolving the react-native export to ./src. This affects type-checking only; Metro bundling is unchanged.
Next steps
- Turn-by-turn navigation —
NavigationViewandstartNavigation - Trip preview — review routes before guidance
- All-in-One UI — search, preview, and navigate in one view
- Headless navigation — custom UI with
NavigationSession - React Native Maps SDK — maps-only apps and shared install steps