Expo
How do I get the user's location in an Expo app?
Install expo-location, call requestForegroundPermissionsAsync, and once the status is granted, call getCurrentPositionAsync. It resolves with a LocationObject whose coords hold the latitude and longitude. Add a timeout and fall back to getLastKnownPositionAsync so a slow GPS fix can't stall your screen.
Updated October 31, 2026
If your screen sits on a spinner waiting for a location, or you just want a working example of requestForegroundPermissionsAsync and getCurrentPositionAsync together, the whole thing fits in one short function. All of the code that Draftbit produces for mobile apps is based on React Native and Expo, so this is also how GPS location works in an app built in Draftbit.
How it works
With expo-location, you can read the device’s location on Android, iOS, and web. First you ask for permission to use location while the app is open, which is called foreground permission. Then there are two ways to get a position. getCurrentPositionAsync asks the device for a fresh fix, which can take several seconds and longer indoors. getLastKnownPositionAsync returns the last position the device already has, which is faster but may be out of date, and it can be null.
The accuracy option sets how hard the device tries. The default, Accuracy.Balanced, is accurate to within about 100 meters, Accuracy.High to within 10 meters, and Accuracy.Highest is the best available. Lower settings can skip power-hungry sources like GPS, so we’d pick the lowest one your feature can live with.
How to set it up
-
Install the module with
npx expo install expo-location. -
Write the permission message iOS shows in its prompt, in
app.json. Plugin changes take effect in a new build.{ "expo": { "plugins": [ [ "expo-location", { "locationWhenInUsePermission": "Allow $(PRODUCT_NAME) to use your location to show places near you." } ] ] } } -
Ask for permission and get the position, with a timeout so a slow fix falls back to the last known one:
import * as Location from "expo-location"; export async function getUserLocation() { const { status } = await Location.requestForegroundPermissionsAsync(); if (status !== "granted") return null; const timeout = new Promise<null>((resolve) => setTimeout(() => resolve(null), 10000)); const current = await Promise.race([ Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.Balanced }), timeout, ]); return current ?? (await Location.getLastKnownPositionAsync()); } -
Use it in your screen and read
coords.latitudeandcoords.longitude:const [location, setLocation] = useState<Location.LocationObject | null>(null); useEffect(() => { getUserLocation().then(setLocation); }, []); -
Handle a refusal. The permission response includes
canAskAgain, and when it’sfalse, asking again won’t show a prompt, so offer a button that callsLinking.openSettings()fromreact-nativeinstead.
How you know it works
On a phone, the permission prompt shows your message, and once you allow it, the screen shows coordinates, or the last known position if a fresh fix takes longer than your timeout. In a simulator or emulator, set a location first, since there’s no real GPS. Expo’s location reference lists the steps for both the Android Emulator and the iOS Simulator.
If it still hangs or returns nothing
Check Location.hasServicesEnabledAsync(), which returns false when location services are switched off for the whole phone, and tell the user rather than waiting. There are reports of getCurrentPositionAsync never resolving on some Android devices and emulators, which is why the timeout above is worth keeping. If you get nothing back in the Android Emulator, Expo’s docs say you may have to turn off Improve Location Accuracy in its location settings. And if you need updates while the user moves, use watchPositionAsync, which only runs while the app is in the foreground. Background location needs extra permissions and, on iOS, a development build rather than Expo Go.
Ask the agent
If your app is in Draftbit, paste this into the agent, and it can read your code and make the change for you.
Get the user's current location with expo-location when this screen opens. Ask for permission with a clear message, fall back to the last known location if a fresh one takes too long, and show a button to open Settings if they've denied it.