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

react-native-accurate-location

v2.3.0

Published

Fast, tunable high-accuracy one-shot geolocation for React Native (New Architecture): resolves on an accuracy threshold, returns the best fix on timeout, always-fresh, with mock-location detection.

Readme

react-native-accurate-location

npm version license

Fast, tunable high-accuracy one-shot geolocation for iOS and Android. It takes a fresh fix and resolves the instant that fix meets your accuracy threshold — and if the threshold is never reached, it returns the best fix seen so far instead of just failing. Built-in mock-location detection.

Requires React Native New Architecture (TurboModules). After installing you must rebuild the native app — this cannot be delivered via OTA / Expo Go.

v2.0.0 is a breaking change. desiredAccuracyMeters was removed and acceptableAccuracyMeters is now the resolve threshold (the request returns as soon as a fresh fix is at least this accurate). See Migration.

Installation

pnpm add react-native-accurate-location
# or
npm install react-native-accurate-location
# or
yarn add react-native-accurate-location

iOS

cd ios && pod install

Add a location usage description to ios/<App>/Info.plist:

<key>NSLocationWhenInUseUsageDescription</key>
<string>We need your location to check you in accurately.</string>

Android

Requires ACCESS_FINE_LOCATION. Add to android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Then rebuild:

npx react-native run-android

Usage

import AccurateLocation from 'react-native-accurate-location';

const location = await AccurateLocation.getCurrentLocation({
  acceptableAccuracyMeters: 15, // resolve as soon as a fresh fix is ≤ 15 m
  timeoutMs: 15000,
});

console.log(location.latitude, location.longitude, location.accuracy);

API

getCurrentLocation(options?): Promise<AccurateLocationResult>

| Option | Type | Default | Description | | --- | --- | --- | --- | | acceptableAccuracyMeters | number | 15 | The speed/accuracy knob. Resolves the moment a fresh fix is at least this accurate — no waiting for a tighter one. Raise it (e.g. 30) for faster, coarser results. | | timeoutMs | number | 15000 | Safety timeout. If the threshold is never met, the best fix seen so far is returned when this elapses (only rejects if no fix arrived). | | maxCacheAgeMs | number | 0 | If > 0, a cached fix younger than this and already within acceptableAccuracyMeters is returned instantly. 0 = always take a fresh fix — important when moving, so you never get a stale position. | | maxFixAgeMs | number | 3000 | Reject any fix older than this. A fix carries the accuracy it had when it was taken, so an old one keeps claiming a tight accuracy for a place the device has already left — the usual cause of a position that is precise yet tens of metres wrong. 0 = accept any age. | | minSettleMs | number | 4000 | Don't resolve before this has elapsed, unless the fix is already better than 5 m. GNSS converges over time and its earliest fixes are its worst. Lower for speed, raise for accuracy. | | smoothing | boolean | true | Return the median of recent comparable fixes instead of a single sample. Multipath scatters fixes around the true position, so the median lands closer than any individual fix. | | adaptiveTimeout | boolean | true* | Extend the timeout to 45 s when no fix at all has arrived after 10 s (cold start without A-GPS can take 30–60 s). Only ever extends, never shortens. *Defaults to true only when timeoutMs is left at its default — an explicit timeoutMs is honoured exactly unless you also pass adaptiveTimeout: true. | | allowStaleFallback | boolean | true | When the deadline passes with no fresh fix at all, resolve with the last known position at any age instead of rejecting. Check ageMs on the result to detect it. Set to false when a wrong position is worse than an error (geofencing, attendance). |

Result: { latitude, longitude, accuracy, altitude?, bearing?, speed?, time, ageMs?, provider, isMocked }.

ageMs is the age of the fix when it was returned — normally a few hundred ms. A large value means it came from the allowStaleFallback path. Behavior and defaults are identical on iOS & Android.

Pick acceptableAccuracyMeters above what the environment can actually deliver. The real accuracy floor is set by the hardware + surroundings (e.g. an older phone indoors may floor at ~35 m). Asking for a tighter value than the floor just makes the request wait until timeout. No library — free or paid — can beat that floor; only moving to open sky does.

cancel(): void

Cancels the in-flight getCurrentLocation request. The pending promise rejects with code LOCATION_CANCELLED. Safe to call even when no request is active.

warmup(durationMs?: number): void / stopWarmup(): void

Pre-warms the GPS so the first getCurrentLocation resolves fast, avoiding the cold-start delay. Call warmup() when you know a read is coming soon (e.g. when the screen opens); it keeps the GPS active for durationMs (default 30000) then stops itself. Requires location permission to have any effect. Example:

useEffect(() => {
  AccurateLocation.warmup(30000);      // start warming on screen open
  return () => AccurateLocation.stopWarmup();
}, []);
// ...later, the user taps a button:
const loc = await AccurateLocation.getCurrentLocation({ acceptableAccuracyMeters: 15 });

requestPermission(): Promise<PermissionStatus>

Requests location permission from the system. PermissionStatus = 'granted' | 'denied' | 'blocked' | 'unavailable'.

  • iOS: triggers the prompt when status is notDetermined; denied/restricted map to 'blocked'.
  • Android: 'granted'/'denied'. Pure native cannot distinguish a plain denied from "don't ask again" (blocked) — if you need that, use PermissionsAndroid in JS.
  • 'unavailable' is returned when there is no Activity (Android) or the native module is not installed.

Permission behavior

getCurrentLocation does not request permission automatically on Android — make sure it is already granted (via requestPermission() or PermissionsAndroid) before calling it, otherwise it rejects with LOCATION_PERMISSION_DENIED. On iOS, when the status is notDetermined, getCurrentLocation shows the permission prompt first and then continues automatically.

Error codes

| Code | When it happens | | --- | --- | | LOCATION_PERMISSION_DENIED | Location permission not granted. | | LOCATION_SERVICES_DISABLED | Device Location Services / GPS are turned off. | | LOCATION_TIMEOUT | Timeout elapsed and no fix arrived at all and no last known position was usable (or allowStaleFallback: false). If any fix arrived, the request resolves with the best one instead of rejecting. | | LOCATION_CANCELLED | Cancelled via cancel(). | | LOCATION_REQUEST_FAILED (Android) | Fused provider failed & hardware GPS unavailable. | | LOCATION_ERROR (iOS) | Non-transient CoreLocation error. | | LOCATION_FETCH_IN_PROGRESS (iOS) | A request is already running (iOS processes one at a time). |

Offline behavior

The module reads GPS satellites directly, so it does not need internet/cellular signal to be accurate. What is lost offline is Assisted-GPS, so the first fix from a cold start can be slower (30–60 s) — the ephemeris has to be decoded from the satellites themselves. adaptiveTimeout covers that case by stretching the deadline to 45 s when nothing has arrived after 10 s, and allowStaleFallback keeps a fully offline cold device from failing outright by returning the last known position rather than an error. By default (maxCacheAgeMs: 0) a fresh fix is always taken, so the position never "sticks" at an old point — important while moving. On Android the fused provider and the raw GPS provider run in parallel, so a fix is still produced if Play Services is unavailable.

isMocked is only reliable on iOS 15+ and Android 12 (S)+. On older versions iOS always returns false; Android falls back to the deprecated isFromMockProvider API.

Comparison with other libraries

Compared with commonly used React Native geolocation libraries. The points below are a reference based on each library's general feature set and may vary between versions — check each library's docs before deciding.

This table is scoped to one-shot getCurrentLocation (single fix), where this library focuses. expo-location behavior below is verified against its iOS source; the other columns reflect each library's general feature set and may change between versions — check their docs before deciding.

| Feature (one-shot) | accurate-location | @react-native-community/geolocation | react-native-geolocation-service | expo-location | | --- | --- | --- | --- | --- | | Architecture | TurboModule (New Arch) | Legacy bridge | Legacy bridge | Expo module | | Resolve strategy | Fresh, on accuracy threshold | First fix in timeout | First fix in timeout | First fix, no filter | | Tunable accuracy threshold | ✅ acceptableAccuracyMeters | ❌ | ❌ | ❌ (accuracy is only a hint) | | Returns best fix on timeout | ✅ | ❌ (rejects) | ❌ (rejects) | ❌ | | Fresh-first / anti stale-cache | ✅ (default) | ⚠️ maximumAge may return stale | ⚠️ maximumAge | ⚠️ | | Dual provider (fused + raw GPS) | ✅ (Android) | ❌ | ⚠️ | ❌ | | Mock detection (isMocked) | ✅ | ❌ | ✅ (Android) | ⚠️ limited | | Requires Expo | ❌ | ❌ | ❌ | ✅ | | Watch / streaming | ❌ | ✅ | ✅ | ✅ | | Background / geofencing | ❌ | ❌ | ⚠️ limited | ✅ | | Maturity (battle-tested) | ⚠️ new | ✅✅✅ | ✅✅ | ✅✅✅ |

Note on accuracy: "best" here means the smartest speed/accuracy trade-off, not more accurate coordinates. The physical accuracy floor is identical across every library — it is set by the device GPS chip and surroundings, not the SDK.

Pros

  • Tunable one-shot: resolve the instant a fresh fix meets your threshold — a knob neither expo-location nor @react-native-community/geolocation expose.
  • Best-on-timeout: returns the best fix instead of failing when the threshold isn't reached (most libraries reject).
  • Fresh-first: never returns a stale cached position by default — correct while moving.
  • Dual provider on Android (fused + raw GPS) for offline / flaky Play Services.
  • Built-in isMocked for check-in / anti-fraud.
  • TurboModule (New Architecture), type-safe via codegen. No Expo required.

Cons

  • Requires New Architecture and a native rebuild — no OTA / Expo Go.
  • One-shot only: no watchPosition streaming, background, or geofencing.
  • Newer / smaller ecosystem than the mainstream libraries — less battle-tested.

Use this when you need one location read, fast and as accurate as the device allows (e.g. attendance / check-in). For continuous or background tracking, use react-native-geolocation-service, expo-location, or react-native-background-geolocation.

Migrating from 1.x

getCurrentLocation options changed:

| 1.x | 2.0 | | --- | --- | | desiredAccuracyMeters | removed — there is no separate "ideal" target anymore | | acceptableAccuracyMeters (timeout floor) | now the resolve threshold: the request returns as soon as a fresh fix is at least this accurate | | — | maxCacheAgeMs (new, default 0 = always fresh) | | timeoutMs | unchanged, but on timeout it now resolves with the best fix rather than rejecting |

- await AccurateLocation.getCurrentLocation({ desiredAccuracyMeters: 8, acceptableAccuracyMeters: 15 });
+ await AccurateLocation.getCurrentLocation({ acceptableAccuracyMeters: 15 });

License

MIT