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

forced-expo-update

v0.0.2

Published

Global Expo Updates provider + hook

Downloads

232

Readme

forced-expo-update

A tiny, zero-config Provider for Expo Updates that checks for updates as soon as the app opens and applies them automatically.

The goal is simple:

  • Wrap your app once with a Provider
  • The library will check/fetch updates on app start
  • If there is an update, it will reload the app (configurable)

It also includes optional conveniences:

  • Reload immediately or wait for user inactivity ("idle")
  • Require a screen-level gate hook to be mounted before an update reload can happen

Install

npm i forced-expo-update@update

This library requires these peer dependencies in your app:

  • expo-updates
  • react
  • react-native

Usage (zero config)

Add ExpoUpdatesProvider at the root of your app. That’s it.

import { ExpoUpdatesProvider } from "forced-expo-update";

export function App() {
  return <ExpoUpdatesProvider>{/* your app */}</ExpoUpdatesProvider>;
}

What happens by default

  • The provider waits a small initial delay (a few seconds)
  • It checks if an update is available
  • If available, it fetches the update
  • If a new update was downloaded, it reloads the app

This helps avoid the "update only applies on the next open" feeling.

Enable/Disable globally

You can disable the entire behavior without removing the Provider:

<ExpoUpdatesProvider enabled={false}>{children}</ExpoUpdatesProvider>

Options

You can pass optional options to tune behavior.

import { ExpoUpdatesProvider } from "forced-expo-update";

export function App() {
  return (
    <ExpoUpdatesProvider
      options={{
        checkIntervalMinutes: 30,
        checkOnAppStateChange: true,
        reloadImmediately: true,
        delayBeforeReloadMs: 3000,
        maxRetries: 2,
        fetchTimeoutMs: 30000,
      }}
    >
      {children}
    </ExpoUpdatesProvider>
  );
}

Callbacks

<ExpoUpdatesProvider
  options={{
    onUpdateAvailable: () => {
      // update exists on server
    },
    onUpdateDownloaded: () => {
      // update has been downloaded
    },
    onError: (error) => {
      // after max retries
      console.log(error);
    },
  }}
>
  {children}
</ExpoUpdatesProvider>

Reload strategy: immediate vs idle

Sometimes you don’t want to reload while the user is actively interacting with the app.

This library supports two reload strategies:

  • "immediate" (default): reloads as soon as an update is downloaded (after delayBeforeReloadMs)
  • "whenIdle": waits for a period of inactivity before reloading

Idle reload

<ExpoUpdatesProvider
  options={{
    reloadStrategy: "whenIdle",
    idleReloadAfterMs: 2 * 60 * 1000,
  }}
>
  {children}
</ExpoUpdatesProvider>

Important:

  • Even with "whenIdle", the provider still checks/fetches updates on app start
  • Only the reload is delayed until the idle timer completes

Screen gate (only reload if a specific screen is mounted)

In some apps you only want to apply updates when the user is on a safe screen (for example, a home screen), not in the middle of a checkout.

Enable gate mode:

<ExpoUpdatesProvider
  options={{
    gateMode: "requireGate",
  }}
>
  {children}
</ExpoUpdatesProvider>

Then, in the screen(s) where it is safe to reload, mount the gate hook:

import { useExpoUpdatesGate } from "forced-expo-update";

export function HomeScreen() {
  useExpoUpdatesGate();

  return null;
}

How it works:

  • If gateMode is "none" (default), updates can reload anytime
  • If gateMode is "requireGate", the Provider will only trigger reload while at least one gate is mounted

Manual check

If you want to manually trigger a check (for example from a settings screen):

import { useExpoUpdates } from "forced-expo-update";

export function Settings() {
  const { checkForUpdates } = useExpoUpdates();

  const onPress = async () => {
    await checkForUpdates();
  };

  return null;
}

Notes

  • This library does nothing in development mode (__DEV__) to avoid disrupting your dev workflow.
  • Actual update availability depends on your expo-updates configuration (release channels, runtime version, etc.).

API

ExpoUpdatesProvider

Props:

  • enabled?: boolean (default true)
  • options?: ExpoUpdatesOptions

ExpoUpdatesOptions

  • checkIntervalMinutes?: number
  • checkOnAppStateChange?: boolean
  • reloadImmediately?: boolean
  • fetchTimeoutMs?: number
  • maxRetries?: number
  • delayBeforeReloadMs?: number
  • reloadStrategy?: "immediate" | "whenIdle"
  • idleReloadAfterMs?: number
  • gateMode?: "none" | "requireGate"
  • onUpdateAvailable?: () => void
  • onUpdateDownloaded?: () => void
  • onError?: (error: Error) => void

Hooks

  • useExpoUpdates()
  • useExpoUpdatesGate()

License

MIT