/mobile-background-tasks
Background fetch, processing tasks, background location, headless JS, battery optimization - Expo and bare React Native
$ npx -y skills add agents-inc/skills --skill mobile-background-tasks --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/mobile-background-tasks
Context preview
The summary Claude sees to decide when to auto-load this skill.
Background fetch, processing tasks, background location, headless JS, battery optimization - Expo and bare React Native
SKILL.md
mobile-background-tasks.SKILL.mdname: mobile-background-tasks
description: Background fetch, processing tasks, background location, headless JS, battery optimization - Expo and bare React Native
React Native Background Tasks
> **Quick Guide:** Background tasks in React Native are heavily constrained by OS power management. Use `expo-background-task` (Expo) or `react-native-background-fetch` (bare RN) for periodic fetch. Use `expo-location` for background location tracking. iOS gives ~30s for refresh tasks (BGAppRefreshTask) and several minutes for processing tasks (BGProcessingTask). Android enforces 15-minute minimum intervals via WorkManager and restricts execution in Doze mode. Always call `finish()` or return a result when done -- the OS will terminate tasks that exceed their time budget.
---
<critical_requirements>
CRITICAL: Before Using This Skill
> **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)
**(You MUST define tasks in the top-level scope (global) -- tasks defined inside React components or lifecycle methods will NOT be registered when the app starts from the background)**
**(You MUST call `finish(taskId)` or return a `BackgroundTaskResult` when task execution completes -- failing to signal completion causes the OS to penalize or kill your app)**
**(You MUST request background permissions explicitly on both platforms -- iOS requires Info.plist UIBackgroundModes entries, Android requires manifest permissions)**
**(You MUST handle the OS killing your task at any time -- use expiration listeners on iOS and timeout callbacks on Android to clean up gracefully)**
**(You MUST keep background work minimal -- sync only changed data, avoid heavy computation, respect the ~30s iOS refresh limit)**
</critical_requirements>
---
**Auto-detection:** expo-task-manager, expo-background-task, expo-background-fetch, expo-location background, react-native-background-fetch, BackgroundFetch, TaskManager, defineTask, registerTaskAsync, startLocationUpdatesAsync, Headless JS, registerHeadlessTask, BGTaskScheduler, WorkManager, background fetch, background processing, background location
**When to use:**
- Syncing data periodically while the app is backgrounded (new messages, feeds, email)
- Tracking location in the background (fitness, delivery, navigation)
- Running periodic cleanup or maintenance tasks (cache purge, log upload)
- Keeping local data fresh so the app opens with current content
- Processing uploads or downloads that continue after backgrounding
**When NOT to use:**
- Real-time updates that need sub-second latency (use push notifications + foreground handling)
- Continuous audio playback (use the audio background mode, not task scheduling)
- Tasks that must execute at an exact time (OS scheduling is advisory, not precise)
- Tasks requiring more than a few minutes of CPU (iOS will terminate them)
**Key patterns covered:**
- Expo background tasks: `expo-background-task` (new) and `expo-background-fetch` (legacy)
- Bare RN background fetch: `react-native-background-fetch` with configure/scheduleTask
- Background location tracking with `expo-location` and TaskManager
- Android Headless JS for post-termination task execution
- iOS BGTaskScheduler constraints (refresh ~30s vs processing ~minutes)
- Android battery optimization: Doze mode, App Standby, WorkManager guarantees
- Task registration, unregistration, and lifecycle management
**Detailed Resources:**
- [examples/core.md](examples/core.md) - Expo background task, bare RN background fetch, background location, headless JS
- [reference.md](reference.md) - Decision frameworks, platform constraints, permission checklists
---
<philosophy>
Philosophy
Background execution on mobile is a **privilege, not a right**. Both iOS and Android aggressively limit what apps can do in the background to preserve battery life and user experience. The OS decides when (and whether) your task runs -- you can only request execution and set minimum intervals.
**Core principles:**
1. **Minimize background work** -- Sync only deltas, not full datasets. The less you do, the more reliably the OS will schedule you. 2. **Always signal completion** -- Return a result code or call `finish()`. The OS tracks your task duration and penalizes apps that don't complete promptly. 3. **Define tasks globally** -- Background tasks must be registered at the top-level scope because the app may launch directly into background mode with no UI. 4. **Plan for termination** -- The OS can kill your task at any time. Use expiration/timeout handlers to save partial progress. 5. **Test on real devices** -- iOS simulators do not run BGTaskScheduler tasks. Android emulators may not enforce Doze mode. 6. **Respect platform differences** -- iOS kills all background tasks when the user force-quits. Android Headless JS can survive app termination with proper configuration.
**The background execution spectrum:**
Most reliable Least reliable
| |
Push notifications > Foreground services > Background tasks > Timers
(instant delivery) (visible to user) (OS-scheduled) (killed)
Background tasks sit in the middle -- more reliable than timers, but entirely at the OS's discretion. For critical work, combine with push notifications as a trigger.
</philosophy>
---
<patterns>
Core Patterns
Pattern 1: Expo Background Task (expo-background-task)
The modern Expo approach using BGTaskScheduler (iOS) and WorkManager (Android). Replaces the older `expo-background-fetch`.
import * as TaskManager from "expo-task-manager";
import * as BackgroundTask from "expo-background-task";
const SYNC_TASK_NAME = "BACKGROUND_SYNC_TASK";
const TWELVE_HOURS_IN_MINUTES = 720;
// MUST be top-level -- not inside a component
TaskManager.defineTask(SYNC_TASK_NAME, async () => {
try {
const hasNeRead more
name: mobile-background-tasks description: Background fetch, processing tasks, background location, headless JS, battery optimization - Expo and bare React Native
React Native Background Tasks
> **Quick Guide:** Background tasks in React Native are heavily constrained by OS power management. Use `expo-background-task` (Expo) or `react-native-background-fetch` (bare RN) for periodic fetch. Use `expo-location` for background location tracking. iOS gives ~30s for refresh tasks (BGAppRefreshTask) and several minutes for processing tasks (BGProcessingTask). Android enforces 15-minute minimum intervals via WorkManager and restricts execution in Doze mode. Always call `finish()` or return a result when done -- the OS will terminate tasks that exceed their time budget.
---
<critical_requirements>
CRITICAL: Before Using This Skill
> **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)
**(You MUST define tasks in the top-level scope (global) -- tasks defined inside React components or lifecycle methods will NOT be registered when the app starts from the background)**
**(You MUST call `finish(taskId)` or return a `BackgroundTaskResult` when task execution completes -- failing to signal completion causes the OS to penalize or kill your app)**
**(You MUST request background permissions explicitly on both platforms -- iOS requires Info.plist UIBackgroundModes entries, Android requires manifest permissions)**
**(You MUST handle the OS killing your task at any time -- use expiration listeners on iOS and timeout callbacks on Android to clean up gracefully)**
**(You MUST keep background work minimal -- sync only changed data, avoid heavy computation, respect the ~30s iOS refresh limit)**
</critical_requirements>
---
**Auto-detection:** expo-task-manager, expo-background-task, expo-background-fetch, expo-location background, react-native-background-fetch, BackgroundFetch, TaskManager, defineTask, registerTaskAsync, startLocationUpdatesAsync, Headless JS, registerHeadlessTask, BGTaskScheduler, WorkManager, background fetch, background processing, background location
**When to use:**
- Syncing data periodically while the app is backgrounded (new messages, feeds, email)
- Tracking location in the background (fitness, delivery, navigation)
- Running periodic cleanup or maintenance tasks (cache purge, log upload)
- Keeping local data fresh so the app opens with current content
- Processing uploads or downloads that continue after backgrounding
**When NOT to use:**
- Real-time updates that need sub-second latency (use push notifications + foreground handling)
- Continuous audio playback (use the audio background mode, not task scheduling)
- Tasks that must execute at an exact time (OS scheduling is advisory, not precise)
- Tasks requiring more than a few minutes of CPU (iOS will terminate them)
**Key patterns covered:**
- Expo background tasks: `expo-background-task` (new) and `expo-background-fetch` (legacy)
- Bare RN background fetch: `react-native-background-fetch` with configure/scheduleTask
- Background location tracking with `expo-location` and TaskManager
- Android Headless JS for post-termination task execution
- iOS BGTaskScheduler constraints (refresh ~30s vs processing ~minutes)
- Android battery optimization: Doze mode, App Standby, WorkManager guarantees
- Task registration, unregistration, and lifecycle management
**Detailed Resources:**
- [examples/core.md](examples/core.md) - Expo background task, bare RN background fetch, background location, headless JS
- [reference.md](reference.md) - Decision frameworks, platform constraints, permission checklists
---
<philosophy>
Philosophy
Background execution on mobile is a **privilege, not a right**. Both iOS and Android aggressively limit what apps can do in the background to preserve battery life and user experience. The OS decides when (and whether) your task runs -- you can only request execution and set minimum intervals.
**Core principles:**
1. **Minimize background work** -- Sync only deltas, not full datasets. The less you do, the more reliably the OS will schedule you. 2. **Always signal completion** -- Return a result code or call `finish()`. The OS tracks your task duration and penalizes apps that don't complete promptly. 3. **Define tasks globally** -- Background tasks must be registered at the top-level scope because the app may launch directly into background mode with no UI. 4. **Plan for termination** -- The OS can kill your task at any time. Use expiration/timeout handlers to save partial progress. 5. **Test on real devices** -- iOS simulators do not run BGTaskScheduler tasks. Android emulators may not enforce Doze mode. 6. **Respect platform differences** -- iOS kills all background tasks when the user force-quits. Android Headless JS can survive app termination with proper configuration.
**The background execution spectrum:**
Most reliable Least reliable | | Push notifications > Foreground services > Background tasks > Timers (instant delivery) (visible to user) (OS-scheduled) (killed)
Background tasks sit in the middle -- more reliable than timers, but entirely at the OS's discretion. For critical work, combine with push notifications as a trigger.
</philosophy>
---
<patterns>
Core Patterns
Pattern 1: Expo Background Task (expo-background-task)
The modern Expo approach using BGTaskScheduler (iOS) and WorkManager (Android). Replaces the older `expo-background-fetch`.
import * as TaskManager from "expo-task-manager";
import * as BackgroundTask from "expo-background-task";
const SYNC_TASK_NAME = "BACKGROUND_SYNC_TASK";
const TWELVE_HOURS_IN_MINUTES = 720;
// MUST be top-level -- not inside a component
TaskManager.defineTask(SYNC_TASK_NAME, async () => {
try {
const hasNeShowing the first part of this file.
The official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?
Repo: agents-inc/skills
Other skills on agents-inc-skills.
- /ai-infrastructure-huggingface-inference
Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation, audio transcription, translation, summarization, and Inference Endpoints
Open skill - /ai-infrastructure-litellm
LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking, virtual keys, and production deployment
Open skill - /ai-infrastructure-modal
Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client patterns
Open skill - /ai-infrastructure-ollama
Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output, model management, and OpenAI-compatible endpoint
Open skill - /ai-infrastructure-replicate
Replicate SDK patterns for TypeScript/Node.js -- client setup, predictions, streaming, webhooks, file handling, model versioning, deployments, and training
Open skill - /ai-infrastructure-together-ai
Together AI SDK patterns for TypeScript — client setup, chat completions, streaming, structured output, function calling, embeddings, image generation, fine-tuning, and OpenAI-compatible endpoints
Open skill

