{"id":23882047,"url":"https://github.com/acetyld/expo-foreground-actions","last_synced_at":"2026-03-09T16:14:38.786Z","repository":{"id":201252944,"uuid":"707073464","full_name":"Acetyld/expo-foreground-actions","owner":"Acetyld","description":"Start actions that continue to run in the grace period after the user switches apps.","archived":false,"fork":false,"pushed_at":"2024-03-06T19:53:52.000Z","size":2871,"stargazers_count":50,"open_issues_count":3,"forks_count":6,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-08T09:47:00.962Z","etag":null,"topics":["expo","javascript","kotlin","react","react-native","swift","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/expo-foreground-actions","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Acetyld.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-10-19T07:08:45.000Z","updated_at":"2025-01-07T11:12:01.000Z","dependencies_parsed_at":"2024-03-06T21:04:25.159Z","dependency_job_id":null,"html_url":"https://github.com/Acetyld/expo-foreground-actions","commit_stats":null,"previous_names":["acetyld/expo-foreground-actions"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Acetyld%2Fexpo-foreground-actions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Acetyld%2Fexpo-foreground-actions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Acetyld%2Fexpo-foreground-actions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Acetyld%2Fexpo-foreground-actions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Acetyld","download_url":"https://codeload.github.com/Acetyld/expo-foreground-actions/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248115245,"owners_count":21050175,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["expo","javascript","kotlin","react","react-native","swift","typescript"],"created_at":"2025-01-04T02:37:18.141Z","updated_at":"2026-03-09T16:14:38.745Z","avatar_url":"https://github.com/Acetyld.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\u003ch1 align=\"center\"\u003e\n\u003cimg src=\"https://github.com/Acetyld/expo-foreground-actions/blob/main/assets/logo.png\" width=\"100\" /\u003e\n\u003cbr\u003eEXPO-FOREGROUND-ACTIONS\u003c/h1\u003e\n\u003cdiv style=\"font-style: italic\"\u003eRunning Foreground actions for Android/IOS\u003c/div\u003e\n\u003cdiv style=\"opacity: 0.5;margin-top:10px;\"\u003eDeveloped with the software and tools below.\u003c/div\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://img.shields.io/badge/JavaScript-F7DF1E.svg?style=flat-square\u0026logo=JavaScript\u0026logoColor=black\" alt=\"JavaScript\" /\u003e\n\u003cimg src=\"https://img.shields.io/badge/TypeScript-3178C6.svg?style=flat-square\u0026logo=TypeScript\u0026logoColor=white\" alt=\"TypeScript\" /\u003e\n\u003cimg src=\"https://img.shields.io/badge/React-61DAFB.svg?style=flat-square\u0026logo=React\u0026logoColor=black\" alt=\"React\" /\u003e\n\u003cimg src=\"https://img.shields.io/badge/React Native-61DAFB.svg?style=flat-square\u0026logo=React\u0026logoColor=black\" alt=\"React\" /\u003e\n\u003cimg src=\"https://img.shields.io/badge/Swift-F05138.svg?style=flat-square\u0026logo=Swift\u0026logoColor=white\" alt=\"Swift\" /\u003e\n\u003cimg src=\"https://img.shields.io/badge/Kotlin-7F52FF.svg?style=flat-square\u0026logo=Kotlin\u0026logoColor=white\" alt=\"Kotlin\" /\u003e\n\u003cimg src=\"https://img.shields.io/badge/Expo-000020.svg?style=flat-square\u0026logo=Expo\u0026logoColor=white\" alt=\"Expo\" /\u003e\n\n\u003c/p\u003e\n\u003ca href=\"https://www.npmjs.com/package/expo-foreground-actions\"\u003e\n  \u003cimg src=\"https://img.shields.io/npm/v/expo-foreground-actions?style=flat-square\" alt=\"npm version\"\u003e\n\u003c/a\u003e\n\u003cimg src=\"https://img.shields.io/github/license/Acetyld/expo-foreground-actions?style=flat-square\u0026color=5D6D7E\" alt=\"GitHub license\" /\u003e\n\u003cimg src=\"https://img.shields.io/github/last-commit/Acetyld/expo-foreground-actions?style=flat-square\u0026color=5D6D7E\" alt=\"git-last-commit\" /\u003e\n\u003cimg src=\"https://img.shields.io/github/commit-activity/m/Acetyld/expo-foreground-actions?style=flat-square\u0026color=5D6D7E\" alt=\"GitHub commit activity\" /\u003e\n\u003cimg src=\"https://img.shields.io/github/languages/top/Acetyld/expo-foreground-actions?style=flat-square\u0026color=5D6D7E\" alt=\"GitHub top language\" /\u003e\n\u003c/div\u003e\n\n---\n\n## 📖 Table of Contents\n\n- [📖 Table of Contents](#-table-of-contents)\n- [📍 Overview](#-overview)\n- [📦 Features](#-features)\n- [📂 repository Structure](#-repository-structure)\n- [🚀 Getting Started](#-getting-started)\n    - [🔧 Installation](#-installation)\n    - [🤖 How to use](#-how-to-use)\n    - [🤖 Functions](#-functions)\n    - [🤖 Interfaces](#-interfaces)\n- [🛣 Roadmap](#-roadmap)\n- [🤝 Contributing](#-contributing)\n- [📄 License](#-license)\n- [👏 Acknowledgments](#-acknowledgments)\n\n---\n\n## 📍 Overview\n\nStart actions that continue to run in the grace period after the user switches apps. This library facilitates the\nexecution of **ios**'s `beginBackgroundTaskWithName` and **android**'s `startForegroundService` methods. The primary\nobjective is to emulate the behavior of `beginBackgroundTaskWithName`, allowing actions to persist even when the user\nswitches to another app. Examples include sending chat messages, creating tasks, or running synchronizations.\n\nOn iOS, the grace period typically lasts around 30 seconds, while on Android, foreground tasks can run for a longer\nduration, subject to device models and background policies. In general, a foreground task can safely run for about 30\nseconds on both platforms. However, it's important to note that this library is not intended for background location\ntracking. iOS's limited 30-second window makes it impractical for such purposes. For background location tracking,\nalternatives like WorkManager or GTaskScheduler are more suitable.\n\nFor usage instructions, please refer to\nthe [Example](https://github.com/Acetyld/expo-foreground-actions/tree/main/example) provided.\n\n---\n\n## 📦 Features\n\n### For IOS \u0026 Android:\n\n- Execute JavaScript while the app is in the background.\n- Run multiple foreground actions simultaneously.\n- Forcefully terminate all foreground actions.\n\n### For Android:\n\n- Display notifications with customizable titles, descriptions, and optional progress bars, along with support for deep\n  linking.\n- Comply with the latest Android 34+ background policy, ensuring that foreground services continue to run without\n  displaying a visible notification. Users can still access these services from the notification drawer.\n\n### For IOS:\n\n- Receive notifications when the background execution time is about to expire. This feature allows users to save their\n  data and terminate tasks gracefully.\n\n### Web Support:\n\n- Limited support for web platforms. We recommend using the `runInJS` method due to potential errors when attempting to\n  run foreground actions on web browsers.\n\n---\n\n## 📂 Repository Structure\n\n```sh\n└── expo-foreground-actions/\n    ├── .eslintrc.js\n    ├── android/\n    ├── example/\n    │   ├── App.tsx\n    │   ├── android/\n    │   ├── app.json\n    │   ├── babel.config.js\n    │   ├── metro.config.js\n    │   ├── package-lock.json\n    │   ├── package.json\n    │   ├── plugins/\n    │   │   └── expo-foreground-actions.js\n    │   ├── tsconfig.json\n    │   ├── webpack.config.js\n    │   └── yarn.lock\n    ├── ios/\n    ├── package-lock.json\n    ├── package.json\n    ├── plugins/\n    │   └── expo-foreground-actions.js\n    ├── src/\n    │   ├── ExpoForegroundActions.types.ts\n    │   ├── ExpoForegroundActionsModule.ts\n    │   └── index.ts\n    ├── tsconfig.json\n    └── yarn.lock\n\n```\n\n## 🚀 Getting Started\n\n***Dependencies***\n\nPlease ensure you have the following dependencies installed on your system:\n\n`- ℹ️ Expo v49+`\n\n`- ℹ️ Bare/Manage workflow, we do not support Expo GO`\n\n### 🔧 Installation\n\n1. Clone the expo-foreground-actions repository:\n\n   **NPM**\n    ```sh\n    npm install expo-foreground-actions\n    ```\n\n   **Yarn**\n    ```sh\n    yarn add expo-foreground-actions\n    ```\n\n2. Install the plugin, for now download the repo and copy\n   the [plugins](https://github.com/Acetyld/expo-foreground-actions/tree/main/plugins) folder to your project root.\n3. Then update your app.json to include the plugin and a scheme if u wanna use the plugin with a\n   deeplink. \u003cbr/\u003ehttps://docs.expo.dev/guides/linking/\n    ```sh\n   \"expo\": {\n      \"scheme\": \"myapp\",\n      \"plugins\": [\n        [\n          \"./plugins/expo-foreground-actions\"\n        ]\n      ],\n   }\n    ```\n\n3. Make sure the plugin is loaded in your app.json, you can do this by running **prebuild on managed** or by running *\n   *pod install/gradle build** on bare.\n\n### 🤖 How to use?\n\nFor the time being, dedicated documentation is not available. However, you can explore the usage of current methods in\nthe provided example app. Refer to the [Example](https://github.com/Acetyld/expo-foreground-actions/tree/main/example)\nfolder to understand how to utilize this package effectively.\n\n![Example](assets/App_tsx.png)\n\n### 🤖 Functions\n\n#### `runForegroundedAction`\n\n```typescript\nexport const runForegroundedAction = async (\n  act: (api: ForegroundApi) =\u003e Promise\u003cvoid\u003e,\n  androidSettings: AndroidSettings,\n  settings: Settings = { runInJS: false }\n): Promise\u003cvoid\u003e;\n```\n\n- `act`: The foreground action function to be executed.\n- `androidSettings`: Android-specific settings for the foreground action.\n- `settings`: Additional settings for the foreground action.\n\n#### `startForegroundAction`\n\n```typescript\nexport const startForegroundAction = async (\n  options?: AndroidSettings\n): Promise\u003cnumber\u003e;\n```\n\n- `options`: Android-specific settings for the foreground action.\n\n#### `stopForegroundAction`\n\n```typescript\nexport const stopForegroundAction = async (id: number): Promise\u003cvoid\u003e;\n```\n\n- `id`: The unique identifier of the foreground action to stop.\n\n#### `updateForegroundedAction`\n\n```typescript\nexport const updateForegroundedAction = async (\n  id: number,\n  options: AndroidSettings\n): Promise\u003cvoid\u003e;\n```\n\n- `id`: The unique identifier of the foreground action to update.\n- `options`: Updated Android-specific settings for the foreground action.\n\n#### `forceStopAllForegroundActions`\n\n```typescript\nexport const forceStopAllForegroundActions = async (): Promise\u003cvoid\u003e;\n```\n\n- Forcefully stops all running foreground actions.\n\n#### `getForegroundIdentifiers`\n\n```typescript\nexport const getForegroundIdentifiers = async (): Promise\u003cnumber\u003e;\n```\n\n- Retrieves the identifiers of all currently running foreground actions.\n\n#### `getRanTaskCount`\n\n```typescript\nexport const getRanTaskCount = () =\u003e ranTaskCount;\n```\n\n- Retrieves the count of tasks that have run.\n\n#### `getBackgroundTimeRemaining`\n\n```typescript\nexport const getBackgroundTimeRemaining = async (): Promise\u003cnumber\u003e;\n```\n\n- Retrieves the remaining background execution time on iOS.\n\n### 🤖 Interfaces\n\n#### `ExpireEventPayload`\n\n```typescript\nexport type ExpireEventPayload = {\n  remaining: number;\n  identifier: number;\n};\n```\n\n- `remaining`: The remaining time in seconds before the foreground action expires.\n- `identifier`: The unique identifier of the foreground action.\n\n#### `AndroidSettings`\n\n```typescript\nexport interface AndroidSettings {\n  headlessTaskName: string;\n  notificationTitle: string;\n  notificationDesc: string;\n  notificationColor: string;\n  notificationIconName: string;\n  notificationIconType: string;\n  notificationProgress: number;\n  notificationMaxProgress: number;\n  notificationIndeterminate: boolean;\n  linkingURI: string;\n}\n```\n\n- `headlessTaskName`: Name of the headless task associated with the foreground action.\n- `notificationTitle`: Title of the notification shown during the foreground action.\n- `notificationDesc`: Description of the notification.\n- `notificationColor`: Color of the notification.\n- `notificationIconName`: Name of the notification icon.\n- `notificationIconType`: Type of the notification icon.\n- `notificationProgress`: Current progress value for the notification.\n- `notificationMaxProgress`: Maximum progress value for the notification.\n- `notificationIndeterminate`: Indicates if the notification progress is indeterminate.\n- `linkingURI`: URI to link to when the notification is pressed.\n\n#### `Settings`\n\n```typescript\nexport interface Settings {\n  events?: {\n    onIdentifier?: (identifier: number) =\u003e void;\n  }\n  runInJS?: boolean,\n}\n```\n\n- `events`: Event handlers for foreground actions.\n    - `onIdentifier`: A callback function called when an identifier is generated.\n- `runInJS`: Indicates whether to run the foreground action without using a headless task or ios background task.\n\n---\n\n## 🛣 Project Roadmap\n\n\u003e - [X] `ℹ️ Task 1: Initial launch`\n\u003e - [X] `ℹ️ Task 2: Possiblity to run multiple foreground tasks`\n\u003e - [ ] `ℹ️ Any idea's are welcome =)`\n\n---\n\n## 🤝 Contributing\n\nContributions are welcome! Here are several ways you can contribute:\n\n- **[Submit Pull Requests](https://github.com/Acetyld/expo-foreground-actions/blob/main/CONTRIBUTING.md)**: Review open\n  PRs, and submit your own PRs.\n- **[Join the Discussions](https://github.com/Acetyld/expo-foreground-actions/discussions)**: Share your insights,\n  provide feedback, or ask questions.\n- **[Report Issues](https://github.com/Acetyld/expo-foreground-actions/issues)**: Submit bugs found or log feature\n  requests for ACETYLD.\n\n#### *Contributing Guidelines*\n\n\u003cdetails closed\u003e\n\u003csummary\u003eClick to expand\u003c/summary\u003e\n\n1. **Fork the Repository**: Start by forking the project repository to your GitHub account.\n2. **Clone Locally**: Clone the forked repository to your local machine using a Git client.\n   ```sh\n   git clone \u003cyour-forked-repo-url\u003e\n   ```\n3. **Create a New Branch**: Always work on a new branch, giving it a descriptive name.\n   ```sh\n   git checkout -b new-feature-x\n   ```\n4. **Make Your Changes**: Develop and test your changes locally.\n5. **Commit Your Changes**: Commit with a clear and concise message describing your updates.\n   ```sh\n   git commit -m 'Implemented new feature x.'\n   ```\n6. **Push to GitHub**: Push the changes to your forked repository.\n   ```sh\n   git push origin new-feature-x\n   ```\n7. **Submit a Pull Request**: Create a PR against the original project repository. Clearly describe the changes and\n   their motivations.\n\nOnce your PR is reviewed and approved, it will be merged into the main branch.\n\n\u003c/details\u003e\n\n---\n\n## 📄 License\n\nThis project is protected under the [MIT](https://choosealicense.com/licenses) License. For more details, refer to\nthe [LICENSE](https://choosealicense.com/licenses/) file.\n\n---\n\n## 👏 Acknowledgments\n\n- Idea/inspiration from https://github.com/Rapsssito/react-native-background-actions\n- [Expo](https://expo.dev) for providing a platform to build universal apps using React Native.\n- [Benedikt](https://twitter.com/bndkt) for mentioning this package in the \"thisweekinreact\"\n  newsletter: [Week 176](https://thisweekinreact.com/newsletter/176)\n\n[**Return**](#Top)\n\n---\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Facetyld%2Fexpo-foreground-actions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Facetyld%2Fexpo-foreground-actions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Facetyld%2Fexpo-foreground-actions/lists"}