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

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.

Readme

react-native-installer

npm version [![License: JESCON TECHNOLOGIES PVT LTD](https://img.shields.io/badge/License-JESCON TECHNOLOGIES PVT LTD-yellow.svg)](https://opensource.org/licenses/JESCON TECHNOLOGIES PVT LTD) Platform - Android

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-installer

Using yarn

yarn add react-native-installer

Quick 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 install
  • options (InstallOptions, optional): Installation configuration

Returns: Promise<InstallResult>

Options:

  • timeout (number, optional): Installation timeout in milliseconds (default: 10000)
  • onSuccess (function, optional): Callback invoked on successful initiation
  • onError (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