Expo Setup
January 15, 2026 ยท View on GitHub
npx expo install react-native-background-geolocation
npx expo install expo-gradle-ext-vars
Note
If you've not purchased a license, the plugin is fully functional in DEBUG builds so you can try before you buy.
:open_file_folder: app.json
- Add the following
plugins:
{
"expo": {
"name": "your-app-name",
"plugins": [
+ [
+ "react-native-background-geolocation", {
+ "license": "YOUR ANDROID LICENSE KEY"
+ }
+ ],
+ [
+ "expo-gradle-ext-vars", {
+ "googlePlayServicesLocationVersion": "21.1.0"
+ }
+ ]
]
}
}
Polygon Geofencing Support
If you've purchased the Polygon Geofencing add-on for creating geofences of any shape, you can add the "Polygon Geofencing" entitlement to your existing Background Geolocation license key in the Customer Dashboard.
Info.plist: Usage Descriptions
- Add the following Usage Descriptions to the
ios.infoPlistsection: - These strings are used by the OS when requesting permission from the user. It's up to you to re-write these strings as-desired.
{
"expo": {
"name": "your-app-name",
.
.
.
"ios": {
+ "infoPlist": {
+ "NSLocationAlwaysAndWhenInUseUsageDescription": "[CHANGEME] This app requires location in the background",
+ "NSLocationWhenInUseUsageDescription": "[CHANGEME] This app requires location while in use",
+ "NSMotionUsageDescription": "[CHANGEME] This app uses motion-detection to determine the motion-activity of the device (walking, vehicle, bicycle, etc)"
+ }
}
}
}
- If you configure the plugin with
locationAuthorizationRequest: 'WhenInUse', you can omitNSLocationAlwaysAndWhenInUseUsageDescription - If you configure the plugin with
disableMotionActivityUpdates: true, you can omitNSMotionUsageDescription
Info.plist: UIBackgroundModes:
- Add the following
UIBackgroundModesto theios.infoPlistsection:
{
"expo": {
"name": "your-app-name",
.
.
.
"ios": {
"infoPlist": {
"NSLocationAlwaysAndWhenInUseUsageDescription": "[CHANGEME] This app requires location in the background",
"NSLocationWhenInUseUsageDescription": "[CHANGEME] This app requires location while in use",
"NSMotionUsageDescription": "[CHANGEME] This app uses motion-detection to determine the motion-activity of the device (walking, vehicle, bicycle, etc)",
+ "UIBackgroundModes": [
+ "location",
+ "fetch",
+ "processing"
+ ],
+ "BGTaskSchedulerPermittedIdentifiers": [
+ "com.transistorsoft.fetch",
+ "com.transistorsoft.customtask"
+ ]
}
}
}
}
- While field-testing the plugin configured with
debug: true(to enable debug found FX), you can optionally add theUIBackgroundModeaudioso you can hear debug sounds while your app is in the background:
{
"expo": {
"name": "your-app-name",
.
.
.
"ios": {
"infoPlist": {
"NSLocationAlwaysAndWhenInUseUsageDescription": "[CHANGEME] This app requires location in the background",
"NSLocationWhenInUseUsageDescription": "[CHANGEME] This app requires location while in use",
"NSMotionUsageDescription": "[CHANGEME] This app uses motion-detection to determine the motion-activity of the device (walking, vehicle, bicycle, etc)",
"UIBackgroundModes": [
"location",
"fetch",
"processing",
+ "audio"
]
}
}
}
}
Info.plist: iOS License Key
- From the Customer Dashboard, add your iOS license key to your
Info.plist:
{
"expo": {
"name": "your-app-name",
.
.
.
"ios": {
"infoPlist": {
+ "TSLocationManagerLicense": "<YOUR IOS LICENSE KEY>"
}
}
}
}
Re-build
You must rebuild your Android app for the added plugins to be evaluated.
- If you're developing locally:
npx expo prebuild
Note
When using prebuild, you must run your app as follows:
$ npx expo run:android
$ npx expo run:ios
- If you're using Expo EAS, you must first run
eas build. - Adjust
--profileas desired. - You must build ALL platforms, both iOS and Android:
eas build --profile development
react-native-background-fetch
Tip
react-native-background-fetch is helpful for executing a periodic task (eg: every 15 minutes). You could use background-fetch to periodically request the current location:
// Execute a task about every 15 minutes:
BackgroundFetch.configure({
minimumFetchInterval: 15
}, async (taskId) => { // <-- This is your periodic-task callback
const location = await BackgroundGeolocation.getCurrentPosition({
samples: 3,
extras: { // <-- your own arbitrary meta-data
"event": "getCurrentPosition"
}
});
console.log('[getCurrentPosition]', location);
BackgroundFetch.finish(taskId); // <-- signal that your task is complete
})