React Native
background tasks
mobile development
asynchronous operations
app performance

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.

Practice algorithms

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:

javascript
1import { AppRegistry } from 'react-native';
2
3async function SyncTask(data) {
4  console.log('Background payload:', data);
5  // fetch data, update local storage, etc.
6}
7
8AppRegistry.registerHeadlessTask('SyncTask', () => SyncTask);

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:

  1. schedule work with WorkManager or another native trigger
  2. start a background service or worker
  3. 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:

javascript
1import BackgroundFetch from 'react-native-background-fetch';
2
3BackgroundFetch.configure(
4  {
5    minimumFetchInterval: 15,
6    stopOnTerminate: false,
7    startOnBoot: true,
8  },
9  async (taskId) => {
10    try {
11      console.log('Background task:', taskId);
12      // sync data here
13    } finally {
14      BackgroundFetch.finish(taskId);
15    }
16  },
17  (taskId) => {
18    BackgroundFetch.finish(taskId);
19  }
20);

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
Course
Intermediate
27 lessons
15 hours
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 course
Track 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.

Practice algorithms

All Rights Reserved.