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

@chankruze/react-native-in-app-updates

v0.1.1

Published

Lightweight in-app updates for Android (Play Store) and iOS (App Store)

Readme

@chankruze/react-native-in-app-updates

Lightweight in-app updates for Android and iOS.

  • Android — Google Play In-App Updates API (FLEXIBLE + IMMEDIATE flows)
  • iOS — iTunes Search API version check + App Store redirect
  • New Architecture — TurboModule on Android, pure TypeScript on iOS
  • Zero extra dependencies beyond react-native

Compatibility

| Environment | Supported | | ----------------------------- | --------- | | React Native CLI | ✅ | | Expo Bare Workflow | ✅ | | EAS Build + expo-dev-client | ✅ | | Expo Managed Workflow | ❌ | | Expo Go | ❌ |

Expo Managed / Expo Go users: This library requires native module support which is not available in the managed sandbox. Use expo-in-app-updates instead.

Why it won't work in Expo Managed Workflow

Our library uses the standard React Native TurboModule API (NativeReactNativeInAppUpdatesSpec, TurboModuleRegistry). Expo Go and Expo Managed Workflow sandbox the native layer — custom TurboModules can't be registered because there's no access to the native build pipeline. The app would crash on the TurboModuleRegistry.getEnforcing call at startup.

Expo has their own native module system (expo-modules-core) and their own in-app updates package (expo-in-app-updates) built on it. That's the right tool for managed Expo users.

Installation

yarn add @chankruze/react-native-in-app-updates
# or
npm install @chankruze/react-native-in-app-updates

iOS

No native setup needed — iOS is pure TypeScript.

No LSApplicationQueriesSchemes required. Unlike libraries that use the itms-apps:// deep link scheme, this library opens the App Store via a standard https://apps.apple.com/... URL. HTTPS URLs do not need to be whitelisted in Info.plist or app.json.

Android

No manual linking needed. The library uses com.google.android.play:app-update-ktx which is bundled.

Important: In-App Updates only work on release builds installed from the Play Store. Debug builds always return updateAvailable: false.

Quick start

import { useEffect } from 'react';
import { Platform, Linking } from 'react-native';
import {
  checkForUpdate,
  startUpdate,
  installUpdate,
  addUpdateListener,
  UpdateType,
  InstallStatus,
  type IosUpdateInfo,
  type AndroidUpdateInfo,
} from '@chankruze/react-native-in-app-updates';

function useInAppUpdates() {
  useEffect(() => {
    // Android FLEXIBLE: auto-install once download completes
    if (Platform.OS !== 'android') return;
    return addUpdateListener('onInAppUpdateStatus', (event) => {
      if (event.status === InstallStatus.DOWNLOADED) {
        installUpdate();
      }
    });
  }, []);

  useEffect(() => {
    const run = async () => {
      try {
        if (Platform.OS === 'ios') {
          const info = (await checkForUpdate({
            bundleId: 'com.example.myapp',
            country: 'us',
          })) as IosUpdateInfo;

          if (info.updateAvailable && info.appStoreUrl) {
            // Show your own modal, then:
            Linking.openURL(info.appStoreUrl);
          }
        } else {
          const info = (await checkForUpdate({})) as AndroidUpdateInfo;
          if (info.updateAvailable) {
            // priority >= 4 → force IMMEDIATE, otherwise FLEXIBLE
            const type =
              info.updatePriority >= 4
                ? UpdateType.IMMEDIATE
                : UpdateType.FLEXIBLE;
            await startUpdate(type);
          }
        }
      } catch {
        // in-app updates are best-effort — never interrupt the user
      }
    };

    run();
  }, []);
}

API

checkForUpdate(options?)

Checks whether an update is available.

| Option | Type | Platform | Description | | ------------ | -------- | -------------- | --------------------------------------------- | | bundleId | string | iOS (required) | App bundle ID | | country | string | iOS | ISO 3166-1 country code (e.g. 'us', 'in') | | curVersion | string | iOS | Current version to compare against |

Returns AndroidUpdateInfo on Android:

| Field | Type | Description | | -------------------- | -------------------- | -------------------------------------------------- | | updateAvailable | boolean | Whether a newer version exists | | availabilityStatus | AvailabilityStatus | Raw Play Store availability enum | | flexibleAllowed | boolean | FLEXIBLE update is allowed | | immediateAllowed | boolean | IMMEDIATE update is allowed | | updatePriority | number | Server-set priority 0–5 (use >= 4 for IMMEDIATE) | | versionCode | number | Available Play Store version code | | daysSinceRelease | number \| null | Days since update was published |

Returns IosUpdateInfo on iOS:

| Field | Type | Description | | ----------------- | ---------------- | ------------------------------------------ | | updateAvailable | boolean | Whether a newer version exists | | storeVersion | string | Latest version string (e.g. "2.1.0") | | releaseDate | string \| null | ISO 8601 release date | | appStoreUrl | string \| null | Direct App Store URL for Linking.openURL |


startUpdate(updateType?)

Android only. Triggers the Play Store update flow.

await startUpdate(UpdateType.FLEXIBLE); // download in background
await startUpdate(UpdateType.IMMEDIATE); // full-screen blocking update

installUpdate()

Android only. Completes a finished FLEXIBLE download. Call this when onInAppUpdateStatus fires with status === InstallStatus.DOWNLOADED.


addUpdateListener(event, listener)

Android only. Subscribes to native update events. Returns an unsubscribe function.

const unsubscribe = addUpdateListener('onInAppUpdateStatus', (event) => {
  console.log(event.status); // InstallStatus enum value
  console.log(event.bytesDownloaded); // bytes downloaded so far
  console.log(event.totalBytesToDownload);
});

// cleanup
unsubscribe();

Events:

| Event | Payload | Description | | --------------------- | ------------------- | ------------------------------------ | | onInAppUpdateStatus | UpdateStatusEvent | Download progress + install status | | onInAppUpdateResult | UpdateResultEvent | Final result (installed / cancelled) |


openAppStore(appId)

iOS only. Opens the App Store page for the given numeric App Store ID.

openAppStore('123456789');
// opens https://apps.apple.com/app/id123456789

Alternatively, use Linking.openURL(info.appStoreUrl) with the URL from checkForUpdate.

Enums

enum UpdateType {
  FLEXIBLE = 0, // background download, user continues using app
  IMMEDIATE = 1, // full-screen blocking update
}

enum InstallStatus {
  UNKNOWN = 0,
  PENDING = 1,
  DOWNLOADING = 2,
  INSTALLING = 3,
  INSTALLED = 4,
  FAILED = 5,
  CANCELED = 6,
  DOWNLOADED = 11, // ready to install — call installUpdate()
}

enum AvailabilityStatus {
  UNKNOWN = 0,
  UNAVAILABLE = 1,
  AVAILABLE = 2,
  DEVELOPER_TRIGGERED = 3,
}

Android testing

Play Store In-App Updates require a real device with a release build installed from the Play Store (or Internal Testing track).

  1. Upload versionCode = 1 to Play Console → Internal Testing track
  2. Install on device via the Internal Testing link
  3. Upload versionCode = 2 to Internal Testing (no need to publish)
  4. Open the app — checkForUpdate() will now return updateAvailable: true

iOS testing

checkForUpdate() hits the live iTunes Search API. To test:

  1. Ensure your app is published on the App Store
  2. Pass your production bundleId and the correct country code
  3. If the App Store version is higher than curVersion, updateAvailable will be true

License

MIT


Made with create-react-native-library