The library provides synchronous access to all app version information. These values are cached at module initialization, so repeated reads have zero native overhead —no bridge calls, no async operations.
Synchronous properties
All version information is available immediately through the VersionCheck object:
import { VersionCheck } from 'react-native-nitro-version-check' ;
VersionCheck . version ; // "1.2.0"
VersionCheck . buildNumber ; // "42"
VersionCheck . packageName ; // "com.example.app"
VersionCheck . installSource ; // "appstore" | "testflight" | "playstore" | undefined
VersionCheck . getCountry (); // "US"
These properties are cached at module init time, ensuring zero JSI overhead on repeated access. The values are plain JavaScript strings, not native calls.
Version string
The current app version as a string.
VersionCheck . version // "1.2.0"
Reads from CFBundleShortVersionString in your Info.plist: < key > CFBundleShortVersionString </ key >
< string > 1.2.0 </ string >
This is the user-facing version number displayed in the App Store. Reads from versionName in your build.gradle: android {
defaultConfig {
versionName "1.2.0"
}
}
This is the user-facing version string displayed in Google Play.
Build number
The current build number or version code as a string.
VersionCheck . buildNumber // "42"
Reads from CFBundleVersion in your Info.plist: < key > CFBundleVersion </ key >
< string > 42 </ string >
This is the build number that increments with each App Store submission. Reads from versionCode in your build.gradle (returned as a string): android {
defaultConfig {
versionCode 42
}
}
This is the integer version code that must increment with each Play Store release.
Use buildNumber for internal tracking and debugging. It’s particularly useful for crash reporting and support tickets.
Package name
The app’s unique identifier (Bundle ID on iOS, Application ID on Android).
VersionCheck . packageName // "com.example.app"
Reads the Bundle ID from your Info.plist: < key > CFBundleIdentifier </ key >
< string > com.example.app </ string >
Reads the Application ID from your build.gradle: android {
defaultConfig {
applicationId "com.example.app"
}
}
Install source
Detects where the app was installed from. Returns undefined for development builds or sideloaded apps.
VersionCheck . installSource // "appstore" | "testflight" | "playstore" | undefined
Possible values
type InstallSource = "appstore" | "testflight" | undefined
if ( VersionCheck . installSource === "testflight" ) {
// Running a TestFlight build
enableBetaFeatures ();
}
if ( VersionCheck . installSource === "appstore" ) {
// Production App Store build
}
if ( VersionCheck . installSource === undefined ) {
// Development build or sideloaded
}
Use cases
Enable beta features in TestFlight
const showBetaUI = VersionCheck . installSource === "testflight" ;
return (
< View >
{ showBetaUI && < BetaFeaturePanel />}
< MainContent />
</ View >
);
Conditional analytics tracking
if ( VersionCheck . installSource === "appstore" || VersionCheck . installSource === "playstore" ) {
// Only track analytics for production builds
Analytics . init ( API_KEY );
}
Debug mode for development builds
const isDevelopment = VersionCheck . installSource === undefined ;
if ( isDevelopment ) {
console . log ( "Running in development mode" );
enableDebugMenu ();
}
Device country
Returns the device’s current 2-letter ISO country code.
VersionCheck . getCountry () // "US"
This is a synchronous Nitro call—no await needed. The country code is determined by the device’s locale settings, not GPS or IP address.
Use cases
const country = VersionCheck . getCountry ();
const showPaymentFeature = [ "US" , "CA" , "GB" ]. includes ( country );
const country = VersionCheck . getCountry ();
const theme = country === "CN" ? chineseTheme : defaultTheme ;
How caching works
All properties except getCountry() are cached as plain JavaScript values at module initialization:
// From source: package/src/index.ts
const HybridVersionCheck = NitroModules . createHybridObject < VersionCheckType >( "VersionCheck" );
// Cached at module init — plain JS values, no JSI overhead on repeated access.
const version = HybridVersionCheck . version ;
const buildNumber = HybridVersionCheck . buildNumber ;
const packageName = HybridVersionCheck . packageName ;
const installSource = HybridVersionCheck . installSource ;
This means:
Module loads
When the module is first imported, it reads all properties from native once.
Values cached
These values are stored as plain JavaScript strings in memory.
Zero overhead access
Every subsequent access reads from the cached JavaScript value—no bridge call, no JSI call, just a variable lookup.
You can access these properties thousands of times per second without any performance impact. They’re just plain JavaScript variables.
Complete example
Here’s a settings screen that displays all version information:
import { VersionCheck } from 'react-native-nitro-version-check' ;
import { View , Text , StyleSheet } from 'react-native' ;
export default function SettingsScreen () {
return (
< View style = {styles. container } >
< Text style = {styles. label } > Version : { VersionCheck . version }</ Text >
< Text style = {styles. label } > Build : { VersionCheck . buildNumber }</ Text >
< Text style = {styles. label } > Package : { VersionCheck . packageName }</ Text >
< Text style = {styles. label } > Country : { VersionCheck . getCountry ()}</ Text >
< Text style = {styles. label } >
Install : { VersionCheck . installSource ?? "Dev Build" }
</ Text >
</ View >
);
}
const styles = StyleSheet . create ({
container: {
padding: 24 ,
},
label: {
fontSize: 15 ,
marginVertical: 2 ,
},
});
Comparison with other libraries
Traditional React Native libraries require async bridge calls to read native values. With Nitro Modules, all version info is synchronous and cached .
// ❌ Old approach (react-native-device-info)
import DeviceInfo from 'react-native-device-info' ;
const version = await DeviceInfo . getVersion (); // Async bridge call
// ✅ Nitro approach (this library)
import { VersionCheck } from 'react-native-nitro-version-check' ;
const version = VersionCheck . version ; // Instant, cached value
Best practices
Import once, use everywhere : The cached values are shared across your entire app
No useEffect needed : These are synchronous values, safe to use directly in render
Perfect for crash reports : Include version, buildNumber, and installSource in all error logs
Combine with update checks : Use version alongside needsUpdate() to show before/after versions
import { VersionCheck , needsUpdate , getLatestVersion } from 'react-native-nitro-version-check' ;
if ( await needsUpdate ()) {
const latest = await getLatestVersion ();
console . log ( `Update available: ${ VersionCheck . version } → ${ latest } ` );
}