Production-grade background-safe timers for React Native.
Powered by Nitro Modules with a shared C++ scheduler core on Android and iOS.
This package is being finalized for the official 1.x stable line.
0.x: rapid iteration and compatibility hardening1.x: stable public contract- SemVer policy: breaking changes only in major releases
See docs/RELEASE_GOVERNANCE.md and docs/FEATURE_UPGRADE_STATUS.md for release gates and live status.
- 🔥 Native-backed timers through Nitro Modules
- 🧠 Shared C++ scheduler core for cross-platform consistency
- 🎯 Legacy API + scheduler-first API in one package
- 🧩 Group controls and drift policies
- 📊 Stats and lifecycle events for production observability
- 🛡️ Retry/token/profile metadata flow with validation safeguards
This module runs critical scheduling paths in native code (C++ core + Swift/Kotlin adapters) instead of keeping hot scheduling loops in JavaScript.
- Typed bridge overhead improvement: about
99%faster than JSON bridge path (benchmark:bridge). - Native C++ core load benchmark: around
15msfor50,000tasks on recent CI runs (benchmark:core-native). - Stress smoke signal:
p95 ~ 3.5ms, heap delta about4.6MB(stress:smoke).
These numbers come from the current release verification lane (npm run verify:release) and are intended as practical indicators, not synthetic peak claims.
- React Native
>= 0.76 - Node.js
>= 18 react-native-nitro-modules>= 0.35.x
npm install react-native-nitro-bg-timer react-native-nitro-modulesor
yarn add react-native-nitro-bg-timer react-native-nitro-modules- Uses
UIApplication.beginBackgroundTaskinternally - No runtime permission prompt
BGTaskScheduleris not required by default
cd ios && pod installThis library uses PARTIAL_WAKE_LOCK while timers are active.
<uses-permission android:name="android.permission.WAKE_LOCK" />FOREGROUND_SERVICE is not required unless your app uses foreground services for other workloads.
import { BackgroundTimer } from 'react-native-nitro-bg-timer'
const timeoutId = BackgroundTimer.setTimeout(() => {
console.log('Runs once after 5 seconds')
}, 5000)
const intervalId = BackgroundTimer.setInterval(() => {
console.log('Runs every 2 seconds')
}, 2000)
BackgroundTimer.clearTimeout(timeoutId)
BackgroundTimer.clearInterval(intervalId)import { BackgroundTimer, BackgroundScheduler } from 'react-native-nitro-bg-timer'
const handle = BackgroundTimer.schedule(() => {
console.log('Sync fired')
}, {
kind: 'interval',
intervalMs: 1000,
group: 'sync',
driftPolicy: 'coalesce',
retryMaxAttempts: 3,
retryInitialBackoffMs: 250,
cancellationToken: 'sync-job',
policyProfile: 'balanced',
tags: ['sync', 'foreground'],
})
BackgroundTimer.pauseGroup('sync')
BackgroundTimer.resumeGroup('sync')
const cronHandle = BackgroundScheduler.scheduleCron(() => {
console.log('Every 2 minutes')
}, '*/2 * * * *')
handle.cancel()
cronHandle.cancel()setTimeout(callback, durationMs): numberclearTimeout(id): voidsetInterval(callback, intervalMs): numberclearInterval(id): voidschedule(callback, options): ScheduledTaskHandlepauseGroup(group): numberresumeGroup(group): numbercancelGroup(group): numberlistActiveTimerIds(): number[]getStats(): SchedulerStatsonStats(listener): () => voidonEvent(listener): () => voidgetPersistWireJson(): stringrestorePersistWireJson(wireJson): void
scheduleAt(callback, runAtMs, options?)scheduleInterval(callback, intervalMs, options?)scheduleCron(callback, expression, options?)
- Existing timer usage (
setTimeout,setInterval) remains supported. - New code should prefer
BackgroundTimer.schedule(...)andBackgroundScheduler.*. - For migration details, see
docs/MIGRATION_V2.md.
npm run testnpm run benchmark:nodenpm run benchmark:bridgenpm run benchmark:core-nativenpm run stress:smokenpm run stress:soaknpm run benchmark:native-smokenpm run verify:release
npm run verify:release is the recommended pre-publish gate.
- iOS execution remains bounded by OS lifecycle policy.
- Android behavior may vary under OEM battery optimization and Doze.
- For durable long-running workloads, combine with platform job schedulers.
Core docs:
docs/FEATURE_UPGRADE_STATUS.mddocs/RELEASE_GOVERNANCE.mddocs/MIGRATION_V2.mddocs/OBSERVABILITY_EVENT_CONTRACT.mddocs/NATIVE_BENCH_THRESHOLDS.mddocs/RELIABILITY_LAB_SCORECARD.mddocs/PERSISTENCE.mddocs/PLATFORM_LIFECYCLE_MATRIX.md
When changing Nitro specs (src/specs/*.nitro.ts), regenerate bindings:
npx nitrogenBefore opening PRs:
npm run verify:releaseSpecial thanks to the following open-source projects which inspired and supported the development of this library:
- mrousavy/nitro – for the Nitro Modules architecture and tooling
MIT © Thành Công