How can I run background tasks in React Native?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
The first thing to understand is that React Native does not bypass mobile operating system background limits. You can run background work in a React Native app, but the real solution is always a combination of JavaScript, native platform APIs, and OS-specific scheduling rules.
Choose the strategy by task type
There is no single background API that fits every case. The right approach depends on what the app is trying to do:
- short Android task after the app goes to background
- scheduled refresh on iOS
- reliable deferred sync that should survive app restarts
- continuous location, audio, or navigation work with a declared background mode
If you skip this classification and just ask for "background tasks," you usually end up with an implementation that works on one platform and fails on the other.
Android: Headless JS and native schedulers
React Native officially documents Headless JS for Android. It lets JavaScript run in response to a native-triggered background event even when no UI is mounted.
A minimal Headless JS task looks like this:
That registration alone is not enough. A native Android service or scheduler still has to trigger the task. For durable, system-friendly scheduling on Android, the normal native choice is WorkManager.
So the usual Android architecture is:
- schedule work with WorkManager or another native trigger
- start a background service or worker
- hand off to Headless JS when JavaScript needs to run
This is much more reliable than trying to keep the JavaScript runtime alive indefinitely.
iOS: background execution is more restrictive
iOS is stricter. You do not get arbitrary recurring background execution just because the app is built with React Native. Current Apple guidance centers on background task APIs such as BGAppRefreshTask and BGProcessingTask, along with special-purpose background modes for categories like location, audio, VoIP, or background transfers.
That means most React Native apps need a native bridge or a maintained library that wraps the native iOS APIs. If the task is periodic refresh, you usually schedule it through BGTaskScheduler or use a background-fetch style wrapper that maps to supported iOS behavior.
The important constraint is that iOS decides when your task runs. You can request background execution, but you cannot demand exact periodic timing.
A practical cross-platform option
For many applications, the pragmatic route is to use a maintained library that bridges native background APIs for both platforms. One common example is a background fetch library that wraps Android scheduling and iOS refresh mechanisms behind a JavaScript API.
A typical setup looks like this in JavaScript:
This is convenient, but it still operates within OS rules. On iOS, execution timing is opportunistic. On Android, battery optimizations and OEM behavior still matter.
When not to use a generic background task
Some jobs should use specialized native capabilities instead of a generic timer-like background mechanism.
Examples:
- file uploads and downloads: background transfer APIs
- location tracking: location background mode
- push-triggered refresh: silent push or notification-driven wake-up where permitted
- guaranteed Android deferrable work: WorkManager
This matters because the operating systems give special treatment to certain task categories. If your app fits one of them, use that category directly instead of forcing everything through a generic background loop.
Design for short, resumable work
Background execution should be treated as limited and interruptible. The work unit should be:
- short
- idempotent
- resumable
- safe to retry
For example, instead of "sync the whole account for ten minutes," schedule "upload pending events in small batches" or "refresh the latest summary." That design survives process kills and expiration callbacks much better.
Common Pitfalls
A common mistake is expecting React Native JavaScript to run forever after the app is backgrounded. The operating system can suspend or terminate it.
Another mistake is designing background work as a precise timer. Especially on iOS, background scheduling is discretionary and not suitable for exact intervals.
A third mistake is ignoring the native side. Even if the business logic is in JavaScript, the actual wake-up mechanism usually comes from WorkManager, BGTaskScheduler, background fetch, or a special-purpose OS capability.
Summary
- React Native background tasks are constrained by Android and iOS, not just by JavaScript.
- On Android, Headless JS is the official React Native mechanism for background JavaScript execution.
- On iOS, use native background task APIs or a maintained bridge library that wraps them.
- Pick the mechanism based on the task category, not just on a desire to "run code in the background."
- Keep background jobs short, resumable, and tolerant of delayed or skipped execution.
Related reading
- How can I run Tensorflow on one single core?
- How can I solve 'ran out of gpu memory' in TensorFlow
- How can I speed up a topic model in R?
- How can I speed up deep learning on a non-NVIDIA setup?
- How can I run code on a background thread on Android?
- How can I run NHibenate queries asynchronously?
- How can I run multiple npm scripts in parallel?
- How can I run NodeJS in Docker with MongoDB and RabbitMQ?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.