react-native-installer
v0.0.2
Published
A robust React Native module for programmatic APK installation on Android. Supports file installation, permissions handling, and error management.
Maintainers
Readme
react-native-installer
[](https://opensource.org/licenses/JESCON TECHNOLOGIES PVT LTD)
A robust React Native module for programmatic APK installation on Android devices. Perfect for app update flows, side-loading, and custom installation scenarios.
Features
✅ Simple API - Easy-to-use promise-based installation
✅ TypeScript Support - Full type definitions included
✅ Error Handling - Comprehensive error management with callbacks
✅ Platform Detection - Automatic Android platform validation
✅ Timeout Support - Configurable installation timeout
✅ Cache Management - Clear app cache before/after installation
✅ Backward Compatible - Supports both import and require
✅ Production Ready - Tested and battle-hardened
Installation
Using npm
npm install react-native-installerUsing yarn
yarn add react-native-installerQuick Start
import { installAPK, isSupported } from 'react-native-installer';
// Check if supported
if (isSupported()) {
// Install APK
try {
const result = await installAPK('/path/to/app.apk', {
timeout: 30000,
onSuccess: () => console.log('Installation started'),
onError: (error) => console.error('Error:', error)
});
console.log('Result:', result);
} catch (error) {
console.error('Failed:', error);
}
}API Reference
installAPK(filePath, options?)
Installs an APK file on the Android device.
Parameters:
filePath(string, required): Full path to the APK file to installoptions(InstallOptions, optional): Installation configuration
Returns: Promise<InstallResult>
Options:
timeout(number, optional): Installation timeout in milliseconds (default: 10000)onSuccess(function, optional): Callback invoked on successful initiationonError(function, optional): Callback invoked on error
Example:
const result = await installAPK('/storage/emulated/0/Download/app.apk', {
timeout: 15000,
onSuccess: () => console.log('Installing...'),
onError: (error) => console.error('Error:', error)
});isSupported()
Checks if APK installation is supported on the current platform.
Returns: boolean
Example:
if (isSupported()) {
// Android device - installation available
} else {
// Not on Android
}TypeScript Usage
import { installAPK, InstallOptions, InstallResult } from 'react-native-installer';
const installWithType = async (): Promise<void> => {
const options: InstallOptions = {
filePath: '/path/to/app.apk',
timeout: 30000,
onSuccess: () => console.log('Success'),
onError: (error) => console.error('Error:', error),
};
try {
const result: InstallResult = await installAPK(options.filePath, options);
console.log('Result:', result);
} catch (error) {
console.error('Failed:', error);
}
};Types
InstallOptions
interface InstallOptions {
filePath: string; // Path to APK file
skipVerification?: boolean; // Skip file existence check (default: false)
onSuccess?: () => void; // Success callback
onError?: (error: Error) => void; // Error callback
timeout?: number; // Timeout in milliseconds (default: 10000)
}InstallResult
interface InstallResult {
success: boolean; // Installation success status
message: string; // Result message
path?: string; // APK file path
cacheCleared?: boolean; // Whether app cache was cleared before installation
}CacheResult
interface CacheResult {
success: boolean; // Whether cache was cleared successfully
message: string; // Result message
packageName?: string; // Package name for which cache was cleared
}Error Handling
import { installAPK, isSupported } from 'react-native-installer';
const safeInstall = async (filePath) => {
if (!isSupported()) {
console.error('Platform not supported - Android only');
return;
}
try {
const result = await installAPK(filePath, {
timeout: 30000,
onError: (error) => {
console.error('Installation error:', error.message);
},
});
console.log('Installation initiated:', result);
} catch (error) {
console.error('Failed to install APK:', error);
// Handle different error types
if (error.message.includes('timeout')) {
console.error('Installation took too long');
} else if (error.message.includes('Invalid')) {
console.error('Invalid APK file or path');
} else if (error.message.includes('not supported')) {
console.error('APK installation not supported');
}
}
};Cache Management
Clear App Cache
Clear application cache before or after installation:
import { clearAppCache, installAPK } from 'react-native-installer';
// Clear current app cache
const clearCurrentAppCache = async () => {
try {
const result = await clearAppCache();
console.log('Cache cleared:', result.message);
} catch (error) {
console.error('Failed to clear cache:', error);
}
};
// Clear specific package cache
const clearPackageCache = async () => {
try {
const result = await clearAppCache('com.example.app', (error) => {
console.error('Cache clear error:', error);
});
console.log('Cache cleared:', result.message);
} catch (error) {
console.error('Failed to clear cache:', error);
}
};
// Install with automatic cache clearing
const installWithCacheClear = async (filePath) => {
try {
const result = await installAPK(filePath, {
clearCache: true, // Clear cache before installation
packageName: 'com.example.app', // Optional: specific package to clear
timeout: 30000,
onSuccess: () => console.log('Installation started with cache cleared'),
onError: (error) => console.error('Error:', error)
});
console.log('Result:', result);
} catch (error) {
console.error('Failed:', error);
}
};TypeScript Usage
import { clearAppCache, CacheResult } from 'react-native-installer';
const handleCacheClear = async (): Promise<void> => {
try {
const result: CacheResult = await clearAppCache('com.example.app');
if (result.success) {
console.log(`Cache cleared for ${result.packageName}`);
}
} catch (error) {
console.error('Cache clearing failed:', error);
}
};Android Requirements
- Minimum SDK: 16
- Target SDK: 33+
- Required Permission:
REQUEST_INSTALL_PACKAGES(automatically handled by the module)
The module automatically handles Android version differences:
- Android 7.0+: Uses FileProvider for secure file access
- Android <7.0: Uses direct file URI access
Complete Example
import React, { useState, useEffect } from 'react';
import {
View,
Text,
TouchableOpacity,
Alert,
StyleSheet,
ActivityIndicator,
} from 'react-native';
import { installAPK, isSupported } from 'react-native-installer';
import DocumentPicker from 'react-native-document-picker';
export default function AppInstallerScreen() {
const [isInstalling, setIsInstalling] = useState(false);
const [supportedPlatform, setSupportedPlatform] = useState(false);
const [selectedFile, setSelectedFile] = useState(null);
useEffect(() => {
setSupportedPlatform(isSupported());
}, []);
const handlePickFile = async () => {
try {
const result = await DocumentPicker.pick({
type: [DocumentPicker.types.apk],
});
setSelectedFile(result);
} catch (error) {
if (!DocumentPicker.isCancel(error)) {
Alert.alert('Error', `Failed to pick file: ${error.message}`);
}
}
};
const handleInstall = async () => {
if (!selectedFile) {
Alert.alert('No File', 'Please select an APK file first');
return;
}
if (!supportedPlatform) {
Alert.alert('Not Supported', 'APK installation only works on Android');
return;
}
setIsInstalling(true);
try {
const filePath = selectedFile.fileCopyUri || selectedFile.uri;
await installAPK(filePath, {
timeout: 30000,
onSuccess: () => {
Alert.alert(
'Success',
'APK installation has been initiated on your device'
);
setSelectedFile(null);
},
onError: (error) => {
Alert.alert(
'Installation Error',
`Failed to install APK: ${error.message}`
);
},
});
} catch (error) {
Alert.alert('Error', `Failed to install APK: ${error.message}`);
} finally {
setIsInstalling(false);
}
};
return (
<View style={styles.container}>
<Text style={styles.title}>APK Installer</Text>
<TouchableOpacity
onPress={handlePickFile}
disabled={!supportedPlatform || isInstalling}
style={[
styles.button,
(!supportedPlatform || isInstalling) && styles.buttonDisabled,
]}
>
<Text style={styles.buttonText}>
{selectedFile ? 'Change File' : 'Select APK File'}
</Text>
</TouchableOpacity>
{selectedFile && (
<Text style={styles.selectedFile}>
Selected: {selectedFile.name}
</Text>
)}
<TouchableOpacity
onPress={handleInstall}
disabled={!supportedPlatform || isInstalling || !selectedFile}
style={[
styles.button,
styles.installButton,
(!supportedPlatform || isInstalling || !selectedFile) &&
styles.buttonDisabled,
]}
>
{isInstalling ? (
<ActivityIndicator color="white" />
) : (
<Text style={styles.buttonText}>Install APK</Text>
)}
</TouchableOpacity>
{!supportedPlatform && (
<Text style={styles.error}>
APK installation is only supported on Android devices
</Text>
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 30,
},
button: {
backgroundColor: '#007AFF',
paddingHorizontal: 20,
paddingVertical: 12,
borderRadius: 8,
marginVertical: 10,
},
buttonDisabled: {
backgroundColor: '#ccc',
},
installButton: {
backgroundColor: '#34C759',
},
buttonText: {
color: 'white',
fontSize: 16,
fontWeight: 'bold',
},
selectedFile: {
marginTop: 15,
fontSize: 14,
color: '#666',
textAlign: 'center',
},
error: {
marginTop: 20,
color: '#FF3B30',
fontSize: 14,
textAlign: 'center',
},
});Troubleshooting
"Module not found" error
npm install react-native-installer
npx react-native link react-native-installer
npx react-native run-android"Native InstallApk module not available"
- Ensure android/build.gradle has proper dependencies
- Re-run:
npx react-native run-android - Check:
npx react-native doctor
Installation not working
- Verify file path is correct and file exists
- Check Android permissions (usually automatic)
- Ensure device/emulator is Android
License
JESCON TECHNOLOGIES PVT LTD © PRAFULDAS M M
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Support
For issues or questions:
- GitHub Issues: https://github.com/react-native-community/react-native-installer/issues
