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 iconExpo Location

A library that provides access to reading geolocation information, polling current location or subscribing location update events from the device.

Android
iOS
Web
Included in Expo Go
Recommended version:
~56.0.26

expo-location allows reading geolocation information from the device. Your app can poll for the current location or subscribe to location update events.

Installation

Terminal
- npx expo install expo-location
- yarn expo install expo-location
- pnpm expo install expo-location
- bun expo install expo-location

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

app.json
{ "expo": { "plugins": [ [ "expo-location", { "locationAlwaysAndWhenInUsePermission": "Allow $(PRODUCT_NAME) to use your location." } ] ] } }

Configurable properties

NameDefaultDescription
locationAlwaysAndWhenInUsePermission"Allow $(PRODUCT_NAME) to use your location"
Only for: 
iOS

A string to set the NSLocationAlwaysAndWhenInUseUsageDescription permission message.

locationAlwaysPermission"Allow $(PRODUCT_NAME) to use your location"
Deprecated
 • 
Only for: 
iOS

A string to set the NSLocationAlwaysUsageDescription permission message.

locationWhenInUsePermission"Allow $(PRODUCT_NAME) to use your location"
Only for: 
iOS

A string to set the NSLocationWhenInUseUsageDescription permission message.

motionUsagePermission"Allow $(PRODUCT_NAME) to detect your current motion activity"
Only for: 
iOS

A string to set the NSMotionUsageDescription permission message shown when getMotionActivityAsync or watchMotionActivityAsync is called for the first time.

isIosBackgroundLocationEnabledfalse
Only for: 
iOS

A boolean to enable location in the UIBackgroundModes in Info.plist.

isAndroidBackgroundLocationEnabledfalse
Only for: 
Android

A boolean to enable the ACCESS_BACKGROUND_LOCATION permission.

isAndroidForegroundServiceEnabled-
Only for: 
Android

A boolean to enable the FOREGROUND_SERVICE permission and FOREGROUND_SERVICE_LOCATION (required on Android 14 and later when running a location foreground service). Defaults to true if isAndroidBackgroundLocationEnabled is true, otherwise false.

androidForegroundServiceIcon-
Only for: 
Android

Local path to an image to use as the icon for the foreground service started by startLocationUpdatesAsync. 96x96 all-white png with transparency. If not set, falls back to the notification_icon drawable (if configured via expo-notifications config plugin), then to the app launcher icon. The launcher icon is full-color and may render as a solid white square since Android requires notification icons to be monochrome.

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.
  • Android
    A terminated app will not automatically restart when a location or geofencing event occurs due to platform limitations.
  • iOS
    The system will restart the terminated app when a new geofence event occurs.

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:

ios/project-name/Supporting/Expo.plist
<key>UIBackgroundModes</key> <array> <string>location</string> </array>

Background location methods

To use Background Location methods, the following requirements apply:

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:

  • Android
    You are allowed up to 100 active geofences per app.
  • iOS
    Expo Location will report the initial state of the registered geofence(s) at app startup.
  • iOS
    There is a limit of 20 regions that 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 Always option using requestBackgroundPermissionsAsync.
Expo and iOS permissions

iOS permissions are divided into the two categories When In Use and Always and map to Expo's foreground and background location permissions requested via:

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.

Usage

If you're using the Android Emulator or iOS Simulator, ensure that Location is enabled.

Location
import { useState, useEffect } from 'react'; import { Platform, Text, View, StyleSheet } from 'react-native'; %%placeholder-start%%%%placeholder-end%%import * as Device from 'expo-device'; import * as Location from 'expo-location'; export default function App() { const [location, setLocation] = useState<Location.LocationObject | null>(null); const [errorMsg, setErrorMsg] = useState<string | null>(null); useEffect(() => { async function getCurrentLocation() { %%placeholder-start%%%%placeholder-end%%if (Platform.OS === 'android' && !Device.isDevice) { setErrorMsg( 'Oops, this will not work on Snack in an Android Emulator. Try it on your device!' ); return; } let { status } = await Location.requestForegroundPermissionsAsync(); if (status !== 'granted') { setErrorMsg('Permission to access location was denied'); return; } let location = await Location.getCurrentPositionAsync({}); setLocation(location); } getCurrentLocation(); }, []); let text = 'Waiting...'; if (errorMsg) { text = errorMsg; } else if (location) { text = JSON.stringify(location); } return ( <View style={styles.container}> <Text style={styles.paragraph}>{text}</Text> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center', padding: 20, }, paragraph: { fontSize: 18, textAlign: 'center', }, });

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 Device Hub open, go to Device > Location and choose any option besides None.

API

import * as Location from 'expo-location';

No API data file found, sorry!

Permissions

Android

When you install the expo-location module, it automatically adds the following permissions:

  • ACCESS_COARSE_LOCATION: for approximate device location
  • ACCESS_FINE_LOCATION: for precise device location

The following permissions are optional:

Android permissionDescription

ACCESS_COARSE_LOCATION

Allows an app to access approximate location.

ACCESS_FINE_LOCATION

Allows an app to access precise location.

FOREGROUND_SERVICE

Allows a regular application to use Service.startForeground.

FOREGROUND_SERVICE_LOCATION

Allows a regular application to use Service.startForeground with the type "location".

ACCESS_BACKGROUND_LOCATION

Allows an app to access location in the background.

Excluding a permission

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:

Info.plist keyDescription

NSLocationAlwaysAndWhenInUseUsageDescription

A message that tells the user why the app is requesting access to the user’s location information at all times.

NSLocationAlwaysUsageDescription

A message that tells the user why the app is requesting access to the user's location at all times.DeprecatedFor apps deployed to targets in iOS 11 and later, use NSLocationAlwaysAndWhenInUseUsageDescription instead.

NSLocationWhenInUseUsageDescription

A message that tells the user why the app is requesting access to the user’s location information while the app is running in the foreground.

NSLocationAlwaysUsageDescription is deprecated in favor of NSLocationAlwaysAndWhenInUseUsageDescription from iOS 11.