This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
Expo Location
A library that provides access to reading geolocation information, polling current location or subscribing location update events from the device.
expo-location allows reading geolocation information from the device. Your app can poll for the current location or subscribe to location update events.
Installation
If you are installing this in an existing React Native app, make sure to install expo in your project.
Configuration in app config
You can configure expo-location using its built-in config plugin if you use config plugins in your project (Continuous Native Generation (CNG)). The plugin allows you to configure various properties that cannot be set at runtime and require building a new app binary to take effect. If your app does not use CNG, then you'll need to manually configure the library.
Example app.json with config plugin
Configurable properties
Are you using this library in an existing React Native app?
If you're not using Continuous Native Generation (CNG) or you're using native ios project manually, then you need to add the NSLocationAlwaysAndWhenInUseUsageDescription, NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription keys to your project's ios/[app]/Info.plist:
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <string>Allow $(PRODUCT_NAME) to use your location</string> <key>NSLocationAlwaysUsageDescription</key> <string>Allow $(PRODUCT_NAME) to use your location</string> <key>NSLocationWhenInUseUsageDescription</key> <string>Allow $(PRODUCT_NAME) to use your location</string>
Background location
Background location allows your app to receive location updates while it is running in the background and includes both location updates and region monitoring through geofencing. This feature is subject to platform API limitations and system constraints:
- Background location will stop if the user terminates the app.
- Background location resumes if the user restarts the app.
- AndroidA terminated app will not automatically restart when a location or geofencing event occurs due to platform limitations.
- iOSThe system will restart the terminated app when a new geofence event occurs.
On Android, the result of removing an app from the recent apps list varies by device vendor. For example, some implementations treat removing an app from the recent apps list as killing it. Read more about these differences here: https://dontkillmyapp.com.
Background location configuration iOS
To be able to run background location on iOS, you need to add the location value to the UIBackgroundModes array in your app's Info.plist file.
If you're using CNG, the required UIBackgroundModes configuration will be applied automatically by prebuild.
Configure UIBackgroundModes manually on iOS
If you're not using Continuous Native Generation (CNG) or you're using a native iOS project, then you'll need to add the following to your Expo.plist file:
Background location methods
To use Background Location methods, the following requirements apply:
- Location permissions must be granted.
- Background location task must be defined in the top-level scope, using
TaskManager.defineTask. - iOS
"location"background mode must be specified in Info.plist file. See Background location configuration. - iOSYou must use a development build to use background location since it is not supported in the Expo Go app.
Geofencing methods
To use Geofencing methods, the following requirements apply:
- Location permissions must be granted.
- The Geofencing task must be defined in the top-level scope, using
TaskManager.defineTask.
When using Geofencing, the following platform differences apply:
- AndroidYou are allowed up to 100 active geofences per app.
- iOSExpo Location will report the initial state of the registered geofence(s) at app startup.
- iOSThere is a limit of 20
regionsthat can be simultaneously monitored.
Background permissions
To use location tracking or Geofencing in the background, you must request the appropriate permissions:
- On Android, you must request both foreground and background permissions.
- On iOS, it must be granted with the
Alwaysoption usingrequestBackgroundPermissionsAsync.
Expo and iOS permissions
iOS permissions are divided into the two categories When In Use and Always and maps to Expo's foreground and background location permissions requested via:
requestForegroundPermissionsAsyncmaps toWhen In UserequestBackgroundPermissionsAsyncmaps toAlways
Note: When requesting
When In Useauthorization, the user can grant temporary access by selectingAllow Oncein the system permission dialog. This authorization will be valid only for the current app session and is automatically revoked when the app is closed.
Detecting "Allow Once" versus "Allow While Using the App"
Unfortunately, iOS does not provide a way to detect whether the user selected Allow Once or Allow While Using the App. Both responses result in When In Use authorization.
If the user selected Allow Once and you subsequently call requestBackgroundPermissionsAsync in the same session, the system will not show another prompt. Instead, the request will silently fail, and the returned background permission status will be denied.
Handling "Allow Once" scenarios
If you suspect the user selected Allow Once and needs to request background permissions, they must manually enable background location in the Settings app. You can use Linking to open the Settings app within your app:
import { Linking } from 'react-native'; function openSettings() { Linking.openURL('app-settings:'); }
Incremental permission requests
It is possible to request foreground location access first and then ask for background location access later. This can improve the user experience by requesting permissions only when necessary.
Requesting Background Permissions directly
If you call requestBackgroundPermissionsAsync without first requesting foreground permissions, iOS treats it as a request for both When In Use and Always authorization. The system will then prompt the user for When In Use access, and the Always authorization prompt will be displayed when the system determines that Always authorization is required.
Remember that the user has the option of granting your app When In Use authorization instead. You must always be prepared to run with When In Use permission.
Deferred locations
When using background locations, you can configure the location manager to defer updates. This helps save battery by reducing update frequency. You can set updates to trigger only after the device has moved a certain distance or after a specified time interval.
Deferred updates are configured through LocationTaskOptions using the deferredUpdatesDistance, deferredUpdatesInterval and deferredTimeout properties.
Deferred locations apply only when the app is in the background.
Usage
If you're using the Android Emulator or iOS Simulator, ensure that Location is enabled.
Enable emulator location
Android Emulator
Open Android Studio, and launch the Android Emulator. Inside it, go to Settings > Location and enable Use location.
If you don't receive the locations in the emulator, you may have to turn off the Improve Location Accuracy setting. This will turn off Wi-Fi location and only use GPS. Then you can manipulate the location with GPS data through the emulator.
For Android 12 and higher, go to Settings > Location > Location Services > Google Location Accuracy, and turn off Improve Location Accuracy. For Android 11 and lower, go to Settings > Location > Advanced > Google Location Accuracy, and turn off Google Location Accuracy.
iOS Simulator
With Simulator open, go to Features > Location and choose any option besides None.
API
import * as Location from 'expo-location';
Hooks
Check or request permissions for the background location.
This uses both requestBackgroundPermissionsAsync and getBackgroundPermissionsAsync to
interact with the permissions.
[PermissionResponse | null, RequestPermissionMethod<PermissionResponse>, GetPermissionMethod<PermissionResponse>]Example
const [status, requestPermission] = Location.useBackgroundPermissions();
Check or request permissions for the foreground location.
This uses both requestForegroundPermissionsAsync and getForegroundPermissionsAsync to interact with the permissions.
[LocationPermissionResponse | null, RequestPermissionMethod<LocationPermissionResponse>, GetPermissionMethod<LocationPermissionResponse>]Example
const [status, requestPermission] = Location.useForegroundPermissions();
Methods
Asks the user to turn on high accuracy location mode which enables network provider that uses Google Play services to improve location accuracy and location-based services.
Promise<void>A promise resolving as soon as the user accepts the dialog. Rejects if denied.
Geocode an address string to latitude-longitude location.
On Android, you must request location permissions with requestForegroundPermissionsAsync
before geocoding can be used.
Note: Geocoding is resource consuming and has to be used reasonably. Creating too many requests at a time can result in an error, so they have to be managed properly. It's also discouraged to use geocoding while the app is in the background and its results won't be shown to the user immediately.
Promise<LocationGeocodedLocation[]>A promise which fulfills with an array (in most cases its size is 1) of LocationGeocodedLocation
objects.
Checks user's permissions for accessing location while the app is in the background.
Promise<PermissionResponse>A promise that fulfills with an object of type PermissionResponse.
Requests for one-time delivery of the user's current location.
Depending on given accuracy option it may take some time to resolve,
especially when you're inside a building.
Note: Calling it causes the location manager to obtain a location fix which may take several seconds. Consider using
getLastKnownPositionAsyncif you expect to get a quick response and high accuracy is not required.
Promise<LocationObject>A promise which fulfills with an object of type LocationObject.
Checks user's permissions for accessing location while the app is in the foreground.
Promise<LocationPermissionResponse>A promise that fulfills with an object of type LocationPermissionResponse.
Gets the current heading information from the device. To simplify, it calls watchHeadingAsync
and waits for a couple of updates, and then returns the one that is accurate enough.
Promise<LocationHeadingObject>A promise which fulfills with an object of type LocationHeadingObject.
Gets the last known position of the device or null if it's not available or doesn't match given
requirements such as maximum age or required accuracy.
It's considered to be faster than getCurrentPositionAsync as it doesn't request for the current
location, but keep in mind the returned location may not be up-to-date.
Promise<LocationObject | null>A promise which fulfills with an object of type LocationObject or
null if it's not available or doesn't match given requirements such as maximum age or required
accuracy.
Check status of location providers.
Promise<LocationProviderStatus>A promise which fulfills with an object of type LocationProviderStatus.
Checks whether location services are enabled by the user.
Promise<boolean>A promise which fulfills to true if location services are enabled on the device,
or false if not.
Promise<boolean>A promise which fulfills with boolean value indicating whether the geofencing task is started or not.
Promise<boolean>A promise which fulfills with boolean value indicating whether the location task is started or not.
Polyfills navigator.geolocation for interop with the core React Native and Web API approach to geolocation.
voidPromise<boolean>Asks the user to grant permissions for location while the app is in the background.
On Android 11 or higher: this method will open the system settings page - before that happens
you should explain to the user why your application needs background location permission.
For example, you can use Modal component from react-native to do that.
Note: Foreground permissions should be granted before asking for the background permissions (your app can't obtain background permission without foreground permission).
Promise<PermissionResponse>A promise that fulfills with an object of type PermissionResponse.
Asks the user to grant permissions for location while the app is in the foreground.
Promise<LocationPermissionResponse>A promise that fulfills with an object of type LocationPermissionResponse.
Reverse geocode a location to postal address.
On Android, you must request location permissions with requestForegroundPermissionsAsync
before geocoding can be used.
Note: Geocoding is resource consuming and has to be used reasonably. Creating too many requests at a time can result in an error, so they have to be managed properly. It's also discouraged to use geocoding while the app is in the background and its results won't be shown to the user immediately.
Promise<LocationGeocodedAddress[]>A promise which fulfills with an array (in most cases its size is 1) of LocationGeocodedAddress objects.
Starts geofencing for given regions. When the new event comes, the task with specified name will
be called with the region that the device enter to or exit from.
If you want to add or remove regions from already running geofencing task, you can just call
startGeofencingAsync again with the new array of regions.
Task parameters
Geofencing task will be receiving following data:
eventType- Indicates the reason for calling the task, which can be triggered by entering or exiting the region. SeeGeofencingEventType.region- Object containing details about updated region. SeeLocationRegionfor more details.
Promise<void>A promise resolving as soon as the task is registered.
Example
import { GeofencingEventType } from 'expo-location'; import * as TaskManager from 'expo-task-manager'; TaskManager.defineTask(YOUR_TASK_NAME, ({ data: { eventType, region }, error }) => { if (error) { // check `error.message` for more details. return; } if (eventType === GeofencingEventType.Enter) { console.log("You've entered region:", region); } else if (eventType === GeofencingEventType.Exit) { console.log("You've left region:", region); } });
Registers for receiving location updates that can also come when the app is in the background.
Task parameters
Background location task will be receiving following data:
locations- An array of the new locations.
Promise<void>A promise resolving once the task with location updates is registered.
Example
import * as TaskManager from 'expo-task-manager'; TaskManager.defineTask(YOUR_TASK_NAME, ({ data: { locations }, error }) => { if (error) { // check `error.message` for more details. return; } console.log('Received new locations', locations); });
Stops geofencing for specified task. It unregisters the background task so the app will not be receiving any updates, especially in the background.
Promise<void>A promise resolving as soon as the task is unregistered.
Stops location updates for specified task.
Promise<void>A promise resolving as soon as the task is unregistered.
Subscribe to compass updates from the device.
Promise<LocationSubscription>A promise which fulfills with a LocationSubscription object.
Subscribe to location updates from the device. Updates will only occur while the application is in
the foreground. To get location updates while in background you'll need to use
startLocationUpdatesAsync.
Promise<LocationSubscription>A promise which fulfills with a LocationSubscription object.
Types
Type of the object containing heading details and provided by watchHeadingAsync callback.
Type representing options object that can be passed to getLastKnownPositionAsync.
LocationPermissionResponse extends PermissionResponse
type exported by expo-modules-core and contains additional platform-specific fields.
Type: PermissionResponse extended by:
Represents the object containing details about location provider.
Represents subscription object returned by methods watching for new locations or headings.
Literal type: union
Permission expiration time. Currently, all permissions are granted permanently.
Acceptable values are: 'never' | number
Literal type: union
Acceptable values are: PermissionHookBehavior | Options
Enums
Enum with available location accuracies.
Enum with available activity types of background location tracking.
ActivityType.Other = 1Default activity type. Use it if there is no other type that matches the activity you track.
ActivityType.AutomotiveNavigation = 2Location updates are being used specifically during vehicular navigation to track location changes to the automobile.
ActivityType.Fitness = 3Use this activity type if you track fitness activities such as walking, running, cycling, and so on.
ActivityType.OtherNavigation = 4Activity type for movements for other types of vehicular navigation that are not automobile related.
A type of the event that geofencing task can receive.
State of the geofencing region that you receive through the geofencing task.
GeofencingRegionState.Unknown = 0Indicates that the device position related to the region is unknown.
Permissions
Android
Foreground and background services are not available in Expo Go for Android. Instead, we recommend using a development build to avoid limitations.
When you install the expo-location module, it automatically adds the following permissions:
ACCESS_COARSE_LOCATION: for approximate device locationACCESS_FINE_LOCATION: for precise device location
The following permissions are optional:
FOREGROUND_SERVICEandFOREGROUND_SERVICE_LOCATION: to be able to access location while the app is open but backgrounded.FOREGROUND_SERVICE_LOCATIONis only required as of Android 14. When you enable this in a new build, you will need to submit your app for review and request access to use the foreground service permission.ACCESS_BACKGROUND_LOCATION: to be able to access location while the app is backgrounded or closed. When you enable this in a new build, you will need to submit your app for review and request access to use the background location permission.
Excluding a permission
Note: Excluding a required permission from a module in your app can break the functionality corresponding to that permission. Always make sure to include all permissions a module is dependent on.
When your Expo project doesn't benefit from having particular permission included, you can omit it. For example, if your application doesn't need access to the precise location, you can exclude the ACCESS_FINE_LOCATION permission.
Another example can be stated using available location accuracies. Android defines the approximate location accuracy estimation within about 3 square kilometers, and the precise location accuracy estimation within about 50 meters. For example, if the location accuracy value is Low, you can exclude ACCESS_FINE_LOCATION permission. To learn more about levels of location accuracies, see Android documentation.
To learn more on how to exclude permission, see Excluding Android permissions.
iOS
The following usage description keys are used by this library:
NSLocationAlwaysUsageDescription is deprecated in favor of NSLocationAlwaysAndWhenInUseUsageDescription from iOS 11.