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-nitro-ota

v0.10.0

Published

A package to react-native-nitro-ota

Downloads

1,285

Readme

react-native-nitro-ota

Still in Alpha and will have issues

⚡️ High-performance Over-The-Air (OTA) updates for React Native - Powered by Nitro Modules

Download, unzip, and apply JavaScript bundle updates at runtime without going through the App Store or Play Store review process.

✨ Features

  • 🚀 Native Performance - Built with Nitro Modules for maximum speed
  • 🧵 Off JS Thread - All operations run on different threads, keeping your JS thread free
  • 🌐 Server Agnostic - Works with any CDN, S3, GitHub Releases, or custom server
  • 📦 Automatic Bundle Management - Handles download, extraction, and cleanup
  • 🔒 Version Control - Built-in version checking and management

📦 Installation

npm install react-native-nitro-ota react-native-nitro-modules
# or
yarn add react-native-nitro-ota react-native-nitro-modules

Note: react-native-nitro-modules is required as this library relies on Nitro Modules.

📱 Platform-Specific Setup (Required!)

Android: Native Bundle Loading

In your MainApplication.kt, add the bundle path loader:

import com.facebook.react.ReactApplication
import com.facebook.react.ReactNativeHost
import com.facebook.react.defaults.DefaultReactNativeHost
import com.margelo.nitro.nitroota.core.getStoredBundlePath

class MainApplication : Application(), ReactApplication {

  override val reactNativeHost: ReactNativeHost =
      object : DefaultReactNativeHost(this) {

        override fun getPackages(): List<ReactPackage> =
            PackageList(this).packages

        override fun getJSMainModuleName(): String = "index"

        override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG

        // 🔥 Load OTA bundle if available, otherwise use default
        override fun getJSBundleFile(): String? {
          return getStoredBundlePath(this@MainApplication)
        }
      }
}

If using modern React host:

import com.facebook.react.ReactHost
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
import com.margelo.nitro.nitroota.core.getStoredBundlePath

class MainApplication : Application(), ReactApplication {

  override val reactHost: ReactHost by lazy {
    getDefaultReactHost(
      context = applicationContext,
      packageList = PackageList(this).packages,
      jsBundleFilePath = getStoredBundlePath(applicationContext)
    )
  }
}

iOS: NitroOtaBundleManager

  1. Install pods:
cd ios && pod install
  1. Update AppDelegate.swift:
import UIKit
import React
import NitroOtaBundleManager

class AppDelegate: UIResponder, UIApplicationDelegate {

    override func bundleURL() -> URL? {
        #if DEBUG
        return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
        #else
        // Check for OTA bundle
        if let bundlePath = NitroOtaBundleManager.shared.getStoredBundlePath() {
            let bundleURL = URL(fileURLWithPath: bundlePath)

            return bundleURL
        }

        // Fallback to default bundle
        return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
        #endif
    }
}

🚀 Quick Start

Option 1: GitHub OTA (Easiest! 🔥)

Use the githubOTA helper to point directly to a GitHub repository:

import { githubOTA, OTAUpdateManager } from 'react-native-nitro-ota';

// Configure GitHub URLs
const { downloadUrl, versionUrl } = githubOTA({
  githubUrl: 'https://github.com/your-username/your-ota-repo',
  otaVersionPath: 'ota.version', // or 'ota.version.json' for advanced features
  ref: 'main', // optional, defaults to 'main'
});

// Create update manager
const otaManager = new OTAUpdateManager(downloadUrl, versionUrl);

// Check for updates
const hasUpdate = await otaManager.checkForUpdates();
if (hasUpdate) {
  await otaManager.downloadUpdate();
  otaManager.reloadApp();
}

// Or use advanced JS checking (supports JSON format)
const updateInfo = await otaManager.checkForUpdatesJS();
if (updateInfo?.hasUpdate && updateInfo.isCompatible) {
  console.log('Compatible update available:', updateInfo.remoteVersion);
  await otaManager.downloadUpdate();
  otaManager.reloadApp();
}

// Get current version
const currentVersion = otaManager.getVersion();
console.log('Current OTA version:', currentVersion);

Option 2: Custom Server/CDN

1. Download and Apply OTA Update

import { NitroOta } from 'react-native-nitro-ota';

// Download and unzip bundle from any server
const updatePath = await NitroOta.downloadAndUnzipFromUrl(
  'https://your-cdn.com/bundles/latest.zip',
  'https://your-cdn.com/bundles/version.txt' // optional version file
);

console.log('Update downloaded to:', updatePath);

// Restart app to apply update
// Use your preferred restart method or RN's DevSettings

2. Check for Updates

// Check if a new version is available
const hasUpdate = await NitroOta.checkForUpdates(
  'https://your-cdn.com/bundles/version.txt'
);

if (hasUpdate) {
  console.log('New version available!');
  // Download and apply update
}

3. Get Current Version

const currentVersion = NitroOta.getStoredOtaVersion();
console.log('Current OTA version:', currentVersion);

3. Get Current Version

NitroOta.reloadApp();

🔄 Background Updates (Experimental)

⚠️ HIGHLY ALPHA FEATURE - This feature is experimental and needs thorough testing. Use with caution in production.

Schedule automatic background checks for updates that run periodically:

import { OTAUpdateManager } from 'react-native-nitro-ota';

const otaManager = new OTAUpdateManager(downloadUrl, versionCheckUrl);

// Schedule background check every hour (3600 seconds)
otaManager.scheduleBackgroundCheck(3600);

📝 Understanding Version Files

Basic: ota.version (Simple Text)

The ota.version file is a simple text file that contains your current bundle version. The version can be anything - numbers, strings, or even creative identifiers like "apple", "orange", "winter2024", or "bugfix-v3".

echo "1.0.0" > ota.version

Advanced: ota.version.json (With Metadata)

For more control, use the JSON format with semantic versioning and target app versions:

{
  "version": "1.2.3",
  "isSemver": true,
  "targetVersions": {
    "android": ["2.30.1", "2.30.2"],
    "ios": ["2.30.1"]
  },
  "releaseNotes": "Bug fixes and improvements"
}

JavaScript API for Advanced Checking:

import { checkForOTAUpdatesJS } from 'react-native-nitro-ota';

// Get detailed update info
const result = await checkForOTAUpdatesJS(
  'https://example.com/ota.version.json'
);
if (result?.hasUpdate && result.isCompatible) {
  console.log(`New version: ${result.remoteVersion}`);
  console.log(`Notes: ${result.metadata?.releaseNotes}`);
}

Note: Both formats are supported. The library automatically detects which one you're using.

📦 Creating and Uploading Bundles

Follow these steps to generate and distribute your OTA bundle:

1. Generate the JavaScript Bundle

Run the following commands to create a production-ready bundle and assets for your platform:

For Android

npx react-native bundle \
  --platform android \
  --dev false \
  --entry-file index.js \
  --bundle-output android/App-Bundles/index.android.bundle \
  --assets-dest android/App-Bundles

For iOS

npx react-native bundle \
  --platform ios \
  --dev false \
  --entry-file index.js \
  --bundle-output ios/App-Bundles/index.jsbundle \
  --assets-dest ios/App-Bundles

Result:
Your bundles and assets will be generated in android/App-Bundles/ or ios/App-Bundles/ respectively.


2. Package the Bundle

After generating the bundle, compress the entire output folder (including the assets) into a single zip file:

# For Android
cd android && zip -r App-Bundles.zip App-Bundles

# For iOS
cd ios && zip -r App-Bundles.zip App-Bundles

3. Distribute the Bundle

Upload the zipped bundle file to your backend, CDN, or preferred file hosting service so that your app can download it for OTA updates.


🔑 Real-World Example

In the Jellify App:

This keeps OTA releases well organized and accessible for deployment.

🤝 Contributing

See CONTRIBUTING.md for development workflow and guidelines.

📄 License

MIT