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

rn-bg-geolocation

v0.1.11

Published

Free background geolocation for React Native (Android + iOS): motion-aware tracking, geofencing, SQLite queue, HTTP sync. API-compatible with react-native-background-geolocation, no license key.

Readme

rn-bg-geolocation

Free background geolocation for React Native — Android + iOS — with motion-aware tracking, geofencing, a SQLite queue and HTTP sync. No license key, no paid tier.

The API mirrors @transistorsoft/react-native-background-geolocation (ready / start / stop / onLocation / onMotionChange / onGeofence …), so most example code for that SDK works by changing only the import.

  • Android: FusedLocationProvider + foreground service + Activity Recognition + SQLite + OkHttp.
  • iOS: CLLocationManager + CoreMotion + region monitoring + SQLite + URLSession.

Install

npm install rn-bg-geolocation

iOS

cd ios && pod install

Add to Info.plist:

<key>NSLocationWhenInUseUsageDescription</key>
<string>We record your trips.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We record your trips in the background.</string>
<key>NSMotionUsageDescription</key>
<string>Used to detect when you start and stop moving.</string>
<key>UIBackgroundModes</key>
<array>
  <string>location</string>
  <string>fetch</string>
</array>

Background Fetch (optional, iOS). To let iOS wake the app ~15 minutes after it was suspended, forward the fetch callback in your AppDelegate:

import rn_bg_geolocation

override func application(_ application: UIApplication,
                          didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
  BgGeo.launchedForLocationEvent = launchOptions?[.location] != nil
  // ...your existing setup
}

override func application(_ application: UIApplication,
                          performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
  BgGeo.handleBackgroundFetch(completionHandler)
}

Android is autolinked — the library manifest merges the required permissions and the foreground service. No manual steps.

Quick start

import BackgroundGeolocation from 'rn-bg-geolocation';

await BackgroundGeolocation.ready({
  distanceFilter: 10,
  interval: 5000,
  desiredAccuracy: BackgroundGeolocation.DesiredAccuracy.High,
  stopOnTerminate: false,
  startOnBoot: true,
  url: 'https://your-server.com/locations',
  autoSync: true,
});

await BackgroundGeolocation.start();

BackgroundGeolocation.onLocation((location) => {
  console.log('location', location.coords.latitude, location.coords.longitude);
});
BackgroundGeolocation.onMotionChange((event) => console.log('moving', event.isMoving));
BackgroundGeolocation.onGeofence((event) => console.log('geofence', event.identifier, event.action));

The server receives:

{ "location": { "uuid": "...", "timestamp": 1792552293211, "device_id": "...",
  "coords": { "latitude": 21.56, "longitude": 105.85, "speed": 1.2, "accuracy": 8 },
  "odometer": 428, "activity": { "type": "on_foot" }, "battery": { "level": 0.9 } } }

A ready-to-run Node.js server + Leaflet map viewer is included in the demo repo (geo-server/, pure Node, no dependencies).

API

ready, start, stop, getState, getConfig, setConfig, reset, getCurrentPosition, changePace, watchPosition, startWatchPosition, stopWatchPosition, addGeofence, addGeofences, removeGeofence, removeGeofences, getGeofences, getGeofence, geofenceExists, getGeofenceStats, getLocations, getCount, insertLocation, destroyLocation, destroyLocations, sync, getOdometer, setOdometer, resetOdometer, hasPermission, requestPermission, getProviderState, getDeviceInfo, getSensors, isPowerSaveMode, getConnectivityInfo, startBackgroundTask, endBackgroundTask, getSchedule, startSchedule, stopSchedule, playSound, getLogPath, getLogSize, getLog, clearLog, destroyLog, setLogLevel.

Events: onLocation, onMotionChange, onGeofence, onGeofencesChange, onHttp, onEnabledChange, onActivityChange, onConnectivity, onPowerSaveChange, onProviderChange, onAuthorization, onHeartbeat, onLocationFilter, onSchedule.

Full option list with JSDoc: types.d.ts.

Key options

| Option | Default | Notes | |---|---|---| | distanceFilter | 10 | Android + iOS (iOS is distance-based only) | | interval / locationUpdateInterval | 5000 | Android only | | desiredAccuracy | high | high / balanced / low | | stopTimeout | 5 | Minutes of stillness before location services turn off | | stationaryRadius | 150 | Radius used to detect "leaving the spot" (native fence min 100 m) | | stopOnTerminate | false | false = resume tracking after the OS relaunches the app (iOS registers a fence before termination) | | startOnBoot | true | Android: restart after reboot. iOS: resumes on the next wake | | pauseInsideGeofence | false | Do not record while standing inside a fence | | zeroLossMode | false | Never stop GPS while stationary (battery heavy) | | preventSuspend | false | iOS: keep the app alive after GPS off (battery heavy, arrow stays on) | | stationaryLowPowerGps | false | iOS: keep a coarse 100 m location while stationary (arrow stays on; faster "left the spot" detection) | | backgroundActivitySession | false | iOS 17+: hold a CLBackgroundActivitySession so iOS does not suspend the app — blue pill always visible. Turn on only when you need a gap-free journey | | safetyGeofenceIntervalMinutes | 5 | iOS: move the "last known position" geofence while moving | | backgroundFetchIntervalMinutes | 15 | iOS: background fetch interval (0 = off) | | geofenceProximityRadius | 1000 | Only fences within this radius are registered with the OS (iOS allows 20 regions) | | geofenceNotifications | true | System notification on geofence ENTER/EXIT | | insideWatchdogMinutes | 10 | iOS: while parked inside a fence, take one coarse sample every N minutes | | providerSilenceMinutes | 3 | Android: no samples while moving → re-arm the provider and log a gap diag | | elasticityMultiplier | 1 | Android: distanceFilter follows speed | | autoSync / batchSync / maxBatchSize | true / false / 500 | HTTP queue | | filter.policy | adjust | adjust = Kalman + spike rejection, passThrough | | logToFile / postDiagEvents | false / false | rnbggeo.log + <url>/diag |

iOS background behaviour

  • After stopTimeout minutes of stillness the library turns location services off (the status-bar arrow disappears), registers a geofence around the last known position and keeps significant-location monitoring. Leaving that geofence wakes the app and tracking resumes — the same model as react-native-background-geolocation.
  • That fence is re-centred whenever tracking starts, while moving every safetyGeofenceIntervalMinutes, and immediately when the app leaves the foreground or is about to terminate — so a region always exists where the device actually was.
  • iOS may relaunch a terminated app when a location event arrives; with stopOnTerminate: false the library resumes tracking even before JS runs. Measured on a real device: iOS relaunched the app 10 times within 3 hours after it had been force-quit.
  • Apple grants continuous background location only when startUpdatingLocation() was called while the app was in the foreground. An app that is woken into the background gets a short run and is suspended again — so a gap-free journey needs the app to be opened once at the start of the trip. backgroundActivitySession: true (iOS 17+) removes that requirement, at the cost of a permanently visible blue pill.
  • The status-bar location arrow is shown by iOS whenever location services are active and cannot be hidden by an app. showsBackgroundLocationIndicator (default false) only controls the blue background banner.

Attendance / check-in use case

Geofence ENTER/EXIT is evaluated by the library on every GPS sample (real radius — circle or polygon), not by the coarse native region: the native region is only the wake-up alarm. Recommended "battery first, zone check-in only" configuration:

await BackgroundGeolocation.ready({
  stopOnTerminate: false,           // keep tracking alive across OS relaunches
  startOnBoot: true,
  stationaryLowPowerGps: false,     // location services OFF while stationary (no arrow, no drain)
  backgroundActivitySession: false, // no blue pill
  zeroLossMode: false,
  pauseInsideGeofence: true,        // no points while standing inside a fence
  geofenceNotifications: true,
  distanceFilter: 10,
  url: 'https://your-server.com/locations',
});

Accuracy you can expect (measured on a real device, iPhone 11 Pro):

| Event | Accuracy | Why | |---|---|---| | ENTER (arriving) | ~1–2 s | the device is moving, so the app is already awake and samples every 10 m | | EXIT (leaving) | ~200 m late | the app is asleep while parked and iOS only wakes it after ~200 m of movement. Set stationaryLowPowerGps: true to trade battery for ~100 m detection |

Every location and geofence event is written to SQLite first and uploaded when the network is available, so a check-in is never lost while offline.

Requirements

  • React Native >= 0.71 (tested on 0.77, new architecture via interop).
  • iOS >= 15.1. Android minSdk 24.
  • Node >= 18 for the demo server.

License

MIT © sep21th