Migration Guide
Migrating from react-native-device-info to react-native-nitro-device-info.
Overview
react-native-nitro-device-info ships a drop-in compatibility layer that exposes the exact
react-native-device-info (RNDI) 15.x API surface — same function names, same signatures, same default
DeviceInfo object, same hooks. You import from react-native-nitro-device-info/compat instead of
react-native-device-info, and your call sites stay unchanged.
There are two ways to migrate. Pick based on how much you want to change:
Start with the drop-in path. Move individual call sites to the native API later if you want the last bit of performance — the two can coexist.
Drop-in Migration (recommended)
1. Install
2. Run the codemod
The library bundles a codemod that rewrites every react-native-device-info import to
react-native-nitro-device-info/compat. It only rewrites import specifiers — it never touches
your call sites.
It rewrites ES imports (default, named, namespace), re-exports, and CommonJS require():
Prefer to do it by hand? A project-wide find-and-replace of the import string
'react-native-device-info' → 'react-native-nitro-device-info/compat' achieves the same result.
3. Remove the old dependency
4. Review the documented caveats
The compat layer targets the RNDI 15.x API surface. A small number of APIs return placeholder values because they have no native equivalent in this library — see Compat Layer Caveats below. If your app doesn't use those APIs, you're done.
That's it — no call sites to change, no await to add or remove.
Compat Layer Caveats
The compat layer is signature-compatible across the whole RNDI surface, with these documented exceptions:
Other APIs delegate to this library’s native implementation. They can still return platform-specific placeholders or behave differently from RNDI. A few APIs differ in shape but are converted
for you (e.g. getAvailableLocationProviders() returns RNDI's { gps: true, network: true } map,
getFreeDiskStorage(storageType?) accepts and ignores the iOS storage-type argument, and the async
accessory hooks return RNDI's { loading, result } shape).
Native Migration (optional, for maximum performance)
If you want direct property access and synchronous getters instead of the compat shims, import
DeviceInfoModule from the package root and rewrite call sites using the tables below.
Key Differences
Architecture
- react-native-device-info: API and implementation depend on the installed release
- react-native-nitro-device-info: Nitro HybridObject (JSI)
Properties vs methods — most RNDI methods become direct property accessors:
Synchronous by default — values that were async in RNDI are now sync:
Promise-based methods still need await:
Quick Migration Reference
Device Information
System Resources
Battery Information
Application Metadata
Network & Connectivity
Step-by-Step (native path)
These steps assume you want the native API. For the zero-change path, use Drop-in Migration instead.
1. Install the New Library
2. Update Imports
Find and replace imports across your codebase:
3. Update Module Name
Replace all DeviceInfo references with DeviceInfoModule:
4. Convert Method Calls to Properties
Update method calls that are now properties:
5. Remove Unnecessary await Keywords
Remove await from methods that are now synchronous:
6. Test Your Changes
Run your app and verify:
- All device info calls work correctly
- No runtime errors from async/sync changes
- TypeScript types are correct
Complete Example
Before (react-native-device-info)
After (react-native-nitro-device-info)
Benefits of Migration
1. Performance Improvement
2. Simpler Code
No need for async/await for simple getters:
3. Better TypeScript Support
Full type definitions with excellent IntelliSense:
4. Future-Proof Architecture
Built on React Native's New Architecture (Fabric + JSI) for long-term support.
React Hooks Migration
Drop-in path: every RNDI hook is re-exported from the compat layer with RNDI's exact signature
(including the { loading, result } shape for the async hooks). The codemod rewrites the import for
you; usage is unchanged:
Native path: the package root exports 7 hooks directly, returning bare values (no
AsyncHookResult wrapper). Use these if you migrate call sites to the native API.
RNDI's remaining hooks (useFirstInstallTime, useDeviceName, useHasSystemFeature,
useIsEmulator, useManufacturer) are available on the compat path only, where they return
RNDI's AsyncHookResult<T> shape.
See the React Hooks Guide for detailed hook documentation.
Behavioral Changes (native path only)
These differences apply when you adopt the native API (DeviceInfoModule). The drop-in compat
layer adapts function signatures and hook result shapes. It does not reproduce all platform behavior; review Compat Layer Caveats.
- Synchronous by default: Most methods no longer return Promises
- Property accessors: Some getters are now properties
- Module name: Uses
DeviceInfoModuleinstead ofDeviceInfo - Event listeners: Raw battery/network state listeners are not exposed; use the provided React
hooks (e.g.
useBatteryLevel,usePowerState) for reactive monitoring instead. The compat layer re-exposes RNDI's hooks unchanged.
Troubleshooting
TypeScript Errors After Migration
If you see type errors after migration:
Runtime Errors
If you get "Cannot read property" errors:
- Ensure
react-native-nitro-modulesis installed as peer dependency - Run
pod installon iOS - Clean build (
yarn android/yarn ioswith clean)
Missing Methods
If a method is not available:
- Check the API Reference for the correct method name
- Some methods may have been renamed or consolidated
- Open an issue on GitHub if you need a specific method
Migrating from expo-device
If you're migrating from expo-device, many APIs have compatible alternatives in react-native-nitro-device-info.
Key Differences
API Migration Reference
Migration Example
Before (expo-device):
After (react-native-nitro-device-info):
APIs Not Available
These expo-device APIs do not have direct equivalents:
Platform-Specific Considerations
Uptime Behavior
On iOS, getUptime() is supported only for app-event timing: measuring elapsed time, enabling timers, or converting app-event uptime to an absolute timestamp with startupTime. Keep raw uptime and boot timestamps out of generic device-info payloads. See iOS Privacy Manifest for the declared purposes and transmission limits.
- expo-device: Returns uptime in milliseconds (excludes deep sleep)
- react-native-nitro-device-info: Returns uptime in milliseconds (excludes deep sleep)
- iOS: Uses
systemUptime - Android: Uses
uptimeMillis() - Both platforms return consistent "active time" matching expo-device behavior
- iOS: Uses
Device Year Class
Both libraries use the same Facebook algorithm for calculating device year class based on RAM and CPU specifications. The year class represents an estimated year that the device's hardware was considered high-end.
Root/Jailbreak Detection
- expo-device:
isRootedExperimentalAsync()- Experimental, basic checks - react-native-nitro-device-info:
isDeviceCompromised()- Comprehensive detection- Android: Checks su binaries, root apps, system properties, test-keys
- iOS: Checks Cydia, jailbreak files, sandbox escape, suspicious paths
Migrating from react-native-carrier-info
If you're using react-native-carrier-info for carrier information, you can consolidate into react-native-nitro-device-info.
API Migration Reference
Migration Example
Before (react-native-carrier-info):
After (react-native-nitro-device-info):
Key Benefits
- No async/await: All carrier properties are synchronous
- Single dependency: No need to install separate carrier-info package
- JSI performance: Zero-overhead native access via Nitro Modules
- Unified API: Carrier info alongside 80+ other device properties
Platform Notes
- iOS: Uses
CTTelephonyNetworkInfoandCTCarrierAPIs - Android: Uses
TelephonyManagerAPIs - carrierAllowsVOIP: Returns actual value on iOS, always
trueon Android (no equivalent API) - Empty strings: All properties return
""when no SIM card is present
