Skip to main content
The library provides a powerful needsUpdate() function that compares your app’s current version against the latest version available in the App Store or Play Store using semantic versioning.

How it works

The needsUpdate() function:
  1. Fetches the latest version from the store API
  2. Compares it against your current app version using semantic versioning
  3. Returns true if an update is available at the specified level
1

Fetch the latest version

The function internally calls getLatestVersion() which queries:
  • iOS: iTunes Lookup API
  • Android: Google Play Store API
2

Compare versions

Uses semantic version comparison to determine if the store version is newer than your current version.
3

Return result

Returns a boolean indicating whether an update is available at the requested granularity level.

Basic usage

The simplest way to check for updates is to call needsUpdate() without any parameters:
import { needsUpdate, getStoreUrl } from 'react-native-nitro-version-check';
import { Linking } from 'react-native';

if (await needsUpdate()) {
  const url = await getStoreUrl();
  Linking.openURL(url);
}
By default, this checks for any version increase (patch level or higher).

Update levels

You can control the granularity of update checks using the level option. This determines what kind of version changes should trigger an update prompt.
Only returns true for major version bumps (e.g., 1.x.x → 2.x.x):
const majorUpdate = await needsUpdate({ level: "major" });
Examples:
  • Current: 1.5.3, Latest: 2.0.0true
  • Current: 1.5.3, Latest: 1.6.0false
  • Current: 1.5.3, Latest: 1.5.4false

Semantic versioning logic

The version comparison follows strict semantic versioning rules. The needsUpdate() function internally compares versions based on the specified level:
  • Major comparison: Returns true only if the major version increases (e.g., 1.x.x → 2.x.x)
  • Minor comparison: Returns true if major or minor version increases (e.g., 1.2.x → 1.3.x or 2.x.x)
  • Patch comparison: Returns true for any version increase (default behavior)
Version strings are parsed as major.minor.patch. Any missing parts default to 0.

Getting the latest version

You can also fetch the latest version directly without checking if an update is needed:
import { getLatestVersion } from 'react-native-nitro-version-check';

const latest = await getLatestVersion(); // "1.3.0"
This is useful when you want to:
  • Display the latest version in your UI
  • Implement custom version comparison logic
  • Show a “What’s New” dialog with version-specific content

Opening the store

When an update is available, you can direct users to the appropriate store using getStoreUrl():
import { getStoreUrl } from 'react-native-nitro-version-check';
import { Linking } from 'react-native';

const url = await getStoreUrl();
Linking.openURL(url);
The function automatically resolves to:
  • iOS: App Store URL for your app
  • Android: Google Play Store URL for your app

Complete example

Here’s a full implementation showing different update levels with proper UI feedback:
import { useEffect, useState } from 'react';
import { ActivityIndicator, Linking, Text, TouchableOpacity, View } from 'react-native';
import { getLatestVersion, getStoreUrl, needsUpdate, VersionCheck } from 'react-native-nitro-version-check';

export default function App() {
  const [loading, setLoading] = useState(true);
  const [storeUrl, setStoreUrl] = useState<string | null>(null);
  const [latestVersion, setLatestVersion] = useState<string | null>(null);
  const [updateLevel, setUpdateLevel] = useState<"major" | "minor" | "patch" | null>(null);

  useEffect(() => {
    const fetchAll = async () => {
      try {
        const [url, latest] = await Promise.all([getStoreUrl(), getLatestVersion()]);
        setStoreUrl(url);
        setLatestVersion(latest);

        // Check each level to determine the most specific update type
        const isMajor = await needsUpdate({ level: "major" });
        if (isMajor) {
          setUpdateLevel("major");
        } else {
          const isMinor = await needsUpdate({ level: "minor" });
          if (isMinor) {
            setUpdateLevel("minor");
          } else {
            const isPatch = await needsUpdate({ level: "patch" });
            if (isPatch) setUpdateLevel("patch");
          }
        }
      } catch {
        console.error('App not found in store');
      }
      setLoading(false);
    };
    fetchAll();
  }, []);

  return (
    <View>
      <Text>Current Version: {VersionCheck.version}</Text>
      
      {loading ? (
        <ActivityIndicator />
      ) : (
        <>
          <Text>Latest Version: {latestVersion}</Text>

          {updateLevel && storeUrl && (
            <TouchableOpacity onPress={() => Linking.openURL(storeUrl)}>
              <Text>
                {updateLevel === "major" ? "Major" : updateLevel === "minor" ? "Minor" : "Patch"} update availabletap to open store
              </Text>
            </TouchableOpacity>
          )}

          {!updateLevel && <Text>App is up to date</Text>}
        </>
      )}
    </View>
  );
}

Error handling

The store APIs may fail if:
  • The app is not published in the store
  • Network connectivity issues occur
  • The package name/bundle ID is incorrect
  • Rate limiting is triggered
Always wrap update checks in try-catch blocks:
try {
  if (await needsUpdate()) {
    const url = await getStoreUrl();
    Linking.openURL(url);
  }
} catch (error) {
  console.error('Failed to check for updates:', error);
  // Show fallback UI or skip the check
}

Best practices

  • Check once per session: Don’t check for updates on every screen mount
  • Use appropriate levels: Reserve "major" for breaking changes that require user action
  • Provide context: Explain why the update is important before redirecting to the store
  • Don’t block the app: Make update prompts dismissible unless absolutely critical

Determining update urgency

const isCritical = await needsUpdate({ level: "major" });
const isRecommended = await needsUpdate({ level: "minor" });
const isOptional = await needsUpdate({ level: "patch" });

if (isCritical) {
  // Show a blocking modal
} else if (isRecommended) {
  // Show a dismissible banner
} else if (isOptional) {
  // Show a subtle notification
}

Build docs developers (and LLMs) love