expo-check-installed-apps
v0.2.14
Published
Expo Package to check the installed apps in android and ios
Maintainers
Readme
Overview
expo-check-installed-apps is a native Expo module and config plugin that lets you query — at runtime — whether specific apps are present on the user's device.
- Android — check by package name (e.g.
com.android.chrome) - iOS — check by URL scheme (e.g.
twitter,fb)
The library normalises and deduplicates your input before hitting the native layer, so you can pass raw schemes like twitter:// and they will work just fine.
Requirements
- Expo SDK 51 or higher
- This package uses native code and does not work inside Expo Go. Use a development build,
expo prebuild, or a bare React Native project.
Table of Contents
- Quick Start
- Installation
- Configuration
- API Reference
- Usage Examples
- Error Handling
- Platform Behaviour
- Contributing
- Support the Project
- License
Quick Start
npx expo install expo-check-installed-apps// app.json
{
"expo": {
"plugins": [
[
"expo-check-installed-apps",
{
"android": ["com.android.chrome"],
"ios": ["twitter"]
}
]
]
}
}npx expo prebuildimport { checkInstalledApps } from "expo-check-installed-apps";
const result = await checkInstalledApps(["com.android.chrome"]);
// → { "com.android.chrome": true }Installation
Managed Expo Projects
Use the Expo CLI installer to get the correct version pinned automatically:
npx expo install expo-check-installed-appsThen follow the Automatic Config Plugin setup and rebuild your app.
Bare React Native Projects
Make sure the expo package is installed and configured in your project first, then:
npm install expo-check-installed-apps
# or
yarn add expo-check-installed-appsIf you are not using Expo config plugins, follow the Manual Native Files setup.
Configuration
Automatic (Config Plugin)
Add the plugin to app.json or app.config.js and list every package/scheme you want to query at runtime. You must declare them ahead of time — this is an OS-level requirement, not a library limitation.
{
"expo": {
"plugins": [
[
"expo-check-installed-apps",
{
"android": ["com.facebook.katana", "com.twitter.android"],
"ios": ["fb", "twitter"]
}
]
]
}
}Plugin options
| Option | Platform | Type | Description | Example |
| --------- | -------- | ---------- | --------------------------------------------------------------------- | ------------------------- |
| android | Android | string[] | Package names added under <queries> in AndroidManifest.xml | ["com.facebook.katana"] |
| ios | iOS | string[] | URL schemes added under LSApplicationQueriesSchemes in Info.plist | ["fb", "twitter"] |
Rebuilding required — any time you change the plugin options you must run
npx expo prebuild(and rebuild your native app) for the changes to take effect.
The plugin automatically:
- Adds
<package android:name="…"/>entries inside<queries>inAndroidManifest.xml - Appends strings to
LSApplicationQueriesSchemesinInfo.plist
Manual (Native Files)
Android — AndroidManifest.xml
Add a <queries> block inside <manifest>:
<manifest>
<queries>
<package android:name="com.facebook.katana" />
<package android:name="com.twitter.android" />
</queries>
<!-- ... rest of your manifest -->
</manifest>iOS — Info.plist
Add the schemes you want to query:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fb</string>
<string>twitter</string>
</array>API Reference
checkInstalledApps
Queries the OS to determine whether specific apps are installed on the device.
function checkInstalledApps(
targets: string[],
): Promise<Record<string, boolean>>;Parameters
| Parameter | Type | Description |
| --------- | ---------- | ---------------------------------------------------------------------------------------------- |
| targets | string[] | Android package names (e.g. com.android.chrome) or iOS URL schemes (e.g. twitter, fb://) |
Input normalisation
Before calling the native layer, the library:
- Trims whitespace from every target
- Strips trailing
://or:from iOS schemes (e.g.twitter://→twitter) - Removes duplicate entries
Validation rules
| Platform | Accepted format | Example |
| -------- | ---------------------------------------------------------- | -------------------- |
| Android | Valid Java package name: [a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)+ | com.android.chrome |
| iOS | Valid URL scheme: [A-Za-z][A-Za-z0-9+.-]* | twitter, fb:// |
Passing an empty string or an invalid identifier throws synchronously before any native call is made.
Returns
Promise<Record<string, boolean>>
Resolves to a plain object keyed by the (normalised) identifier:
{
"com.android.chrome": true, // app is installed
"com.facebook.katana": false // app is not installed
}Returns an empty object {} when the targets array is empty.
Usage Examples
Basic — check a single app
import { checkInstalledApps } from "expo-check-installed-apps";
const result = await checkInstalledApps(["com.android.chrome"]);
if (result["com.android.chrome"]) {
console.log("Chrome is installed");
}Platform-aware check
import { checkInstalledApps } from "expo-check-installed-apps";
import { Platform } from "react-native";
const targets = Platform.select({
android: ["com.google.android.apps.fitness", "com.android.chrome"],
ios: ["fb", "twitter"],
default: [],
});
const installedApps = await checkInstalledApps(targets);
console.log(installedApps);Example response (Android)
{
"com.google.android.apps.fitness": false,
"com.android.chrome": true
}Example response (iOS)
{
"fb": true,
"twitter": false
}Check multiple social apps
import { checkInstalledApps } from "expo-check-installed-apps";
import { Platform } from "react-native";
const SOCIAL_APPS = {
android: [
"com.facebook.katana",
"com.twitter.android",
"com.instagram.android",
"com.whatsapp",
],
ios: ["fb", "twitter", "instagram", "whatsapp"],
};
async function getInstalledSocialApps() {
const targets =
Platform.OS === "android" ? SOCIAL_APPS.android : SOCIAL_APPS.ios;
const result = await checkInstalledApps(targets);
return Object.entries(result)
.filter(([, installed]) => installed)
.map(([app]) => app);
}
const installed = await getInstalledSocialApps();
console.log("Installed social apps:", installed);
// → ["com.facebook.katana", "com.whatsapp"]Error Handling
The library throws for invalid input before making any native call:
import { checkInstalledApps } from "expo-check-installed-apps";
try {
const result = await checkInstalledApps(["com.android.chrome"]);
console.log(result);
} catch (error) {
if (error instanceof TypeError) {
// Invalid targets array or non-string element
console.error("Invalid input:", error.message);
} else {
// Invalid package name / URL scheme format
console.error("Validation error:", error.message);
}
}| Condition | Error type | Message |
| ------------------------------------------ | ----------- | ---------------------------------------------------------------------- |
| targets is not an array | TypeError | checkInstalledApps expects an array of package names or URL schemes. |
| An element is not a string | TypeError | checkInstalledApps targets must be strings. |
| An element is an empty string (after trim) | Error | checkInstalledApps targets cannot be empty. |
| Invalid Android package name | Error | Invalid Android package name: <value> |
| Invalid iOS URL scheme | Error | Invalid iOS URL scheme: <value> |
Platform Behaviour
| Behaviour | Android | iOS | | ------------------------------------ | :-----: | :-: | | Check by package name | ✅ | ❌ | | Check by URL scheme | ❌ | ✅ | | Requires pre-declaration in manifest | ✅ | ✅ | | Works in Expo Go | ❌ | ❌ | | Works in development build | ✅ | ✅ | | Requires rebuild after config change | ✅ | ✅ |
Contributing
Contributions, bug reports, and feature requests are welcome!
- Fork the repository and create a new branch from
main. - Make your changes — please include tests for new behaviour.
- Open a Pull Request with a clear description of the problem and your solution.
For substantial changes, please open an issue first to discuss the approach.
- Bug reports → GitHub Issues
- Source code → GitHub Repository
Support the Project
If this library has saved you time, consider supporting its development:
License
MIT © EndLess728
See LICENSE for the full text.
