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

@alimirzayev/react-native-background-timer

v0.1.0

Published

Reliable lifecycle-aware timers for modern React Native and Expo development builds

Downloads

206

Readme

@alimirzayev/react-native-background-timer

Modern background-aware timers for the React Native New Architecture

Built from scratch with TurboModules + Codegen, first-class TypeScript, real native cancellation, Expo development builds, and a safe web fallback.

CI ready npm ready React Native Expo license

Getting started · Why this package? · API · Platform behavior · Migration

[!IMPORTANT] This is a modern, clean implementation - not a fork of the original package. It is designed for current React Native projects and explicitly documents what mobile operating systems can and cannot guarantee.

At a glance

  • New Architecture first - typed TurboModule spec, Codegen events, Hermes-ready.
  • Expo-ready - works in Expo development builds through standard autolinking; no config plugin required.
  • Correct cancellation - clearing a timer removes both its JavaScript callback and native scheduled work.
  • Multiple timers - independent timeouts and intervals with one shared native event subscription.
  • Stable cadence - monotonic Android deadlines skip missed ticks instead of creating callback storms.
  • Lifecycle-safe - native timers, listeners, background assertions, and WakeLocks are cleaned up.
  • TypeScript included - no separate @types package.
  • Web-safe - the same API works through a foreground-only JavaScript fallback.
  • Tested release path - CI, coverage thresholds, native lint/tests, and a publish-blocking verification step.

Why this package?

The original react-native-background-timer was created for the legacy React Native bridge. This package preserves the familiar timer experience while rebuilding the native and JavaScript layers around the current React Native architecture.

| Area | Legacy approach | This package | | ------------------- | ---------------------------------------- | -------------------------------------------- | | Native architecture | Legacy bridge module | TurboModule + Codegen | | Events | Manual NativeEventEmitter wiring | Typed Codegen events | | TypeScript | External/community definitions | Built in | | Cancellation | Reported timeout/interval cleanup issues | JS and native work cancelled together | | Concurrent timers | Historically inconsistent APIs | Independent timers by design | | Long-running IDs | Callback object growth / range reports | Map storage and safe ID recycling | | Timing cadence | Repeating delay accumulation | Monotonic deadlines and missed-tick skipping | | Expo | Legacy eject-oriented setup | Expo development builds + autolinking | | Web | No dependable package fallback | Foreground-compatible web driver | | Verification | No current regression suite | Jest, Android unit/lint, host builds, CI |

Issue classes addressed

The implementation includes targeted regressions for common reports from the original library:

  • New Architecture and builds: #536, #532, #530, #527, #526, #367, #290, #242
  • Immediate, long-running, and synchronized timers: #533, #529, #270, #271, #256, #299
  • Cancellation and multiple timers: #524, #337, #310, #366
  • Safe missing-native-module behavior: #531
  • React Native Web fallback: #455
  • iOS reload cleanup protections: #460 (device stress loop remains pending)

See the issue regression matrix for test details. OS-controlled behavior such as iOS suspension, Android Doze, OEM process killing, or force-quit is documented as a limitation - not presented as a library fix.

Compatibility

| Target | Support | | ------------ | --------------------------------------------------------------- | | React Native | Verified on 0.82.1, 0.83.10, 0.84.1, 0.85.3, and 0.86 | | React | >=19.1 | | Architecture | New Architecture / TurboModules | | Expo | SDK 57 development builds verified; Expo Go is not supported | | Android | API 24+, compile SDK 36 | | iOS | 16.4+ | | Web | Expo Web / React Native Web foreground fallback |

[!NOTE] React Native 0.82.1 passes Android normally. With Xcode 26.5, its bundled fmt 11.0.2 pod must be compiled as C++17 due to an upstream toolchain incompatibility. This does not originate in this package and is not required for React Native 0.83+.

Getting started

Install

npm install @alimirzayev/react-native-background-timer
yarn add @alimirzayev/react-native-background-timer

Bare React Native

Android uses standard autolinking. For iOS, install pods after adding the package:

cd ios && pod install

Rebuild the native application after installation.

Expo

This package contains native code, so use an Expo development build:

npx expo install @alimirzayev/react-native-background-timer
npx expo run:android
# or
npx expo run:ios

[!WARNING] Expo Go is not supported. Package import is safe, but starting a native timer without a development build throws an actionable error.

Quick start

import BackgroundTimer from "@alimirzayev/react-native-background-timer";

const timerId = BackgroundTimer.setInterval(
  () => {
    console.log("tick");
  },
  1_000,
  { immediate: true },
);

// Later: removes the callback and native timer.
BackgroundTimer.clearInterval(timerId);

Timeout

const timeoutId = BackgroundTimer.setTimeout(() => {
  console.log("finished");
}, 2_000);

BackgroundTimer.clearTimeout(timeoutId);

Handle iOS background-time expiration

const unsubscribe = BackgroundTimer.addBackgroundTimeExpiredListener(() => {
  // Save state and stop background work gracefully.
  console.log("iOS background time expired");
});

unsubscribe();

Inspect platform capabilities

const capabilities = BackgroundTimer.getCapabilities();

console.log(capabilities.backgroundExecution);
// Android: "best-effort"
// iOS:     "time-limited"
// Web:     "none"

API

| Method | Returns | Description | | ----------------------------------------------- | ------------------- | --------------------------------------- | | setTimeout(callback, delay?) | TimerId | Schedule one callback | | clearTimeout(id) | void | Cancel one timeout | | setInterval(callback, delay?, options?) | TimerId | Schedule a repeating callback | | clearInterval(id) | void | Cancel one interval | | clearAllTimers() | void | Cancel all timers owned by this package | | addBackgroundTimeExpiredListener(listener) | unsubscribe | Observe iOS expiration | | getCapabilities() | TimerCapabilities | Inspect runtime guarantees | | runBackgroundTimer(callback, delay, options?) | TimerId | Single-timer migration helper | | stopBackgroundTimer() | void | Stop the migration-helper timer |

options.immediate fires an interval once immediately, then continues at the requested delay. Delays must be finite values from 0 through 2,147,483,647 milliseconds; repeating intervals use a minimum of 1 millisecond.

The full API contract is documented in API.md.

Platform behavior

Android

  • Schedules native timers from monotonic deadlines.
  • Supports independent one-shot and repeating timers.
  • Holds a partial WakeLock only while the host is backgrounded and active timers remain.
  • Releases callbacks and WakeLock state on clear, resume, host destruction, or module invalidation.
  • Skips missed ticks instead of replaying a callback storm.

Android execution is best effort. Doze, force-stop, OEM battery policies, or process pressure can stop the app. Continuous user-visible work belongs in a foreground service with a visible notification.

iOS

  • Uses one GCD timer source per timer.
  • Requests a UIKit background task when active timers enter the background.
  • Coalesces missed repeating ticks.
  • Emits an expiration event when iOS revokes background time.
  • Ends timers and background assertions during clear, foregrounding, invalidation, and deallocation.

iOS background execution is time limited. After the granted time expires, iOS may suspend the app. No timer library can promise indefinite execution or execution after force-quit.

Web

  • Automatically selects a JavaScript driver.
  • Provides the same timeout, interval, cancellation, and capability APIs.
  • Never claims native background execution.

Browsers can throttle or suspend timers in inactive tabs. Web support is API compatibility for foreground use.

Choose the right background tool

Use this package when you need second- or millisecond-level callbacks while the application process still has permission to execute.

| Requirement | Recommended tool | | -------------------------------------------- | --------------------------------------------------- | | Short, frequent callbacks while backgrounded | This package | | Deferrable sync or maintenance work | Expo BackgroundTask / WorkManager / BGTaskScheduler | | Alarm or user-visible event at a future time | Local notifications | | Continuous Android work | Foreground service | | Work after force-quit | OS-specific scheduling; not a timer |

For countdowns and stopwatches, store a timestamp and calculate elapsed time when the app resumes instead of depending on every tick.

Migration from react-native-background-timer

Change the import:

- import BackgroundTimer from 'react-native-background-timer';
+ import BackgroundTimer from '@alimirzayev/react-native-background-timer';

Standard calls keep the familiar shape:

const id = BackgroundTimer.setInterval(callback, 1_000);
BackgroundTimer.clearInterval(id);

For older code using a single global background timer:

BackgroundTimer.runBackgroundTimer(callback, 1_000);
BackgroundTimer.stopBackgroundTimer();

The migration helpers intentionally own only one timer. Prefer the core timeout and interval API for new code.

Verification

  • 38 Jest tests across timer engine, native driver, web driver, and issue regressions.
  • 98.46% statements, 95.31% branches, 100% functions, 99.13% lines.
  • Android native unit tests and lint pass.
  • Bare React Native Android APK and iOS simulator application builds pass.
  • Expo SDK 57 Android, iOS, and web host builds pass.
  • Packaged .tgz clean-install, autolinking, types, and Metro bundles pass.
  • CI enforces coverage and package verification.
  • prepublishOnly blocks npm publication when verification fails.

Runnable examples:

Development

npm install
npm run verify

Native Android verification:

cd examples/bare/android
./gradlew \
  :alimirzayev_react-native-background-timer:testDebugUnitTest \
  :alimirzayev_react-native-background-timer:lintDebug

License

MIT © Ali Mirzayev