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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rnpack/location

v0.2.0

Published

Location permissions and adapter state

Readme

@rnpack/location

npm version npm downloads License Platform

A high-performance location tracking and permissions management package for React Native, built using the modern Turbo Modules (New Architecture) framework. It provides smooth, battery-efficient, and precise location tracking across both iOS and Android.


Features

  • ⚡️ Built on Turbo Modules: Next-generation React Native performance with JSI (no JSON bridge serialization overhead).
  • 📍 Precise Tracking: Support for high accuracy, balanced power, and passive location providers.
  • 🔄 Subscription Services: Simple, event-based hooks for location provider status, permission status, and real-time location coordinates.
  • 🛡️ Permission Management: Easy-to-use API for requesting foreground and background permissions, plus helpers to open system settings directly.
  • 📱 Android Foreground Service: Run persistent foreground tracking with standard status-bar notifications (Android Only).
  • 🌌 Background Location Sync: Keep tracking and sync location data directly to your API endpoint in the background (iOS & Android).

Installation

npm install @rnpack/location

or with Yarn:

yarn add @rnpack/location

or with pnpm:

pnpm add @rnpack/location

Platform Setup

iOS Setup

Add the following keys to your ios/YourAppName/Info.plist file with description strings explaining why your app requires these permissions:

<!-- Foreground Location Permission -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>We need access to your location to show local events and route details.</string>

<!-- Background Location Permission -->
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We need continuous access to your location to track your journey even when the app is in the background.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>We need continuous access to your location to track your journey in the background.</string>

For background location tracking, enable Location updates under Signing & Capabilities -> Background Modes in Xcode.


Android Setup

  1. Add permissions to your android/app/src/main/AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Foreground location permissions -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

    <!-- Background location permissions -->
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

    <!-- Foreground Service permissions (For Android Foreground Service) -->
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
    
    <!-- Wake Lock permission for waking up the app -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    
    <!-- Internet permission for background URL sync -->
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>
  1. Register the services, headless JS tasks, and receivers within the <application> tag of your android/app/src/main/AndroidManifest.xml:
<application ...>
    <!-- ... other components ... -->

    <!-- Foreground Location Service -->
    <service
      android:name="com.rnpack.location.services.LocationForegroundService"
      android:exported="false"
      android:foregroundServiceType="location" />
    <service
      android:name="com.rnpack.location.services.ForegroundLocationHeadlessJsTaskService"
      android:exported="false" />

    <!-- Background Location Service & Headless Task -->
    <receiver
      android:name="com.rnpack.location.services.BackgroundLocationReceiver"
      android:exported="false" />
    <service
      android:name="com.rnpack.location.services.BackgroundLocationHeadlessJsTaskService"
      android:exported="false" />

</application>
  1. Add the required dependencies to your android/app/build.gradle:
dependencies {
    // ... other dependencies ...
    implementation('com.google.android.gms:play-services-location:21.3.0')
    implementation('androidx.work:work-runtime-ktx:2.11.2')
}

API Reference

Methods

| Method | Return Type | Platform | Description | | :--- | :--- | :--- | :--- | | requestLocationPermission() | void | Both | Triggers the system dialog to request foreground location permission. | | requestBackgroundLocationPermission() | void | Both | Triggers the system dialog to request background location permission. Note: On Android, this should only be called after normal (coarse/fine) location permission has already been granted. | | isLocationEnabled() | boolean | Both | Checks if system location services (GPS/sensors) are active. | | isLocationAuthorized() | LocationAuthorizedResponse | Both | Checks current status of location permissions for coarse, fine, and iOS-specific states. | | configureLocation(config) | void | Both | Configures parameters for standard location tracking requests. | | getLastLocation() | Promise<LocationResponse> | Both | Resolves the last cached location on the device. Faster and battery-friendly. | | getCurrentLocation(priority?) | Promise<LocationResponse> | Both | Requests a current location update based on the specified priority level. | | getFreshCurrentLocation(priority?) | Promise<LocationResponse> | Both | Bypasses caching and forces a fresh GPS fix from the hardware. | | openLocationProvidersSettings() | void | Both | Directs the user to the device's system Location Provider settings. | | openLocationPermissionsSettings() | void | Both | Directs the user to the application's details screen to adjust permissions. | | subscribeToLocationProvidersChange() | void | Both | Begins monitoring changes in the system location provider status. | | unsubscribeFromLocationProvidersChange() | void | Both | Stops monitoring changes in the system location provider status. | | onLocationProvidersChange(cb) | EventSubscription | Both | Registers a callback for when system location providers turn ON/OFF. | | subscribeToLocationPermissionsChange() | void | Both | Begins monitoring changes in app location permissions. | | unsubscribeFromLocationPermissionsChange() | void | Both | Stops monitoring changes in app location permissions. | | onLocationPermissionsChange(cb) | EventSubscription | Both | Registers a callback to receive permission updates. | | subscribeToLocationChange() | void | Both | Starts active/passive location update streams. | | unsubscribeFromLocationChange() | void | Both | Stops active/passive location update streams. | | onLocationChange(cb) | EventSubscription | Both | Registers a callback to receive location updates. | | startLocationForegroundService() | void | Android Only | Launches a persistent foreground service with a notification. | | stopLocationForegroundService() | void | Android Only | Stops the active foreground service. | | onLocationForegroundServiceChange(cb) | EventSubscription | Android Only | Registers a callback for foreground service location updates. | | wakeUpApp() | void | Android Only | Triggers application wake-up from background state. | | configureBackgroundLocation(config) | void | Both | Configures settings for background tracking and REST API endpoint sync. | | startLocationBackgroundService() | void | Both | Starts background tracking and sync. | | stopLocationBackgroundService() | void | Both | Stops background tracking. | | onBackgroundLocationChange(cb) | EventSubscription | Both | Registers a callback for location updates received in the background. |


Type Definitions

LocationResponse

type LocationResponse = {
  latitude: number;
  longitude: number;
  altitude: number;
  accuracy: number;
  timestamp: number;
};

LocationConfiguration

type LocationConfiguration = {
  priority?: LocationPriority;
  intervalMillis?: number;
  minUpdateIntervalMillis?: number;
  waitForAccurateLocation?: boolean;
  minUpdateDistanceMeters?: number;
  maxUpdateAgeMillis?: number;
  durationMillis?: number;
  maxUpdateDelayMillis?: number;
  granularity?: LocationGranularity;
};

BackgroundLocationConfiguration

type BackgroundLocationConfiguration = {
  url: string; // Endpoint to POST location payload
  priority?: LocationPriority;
  maxUpdateAgeMillis?: number;
  granularity?: LocationGranularity;
  durationMillis?: number;
};

LocationAuthorizedResponse

type LocationAuthorizedResponse = {
  status: boolean; // Generalized permission status
  coarse: boolean; // Android: COARSE permission status
  fine: boolean; // Android: FINE permission status
  iosStatus: IosLocationAuthorizationStatus; // iOS-specific authorization status
};

IosLocationAuthorizationStatus

type IosLocationAuthorizationStatus =
  | 'AuthorizedWhenInUse'
  | 'AuthorizedAlways'
  | 'Restricted'
  | 'Denied'
  | 'NotDetermined';

LocationPriority (Enum)

enum LocationPriority {
  PRIORITY_HIGH_ACCURACY = 100,
  PRIORITY_BALANCED_POWER_ACCURACY = 102,
  PRIORITY_LOW_POWER = 104,
  PRIORITY_PASSIVE = 105,
}

LocationGranularity (Enum)

enum LocationGranularity {
  GRANULARITY_PERMISSION_LEVEL = 0,
  GRANULARITY_COARSE = 1,
  GRANULARITY_FINE = 2,
}

Usage Guide & Code Examples

1. Basic Permission & Location Check

import React, { useEffect, useState } from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import {
  isLocationEnabled,
  isLocationAuthorized,
  requestLocationPermission,
  getCurrentLocation,
  type LocationResponse
} from '@rnpack/location';

export default function App() {
  const [location, setLocation] = useState<LocationResponse | null>(null);

  const fetchLocation = async () => {
    // Check if services are active
    const enabled = isLocationEnabled();
    if (!enabled) {
      console.log('Location services are disabled on this device.');
      return;
    }

    // Check and request permission
    const auth = isLocationAuthorized();
    if (!auth.status) {
      requestLocationPermission();
      return;
    }

    try {
      const result = await getCurrentLocation();
      setLocation(result);
    } catch (error) {
      console.error('Failed to get location:', error);
    }
  };

  return (
    <View style={styles.container}>
      <Button title="Get Current Location" onPress={fetchLocation} />
      {location && (
        <Text style={styles.text}>
          Lat: {location.latitude}, Lon: {location.longitude}
        </Text>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
  text: { marginTop: 20, fontSize: 16 }
});

2. Live Location Subscription

import React, { useEffect } from 'react';
import {
  subscribeToLocationChange,
  unsubscribeFromLocationChange,
  onLocationChange
} from '@rnpack/location';

export function TrackUser() {
  useEffect(() => {
    // 1. Subscribe to updates
    subscribeToLocationChange();

    // 2. Register callback listener
    const subscription = onLocationChange((location) => {
      console.log('New coordinates:', location.latitude, location.longitude);
    });

    return () => {
      // Clean up subscription & event listener
      subscription.remove();
      unsubscribeFromLocationChange();
    };
  }, []);

  return null;
}

3. Background Sync (Android & iOS)

Automatically track location and post coordinates to your API server in the background. Note: On Android, ensure you request and obtain background permission using requestBackgroundLocationPermission() after normal/foreground location permission is already granted before starting this service:

import {
  configureBackgroundLocation,
  startLocationBackgroundService,
  stopLocationBackgroundService,
  onBackgroundLocationChange,
  LocationPriority
} from '@rnpack/location';

// 1. Configure the endpoint and tracking settings
configureBackgroundLocation({
  url: 'https://api.yourdomain.com/user/track-location',
  priority: LocationPriority.PRIORITY_BALANCED_POWER_ACCURACY,
});

// 2. Register a listener to track in-app if desired
const bgSub = onBackgroundLocationChange((location) => {
  console.log('Background location tracked locally:', location);
});

// 3. Start background updates
startLocationBackgroundService();

// 4. Stop service when done
// stopLocationBackgroundService();

4. Foreground Service Tracking (Android Only)

Keep location tracking active in the foreground even when the app is minimized (running with a status bar notification):

import { Platform } from 'react-native';
import {
  startLocationForegroundService,
  stopLocationForegroundService,
  onLocationForegroundServiceChange
} from '@rnpack/location';

function startAndroidTracking() {
  if (Platform.OS !== 'android') {
    console.warn('Foreground location service is only supported on Android.');
    return;
  }

  // Start the service
  startLocationForegroundService();

  // Listen to updates
  const subscription = onLocationForegroundServiceChange((location) => {
    console.log('Foreground Service location update:', location);
  });
}

Contributing

License

MIT

Author

Thank you

Sponsors

Thank you to all our sponsors! Become a sponsor and get your image on our README on GitHub.