Simple to use React Native library to get native device location for Android and iOS.
React Native Get Location provides a streamlined, lightweight API to request the device's current native location on Android and iOS. With zero bloat, native New Architecture (TurboModule) support, and unified error handling, obtaining a reliable GPS or network fix has never been easier.
Quick Start · Why · Requirements · Installation · Platform Configuration · Usage · API · Error Codes · Contributing
# 1. Install dependency
yarn add react-native-get-location
# or: npm i -S react-native-get-location
# 2. Install native CocoaPods dependencies (iOS)
cd ios && pod installimport GetLocation, { Location, isLocationError } from 'react-native-get-location';
try {
const location: Location = await GetLocation.getCurrentPosition({
enableHighAccuracy: true,
timeout: 60000,
});
console.log('Current coordinates:', location.latitude, location.longitude);
} catch (error) {
if (isLocationError(error)) {
const { code, message } = error;
console.warn(`Location Error [${code}]:`, message);
} else {
console.warn('Unexpected error:', error);
}
}
- ⚡ Zero Bloat & No Heavy SDKs. Relies strictly on Android's native
LocationManagerand iOS'sCLLocationManager. No Google Play Services dependencies or bulky binary frameworks required. - 🏎️ New Architecture Ready (TurboModule). Engineered with React Native Codegen specs. Enjoy C++ TurboModule performance on New Architecture with seamless backward compatibility on the legacy bridge.
- 🎯 Single Deterministic Call. Avoid complex stream subscriptions when you only need a single location fix. Call
GetLocation.getCurrentPosition()and receive a strongly-typedPromise<Location>. - 🛡️ Normalized Error Handling. Cross-platform parity across all failure states with unified error codes:
CANCELLED,UNAVAILABLE,TIMEOUT, andUNAUTHORIZED. - 📱 Built-in Android Permissions & Rationale. Automatically requests fine or coarse permissions at runtime on Android, with native support for permission rationale dialogs.
- ⚙️ Direct Settings Deep Link. Includes
GetLocation.openSettings()to quickly redirect users to your app's system settings if permissions were permanently denied. - 🔋 Battery Efficient. Automatically unregisters native location listeners as soon as the first valid fix is acquired or the timeout expires.
| Requirement | Supported Version |
|---|---|
| React Native | >= 0.71.0 |
| iOS | >= 14.0 |
| Android | >= API 21 (Android 5.0 Lollipop) |
| Architecture | Both New Architecture (TurboModule) & Legacy Architecture |
Using yarn:
yarn add react-native-get-locationUsing npm:
npm i -S react-native-get-locationNavigate to your ios folder and run pod install:
cd ios && pod installNote
If your project uses the New Architecture (RCT_NEW_ARCH_ENABLED=1), CocoaPods will automatically configure the TurboModule spec provider RNGetLocationTurbo.
Add the required permissions inside android/app/src/main/AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Define ACCESS_FINE_LOCATION if you will use enableHighAccuracy=true (GPS) -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Define ACCESS_COARSE_LOCATION if you will use enableHighAccuracy=false (Wifi, Cellular) -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application ...>
...
</application>
</manifest>Important
- If you configure
enableHighAccuracy: true, you must includeACCESS_FINE_LOCATION. - If you configure
enableHighAccuracy: false, you must include at leastACCESS_COARSE_LOCATION.
Open ios/YourAppName/Info.plist and add the NSLocationWhenInUseUsageDescription key with a user-facing explanation:
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app requires access to your location to show nearby services.</string>
import React, { useState } from 'react';
import { View, Text, Button, ActivityIndicator, StyleSheet } from 'react-native';
import GetLocation, { Location, LocationErrorCode, isLocationError } from 'react-native-get-location';
export default function LocationScreen() {
const [loading, setLoading] = useState(false);
const [location, setLocation] = useState<Location | null>(null);
const [errorCode, setErrorCode] = useState<LocationErrorCode | null>(null);
const requestPosition = async () => {
setLoading(true);
setLocation(null);
setErrorCode(null);
try {
const position = await GetLocation.getCurrentPosition({
enableHighAccuracy: true,
timeout: 30000,
});
setLocation(position);
} catch (error) {
if (isLocationError(error)) {
setErrorCode(error.code);
console.warn('Location Error:', error.code, error.message);
} else {
console.warn('Unknown error:', error);
}
} finally {
setLoading(false);
}
};
return (
<View style={styles.container}>
<Button title="Get Current Location" onPress={requestPosition} disabled={loading} />
{loading && <ActivityIndicator style={styles.spacing} />}
{location && (
<View style={styles.card}>
<Text>Latitude: {location.latitude}</Text>
<Text>Longitude: {location.longitude}</Text>
<Text>Accuracy: ±{location.accuracy}m</Text>
<Text>Altitude: {location.altitude}m</Text>
<Text>Speed: {location.speed} m/s</Text>
<Text>Time: {new Date(location.time).toLocaleString()}</Text>
</View>
)}
{errorCode && <Text style={styles.errorText}>Error Code: {errorCode}</Text>}
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 16 },
spacing: { marginTop: 16 },
card: { marginTop: 16, padding: 16, backgroundColor: '#f0f4f8', borderRadius: 8 },
errorText: { marginTop: 16, color: '#e53e3e', fontWeight: 'bold' },
});You can balance precision and battery speed using enableHighAccuracy:
// 1. High Accuracy (GPS fix)
const preciseLocation = await GetLocation.getCurrentPosition({
enableHighAccuracy: true,
timeout: 60000,
});
// 2. Coarse Accuracy (Cell tower, Wi-Fi, faster fix, lower battery consumption)
const quickLocation = await GetLocation.getCurrentPosition({
enableHighAccuracy: false,
timeout: 15000,
});On Android, you can provide an explanation dialog before prompting the system permission modal:
const location = await GetLocation.getCurrentPosition({
enableHighAccuracy: true,
timeout: 60000,
rationale: {
title: 'Location Permission',
message: 'We need your location to show places near you.',
buttonPositive: 'Grant Permission',
buttonNegative: 'Cancel',
},
});When a user permanently denies location permission, GetLocation.getCurrentPosition() rejects with error code 'UNAUTHORIZED'. You can prompt the user and deep-link directly into system settings via GetLocation.openSettings():
try {
const loc = await GetLocation.getCurrentPosition({
enableHighAccuracy: true,
timeout: 30000,
});
} catch (error) {
if (isLocationError(error) && error.code === 'UNAUTHORIZED') {
// Direct user to system settings to grant permission manually
GetLocation.openSettings();
}
}For a complete working sample, explore the Sample Project.
All methods, types, and error helpers are exported from 'react-native-get-location'.
Requests the device's current geographical fix and returns a Promise that resolves with a Location object.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
options |
GetCurrentPositionOptions |
No | Configuration object for accuracy, timeout, and Android rationale. |
Returns:
Promise<Location>: Resolves to the currentLocationfix. Rejects withLocationError.
Opens the current application's system settings screen (e.g. to enable location permissions manually). Calls React Native's Linking.openSettings() under the hood.
Configuration options passed to GetLocation.getCurrentPosition().
| Property | Type | Default | Description |
|---|---|---|---|
enableHighAccuracy |
boolean |
false |
When true, uses fine location (GPS). When false, uses coarse location (Wi-Fi, Bluetooth, 3G/4G). |
timeout |
number |
60000 |
Maximum duration (in milliseconds) to wait for a location fix before throwing a TIMEOUT error. |
rationale? |
Rationale |
undefined |
(Android only) Custom rationale dialog options passed to React Native's PermissionsAndroid.request(). |
The resolved geolocation object.
| Property | Type | Platform | Description |
|---|---|---|---|
latitude |
number |
Both | The latitude, in degrees. |
longitude |
number |
Both | The longitude, in degrees. |
altitude |
number |
Both | The altitude if available, in meters above the WGS 84 ellipsoid. |
accuracy |
number |
Both | Estimated horizontal accuracy of the fix, radial, in meters. |
speed |
number |
Both | Ground speed if available, in meters/second. |
time |
number |
Both | UTC timestamp of this fix, in milliseconds since Unix Epoch. |
bearing |
number? |
Android only | Direction of travel in degrees (0.0 to 359.9). |
provider |
string? |
Android only | Name of the native provider that generated this fix (e.g., 'gps', 'network'). |
verticalAccuracy |
number? |
iOS only | Vertical accuracy of the altitude in meters. Negative if invalid. |
course |
number? |
iOS only | Course in degrees true North (0.0 to 359.9). Negative if invalid. |
Custom error instance thrown when location acquisition fails.
export class LocationError extends Error {
code: LocationErrorCode;
}Type guard utility to determine if an unknown caught exception is a LocationError.
When a position request fails, the promise rejects with a LocationError containing one of the following normalized codes:
| Code | Canonical Message | Cause & Recommended Action |
|---|---|---|
CANCELLED |
"Location cancelled by user or by another request" |
A new getCurrentPosition call was triggered before the previous one completed. Avoid duplicate simultaneous requests. |
UNAVAILABLE |
"Location service is disabled or unavailable" |
Location services / GPS hardware are turned off in system settings or unavailable on the device. Prompt user to turn location services on. |
TIMEOUT |
"Location timed out" |
The device could not acquire a satellite or network fix within the configured timeout window. Increase timeout or toggle enableHighAccuracy. |
UNAUTHORIZED |
"Location permission denied by the user" |
The user denied location permissions. Use GetLocation.openSettings() to guide the user to the app permissions settings screen. |
New features, bug fixes, and documentation improvements are welcome!
- Fork the repository and create a descriptive topic branch.
- Ensure TypeScript builds cleanly (
yarn build). - Open a pull request describing your changes.
For questions and suggestions, please open an issue.
If this library saved you time, consider supporting the maintainer:
The MIT License (MIT)
Copyright (c) 2019 Douglas Nassif Roma Junior
See the full license file.
Discover more open-source libraries, creative animation engines, and developer tools at douglasjunior.work.