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-background-keepalive

v1.1.0

Published

Dynamic always-on background service for React Native. mode:'data' for API/sync or mode:'location' for GPS + kill/reboot keep-alive. Sticky Android FGS + iOS keep-alive. Run any JS task: fetch, sockets, timers, or location.

Downloads

804

Readme

react-native-background-keepalive

Always-on background execution for React Native — dynamic, not location-only.

Run any JS task while the app is in foreground, background, or (within OS limits) after kill / reboot: API sync, sockets, timers, or location tracking.

| Mode | Use when | Android | iOS | | --- | --- | --- | --- | | mode: 'data' (default) | API fetch, sockets, cron, sync | Sticky FGS dataSync + boot/kill restart | Short BG window + BGTaskScheduler (no Always location) | | mode: 'location' | GPS / duty tracking / after-kill | FGS location\|dataSync + AlarmManager kill recovery | Always location + significant-change relaunch | | mode: 'custom' | You set android / ios yourself | Your FGS types | Your keepAlive |


Architecture (same idea as STC Guard, but generic)

┌──────────────────────────────────────────────────────────────┐
│ JS: defineTask → start({ mode }) → your work loop            │
│     resumeIfNeeded() after cold start / headless relaunch    │
└───────────────┬──────────────────────────┬───────────────────┘
                ▼                          ▼
┌───────────────────────────┐  ┌───────────────────────────────┐
│ iOS                       │  │ Android                       │
│ keepAlive none | location │  │ Foreground service + Headless │
│ UserDefaults enabled flag │  │ AlarmManager kill restart     │
│ significant-change wake   │  │ BootReceiver reboot restore   │
└───────────────────────────┘  └───────────────────────────────┘

Your task decides what to do (fetch, socket emit, watchPosition, …). mode only chooses how the OS is asked to keep the process alive.


Install

npm install react-native-background-keepalive
cd ios && pod install

Rebuild the native app (JS reload is not enough). Not supported in Expo Go.


Quick start (dynamic task)

1. Register the task in index.js (required for Android kill/reboot)

import { AppRegistry } from 'react-native';
import { defineTask, isRunning, sleep } from 'react-native-background-keepalive';
import App from './App';
import { name as appName } from './app.json';

defineTask('Worker', async (params) => {
  while (isRunning()) {
    if (params?.mode === 'location') {
      // read GPS / emit guard:location:update
    } else {
      // await fetch('https://api.example.com/sync')
    }
    await sleep(5000);
  }
});

AppRegistry.registerComponent(appName, () => App);

2. Start with the right mode

API / sync only (no location permission needed):

await start({
  taskName: 'Worker',
  mode: 'data',
  notification: { title: 'Syncing', text: 'Background sync' },
  parameters: { mode: 'data', userId: 42 },
});

Location + kill/reboot keep-alive (STC Guard style):

await start({
  taskName: 'Worker',
  mode: 'location',
  notification: {
    title: 'Location Tracking',
    text: 'Tracking your location for security purposes',
  },
  parameters: { mode: 'location' },
});
await requestIgnoreBatteryOptimizations(); // Android OEMs

3. Resume after kill / cold start

// HomeScreen / Splash — same pattern as BackgroundLocationService.resumeIfNeeded()
const resumed = await resumeIfNeeded();

stop() clears the persisted enabled flag so resume will not restart.


Mode → platform mapping

| mode | Android foregroundServiceType | iOS keepAlive | | --- | --- | --- | | 'data' | ['dataSync'] | 'none' | | 'location' | ['location', 'dataSync'] | 'location' | | 'custom' | you provide | you provide |

You can still override:

await start({
  mode: 'data',
  android: { foregroundServiceType: ['dataSync'], startOnBoot: true },
  ios: { keepAlive: 'none' },
  notification: { title: 'Sync', text: '…' },
});

API

| Method | Purpose | | --- | --- | | defineTask(name, fn) | Register task at top of index.js | | start(options) / start(fn, options) | Start FGS + task (mode recommended) | | stop() | Stop + clear enabled flag + cancel kill alarms | | resumeIfNeeded() | Restart if native flag still on after kill/relaunch | | wasEnabled() / wasTrackingEnabled() | Read persisted enabled flag | | isRunning() | Sync loop guard inside your task | | isServiceRunning() | Async native service state | | sleep(ms) | Interruptible delay (ends on stop) | | updateNotification({ notification }) | Update FGS / iOS local notification | | requestIgnoreBatteryOptimizations() | Android battery exemption UI | | resolveOptionsForMode(options) | Preview resolved android/ios from mode | | on(event, listener) | run / stop / expiration / restore |


Permissions (host app)

Android (mode: 'data')

  • POST_NOTIFICATIONS (API 33+) for the FGS notification

Android (mode: 'location')

  • Fine/coarse location, then separately ACCESS_BACKGROUND_LOCATION (API 29+)
  • Do not start a location FGS without location permission (Android 14+ crash)

iOS (mode: 'location')

Info.plist:

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysAndWhenInUseUsageDescription
  • UIBackgroundModeslocation (+ optional fetch / processing)

Grant Always for lock / kill reliability.

Optional: BackgroundWorker.registerBackgroundTasks() in AppDelegate for BGTaskScheduler wakes (mode: 'data').


Kill / reboot (what this package does)

Android

  • Sticky FGS + stopWithTask=false
  • AlarmManager restart after swipe-kill (survives process death)
  • BootReceiver + prefs commit() for reboot
  • Headless JS re-runs your defineTask

iOS

  • Only with mode: 'location' (Always + significant-change)
  • Persisted UserDefaults + restore / resumeIfNeeded() to restart the JS loop

Honest OS limits

  • iOS API-only after force-quit: not possible without a sanctioned background mode (location is the one this package uses).
  • Android OEM killers may still need battery exemption / autostart.
  • Force stop from system App Info will not auto-restart (Android design).

License

MIT