npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

expo-check-installed-apps

v0.2.14

Published

Expo Package to check the installed apps in android and ios

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

npx expo install expo-check-installed-apps
// app.json
{
  "expo": {
    "plugins": [
      [
        "expo-check-installed-apps",
        {
          "android": ["com.android.chrome"],
          "ios": ["twitter"]
        }
      ]
    ]
  }
}
npx expo prebuild
import { 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-apps

Then 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-apps

If 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> in AndroidManifest.xml
  • Appends strings to LSApplicationQueriesSchemes in Info.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:

  1. Trims whitespace from every target
  2. Strips trailing :// or : from iOS schemes (e.g. twitter://twitter)
  3. 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!

  1. Fork the repository and create a new branch from main.
  2. Make your changes — please include tests for new behaviour.
  3. 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.


Support the Project

If this library has saved you time, consider supporting its development:

Buy Me a Coffee Donate via PayPal


License

MIT © EndLess728

See LICENSE for the full text.