npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@amrshbib/react-native-geolocation

v2.0.1

Published

React Native geolocation package with FusedLocationProviderClient for high accuracy location tracking

Readme

React Native Geolocation

npm version License: MIT React Native

A high-performance React Native geolocation library with advanced location tracking capabilities using Google's FusedLocationProviderClient for Android and CoreLocation for iOS.

✨ Features

  • 🚀 Cross-Platform: Full support for both Android and iOS
  • 📍 High Accuracy Location: Uses Google's FusedLocationProviderClient on Android
  • 🔄 Background Location: Continuous location tracking in background
  • 🛡️ Smart Permissions: Automatic permission request dialogs with user guidance
  • 🎯 Multiple Providers: GPS, Network, Passive, and Bluetooth-based location
  • Real-time Watching: Continuous location updates with configurable intervals
  • 📝 TypeScript: Complete TypeScript support with type definitions
  • 🔗 Auto-linking: Zero configuration setup for React Native 0.60+
  • 📱 Easy API: Simple getCurrentLocation/watchLocation methods
  • 🔧 Permission Management: Check and request permissions programmatically

📦 Installation

npm install @amrshbib/react-native-geolocation
# or
yarn add @amrshbib/react-native-geolocation

Note: This package is currently in version 0.0.1 and ready for use. The package supports both Android and iOS platforms with comprehensive geolocation capabilities.

React Native 0.60+

This package supports auto-linking. No additional configuration is required.

React Native < 0.60

For older React Native versions, you'll need to manually link the package:

react-native link @amrshbib/react-native-geolocation

🚀 Quick Start

import Geolocation from "@amrshbib/react-native-geolocation";

// Get current location
const getCurrentLocation = async () => {
  try {
    const location = await Geolocation.getCurrentLocation({
      enableHighAccuracy: true,
      timeout: 15000,
      priority: "high_accuracy",
    });

    console.log("Location:", location);
    // {
    //   latitude: 37.7749,
    //   longitude: -122.4194,
    //   altitude: 10.5,
    //   accuracy: 5.0,
    //   heading: 45.0,
    //   speed: 2.5,
    //   timestamp: 1640995200000,
    //   provider: "gps",
    //   fromMockProvider: false,
    //   coords: { ... }
    // }
  } catch (error) {
    console.error("Error getting location:", error);
  }
};

// Watch location changes
const watchLocation = async () => {
  try {
    const watchId = await Geolocation.watchLocation(
      (location, error) => {
        if (error) {
          console.error("Location error:", error);
        } else {
          console.log("Location update:", location);
        }
      },
      {
        enableHighAccuracy: true,
        interval: 1000,
        priority: "high_accuracy",
      }
    );

    // Stop watching after 30 seconds
    setTimeout(() => {
      Geolocation.stopWatching(watchId);
    }, 30000);
  } catch (error) {
    console.error("Error watching location:", error);
  }
};

// Check permissions
const checkPermissions = async () => {
  const permissions = await Geolocation.checkPermissions();
  console.log("Fine location:", permissions.fine);
  console.log("Background location:", permissions.background);
};

// Request permissions
const requestPermissions = async () => {
  const permissions = await Geolocation.requestPermissions();
  if (permissions.fine) {
    console.log("Location permission granted!");
  }
};

📖 API Reference

Geolocation.getCurrentLocation(options)

Get the current location once.

Parameters:

  • options (Object, optional):
    • enableHighAccuracy (boolean): Use high accuracy mode (default: true)
    • timeout (number): Timeout in milliseconds (default: 15000)
    • maximumAge (number): Maximum age of cached location in milliseconds (default: 10000)
    • priority (string): Location priority - 'high_accuracy', 'balanced_power_accuracy', 'low_power', 'no_power' (default: 'high_accuracy')
    • interval (number): Update interval in milliseconds (default: 1000)
    • fastestInterval (number): Fastest update interval in milliseconds (default: 1000)
    • smallestDisplacement (number): Minimum displacement for updates in meters (default: 0)

Returns: Promise<LocationData> - Resolves with location data

Example:

const location = await Geolocation.getCurrentLocation({
  enableHighAccuracy: true,
  timeout: 10000,
  priority: "high_accuracy",
});

Geolocation.watchLocation(callback, options)

Watch for location changes continuously.

Parameters:

  • callback (Function): Function called with (location, error)
    • location: LocationData object or null
    • error: Error string or null
  • options (Object, optional): Same as getCurrentLocation

Returns: Promise<number> - Resolves with watchId

Example:

const watchId = await Geolocation.watchLocation(
  (location, error) => {
    if (error) {
      console.error("Location error:", error);
    } else {
      console.log("New location:", location);
    }
  },
  {
    enableHighAccuracy: true,
    interval: 2000,
    smallestDisplacement: 5,
  }
);

Geolocation.stopWatching(watchId)

Stop watching location changes.

Parameters:

  • watchId (number): The watch ID returned by watchLocation

Returns: Promise<void> - Resolves when watching stops

Example:

await Geolocation.stopWatching(watchId);

Geolocation.checkPermissions()

Check current permission status.

Returns: Promise<{fine: boolean, background: boolean}> - Permission status

Example:

const permissions = await Geolocation.checkPermissions();
console.log("Fine location:", permissions.fine);
console.log("Background location:", permissions.background);

Geolocation.requestPermissions()

Request location permissions from the user.

Returns: Promise<{fine: boolean, background: boolean}> - Permission status after request

Example:

const permissions = await Geolocation.requestPermissions();
if (permissions.fine) {
  console.log("Location permission granted!");
}

Geolocation.isLocationEnabled()

Check if location services are enabled on the device.

Returns: Promise<boolean> - True if location services are enabled

Example:

const enabled = await Geolocation.isLocationEnabled();
if (!enabled) {
  Alert.alert("Location Services", "Please enable location services in settings");
}

🔧 Platform-Specific Setup

Android Setup

The package automatically handles Android configuration, but you need to add location permissions to your android/app/src/main/AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Location permissions -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
</manifest>

iOS Setup

For iOS, you need to add location usage descriptions to your ios/YourApp/Info.plist:

<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location when open.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs access to location when open and in the background.</string>

Optional: For background location tracking, add background modes:

<key>UIBackgroundModes</key>
<array>
    <string>location</string>
</array>

🎯 Use Cases

  • Location Tracking: Track user location for fitness apps
  • Navigation: Real-time navigation and routing
  • Geofencing: Location-based notifications and actions
  • Asset Tracking: Track vehicles, equipment, or packages
  • Social Features: Location-based social networking
  • Emergency Services: Emergency location sharing
  • Delivery Apps: Real-time delivery tracking
  • Weather Apps: Location-based weather information

📱 Example Implementation

import React, { useEffect, useState } from "react";
import { View, Text, TouchableOpacity, Alert } from "react-native";
import Geolocation from "@amrshbib/react-native-geolocation";

const App = () => {
  const [location, setLocation] = useState(null);
  const [permissions, setPermissions] = useState({ fine: false, background: false });
  const [watchId, setWatchId] = useState(null);
  const [isWatching, setIsWatching] = useState(false);

  useEffect(() => {
    checkPermissions();
    return () => {
      if (watchId) {
        Geolocation.stopWatching(watchId);
      }
    };
  }, []);

  const checkPermissions = async () => {
    try {
      const perms = await Geolocation.checkPermissions();
      setPermissions(perms);
    } catch (error) {
      console.error("Error checking permissions:", error);
    }
  };

  const requestPermissions = async () => {
    try {
      const perms = await Geolocation.requestPermissions();
      setPermissions(perms);
      if (perms.fine) {
        Alert.alert("Success", "Location permissions granted!");
      } else {
        Alert.alert("Permission Required", "Please grant location permission to use this feature.");
      }
    } catch (error) {
      Alert.alert("Error", "Failed to request permissions");
    }
  };

  const getCurrentLocation = async () => {
    try {
      if (!permissions.fine) {
        Alert.alert("Permission Required", "Please grant location permission first.");
        return;
      }

      const loc = await Geolocation.getCurrentLocation({
        enableHighAccuracy: true,
        timeout: 15000,
        priority: "high_accuracy",
      });

      setLocation(loc);
      Alert.alert("Success", `Location: ${loc.latitude}, ${loc.longitude}`);
    } catch (error) {
      if (error.message && error.message.includes("permissions not granted")) {
        Alert.alert("Permission Required", "Location permission is required.");
      } else {
        Alert.alert("Error", error.message || "Failed to get location");
      }
    }
  };

  const startWatching = async () => {
    try {
      if (!permissions.fine) {
        Alert.alert("Permission Required", "Please grant location permission first.");
        return;
      }

      const id = await Geolocation.watchLocation(
        (loc, error) => {
          if (error) {
            console.error("Location watch error:", error);
            Alert.alert("Location Error", error);
          } else {
            setLocation(loc);
          }
        },
        {
          enableHighAccuracy: true,
          interval: 1000,
          priority: "high_accuracy",
        }
      );

      setWatchId(id);
      setIsWatching(true);
    } catch (error) {
      Alert.alert("Error", error.message || "Failed to start location watching");
    }
  };

  const stopWatching = () => {
    if (watchId) {
      Geolocation.stopWatching(watchId);
      setWatchId(null);
      setIsWatching(false);
    }
  };

  return (
    <View style={{ flex: 1, padding: 20 }}>
      <Text style={{ fontSize: 24, marginBottom: 20 }}>Geolocation Demo</Text>

      <View style={{ marginBottom: 20 }}>
        <Text>Fine Location: {permissions.fine ? "✅ Granted" : "❌ Denied"}</Text>
        <Text>Background Location: {permissions.background ? "✅ Granted" : "❌ Denied"}</Text>
      </View>

      {!permissions.fine && (
        <TouchableOpacity
          onPress={requestPermissions}
          style={{
            backgroundColor: "#007AFF",
            padding: 15,
            borderRadius: 8,
            marginBottom: 20,
          }}
        >
          <Text style={{ color: "white", textAlign: "center", fontSize: 18 }}>Request Permissions</Text>
        </TouchableOpacity>
      )}

      <TouchableOpacity
        onPress={getCurrentLocation}
        style={{
          backgroundColor: "#34C759",
          padding: 15,
          borderRadius: 8,
          marginBottom: 10,
        }}
      >
        <Text style={{ color: "white", textAlign: "center", fontSize: 18 }}>Get Current Location</Text>
      </TouchableOpacity>

      <TouchableOpacity
        onPress={isWatching ? stopWatching : startWatching}
        style={{
          backgroundColor: isWatching ? "#FF3B30" : "#FF9500",
          padding: 15,
          borderRadius: 8,
          marginBottom: 20,
        }}
      >
        <Text style={{ color: "white", textAlign: "center", fontSize: 18 }}>{isWatching ? "Stop Watching" : "Start Watching"}</Text>
      </TouchableOpacity>

      {location && (
        <View style={{ backgroundColor: "#f0f0f0", padding: 15, borderRadius: 8 }}>
          <Text style={{ fontSize: 18, marginBottom: 10 }}>Current Location:</Text>
          <Text>Latitude: {location.latitude}</Text>
          <Text>Longitude: {location.longitude}</Text>
          <Text>Accuracy: {location.accuracy}m</Text>
          <Text>Speed: {location.speed} m/s</Text>
          <Text>Heading: {location.heading}°</Text>
          <Text>Provider: {location.provider}</Text>
        </View>
      )}
    </View>
  );
};

export default App;

⚠️ Important Notes

Android

  • Uses Google's FusedLocationProviderClient for optimal battery usage
  • Background location requires additional permission on Android 10+
  • Location accuracy depends on GPS signal strength and device capabilities

iOS

  • Uses CoreLocation framework for location services
  • Background location is limited by iOS system policies
  • Location services must be enabled by the user

🔧 Troubleshooting

Permission Denied Error

  1. Check if location permissions are granted
  2. Request permissions using Geolocation.requestPermissions()
  3. Guide user to app settings if permissions are denied

Location Services Disabled

  1. Check if location services are enabled using Geolocation.isLocationEnabled()
  2. Guide user to enable location services in device settings

No Location Updates

  1. Ensure permissions are granted
  2. Check if location services are enabled
  3. Verify GPS signal strength
  4. Try different priority levels

High Battery Usage

  1. Use balanced_power_accuracy or low_power priority
  2. Increase interval and fastestInterval values
  3. Use smallestDisplacement to reduce unnecessary updates

📋 Requirements

  • React Native 0.60+
  • Android API 21+ (Android 5.0+)
  • iOS 10.0+
  • Kotlin support (Android)

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📄 License

The MIT License

Copyright (c) 2024 Amr Shbib [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

🔗 Links


Made with ❤️ for the React Native community