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

@zepto-labs/react-native-delta

v1.0.0

Published

Delta sdk for react native apps

Readme

Ship the change. Not the bundle.

The next generation of runtime updates for React Native.


delta is a production-ready patch-based runtime update platform for React Native that enables you to ship bug fixes, performance improvements, and new features instantly—without waiting for App Store or Play Store approvals.

Unlike traditional OTA solutions that download and replace the entire JavaScript bundle, delta generates and applies lightweight binary patches, delivering only what changed. The result is dramatically smaller downloads, faster update adoption, lower bandwidth consumption, and a seamless update experience for your users.


Why delta?

Traditional OTA platforms replace the entire JavaScript bundle every time you publish an update—even if you've changed only a few lines of code.

Delta takes a fundamentally different approach.

Using intelligent binary delta patching, it computes the difference between releases and delivers only the bytes required to transform one version into another. This significantly reduces update sizes, accelerates deployments, and helps users stay on the latest version with minimal data usage.

What does the SDK do?

The react-native-delta SDK seamlessly integrates with your React Native application and manages the complete runtime update lifecycle.

  • Automatically checks for available updates.
  • 📦 Downloads lightweight delta patches instead of full JavaScript bundles.
  • 🔐 Verifies every update before installation to ensure integrity and security.
  • 🚀 Applies updates seamlessly with minimal interruption to the user experience.
  • 🔄 Safely rolls back to the previous version if an update fails.
  • 🎯 Targets compatible app versions, ensuring only supported devices receive updates.
  • 📊 Provides update metadata and lifecycle events for monitoring and analytics.

Whether you're shipping a critical hotfix or rolling out your next feature, Delta enables continuous delivery while keeping updates fast, reliable, and bandwidth-efficient.

Ship only the difference. Deliver updates that users barely notice—but always appreciate.

Related Repositories

This SDK is one part of the Delta platform. It works alongside:

| Repository | Description | | ---------------------------------------------------------- | ------------------------------------------------------------------ | | delta-cli | CLI for registry management, bundle uploads, and release workflows | | delta-server | Backend server for patch delivery, releases, and the update API |

Table of Contents


Installation

yarn add @zepto-labs/react-native-delta

or

npm install @zepto-labs/react-native-delta

Prerequisites

  • Node.js >= 20
  • JDK 17 (for Android builds)
  • Xcode >= 14 (for iOS builds)
  • React Native >= 0.73

Integration

Android

1. Apply the delta Gradle Plugin

In your app-level build.gradle, apply the Delta Gradle plugin at the bottom:

apply from: file("../../node_modules/@zepto-labs/react-native-delta/android/delta.gradle");

2. Configure delta ext properties

Add the following ext block at the top of your app-level build.gradle to configure Delta:

ext {
    DELTA_JS_VERSION = "1"          // Unique per native app version; increment for each new store release or breaking native change
    ANDROID_DELTA_ID = "YOUR_ANDROID_APP_ID"
    DELTA_SERVER_URL = "YOUR_DELTA_SERVER_URL"
}

Then expose ANDROID_DELTA_ID and DELTA_SERVER_URL as BuildConfig fields inside your android { defaultConfig { ... } } block:

android {
    defaultConfig {
        buildConfigField "String", "ANDROID_DELTA_ID", "\"${ANDROID_DELTA_ID}\""
        buildConfigField "String", "DELTA_SERVER_URL", "\"${DELTA_SERVER_URL}\""
    }
}

Each platform requires its own unique App ID registered in the delta registry — the Android and iOS App IDs must be different values and must not be reused across platforms. Use delta-cli to create one for Android:

# Install delta-cli (if not already installed)
npm install -D @zepto-labs/delta-cli

# Create a registry entry for Android.
yarn delta-cli createRegistry --appId YOUR_ANDROID_DELTA_ID --platform android --appName "YourAppName"

Important: Choose a unique --appId for Android. This value must not be reused for iOS or any other app.

3. Configure MainApplication

Your MainApplication must implement IDeltaDelegate:

import com.delta.IDeltaDelegate
import com.delta.Delta

class MainApplication : Application(), ReactApplication, IDeltaDelegate {

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

            override fun getJSBundleFile(): String {
                return Delta.getJSBundlePath()
            }

            // ... other overrides
        }

    override fun onCreate() {
        super.onCreate()
        Delta.initialize(this)
    }

    override fun onEventOccurred(eventName: String, params: JSONObject) {
        // Handle Delta lifecycle events — see Events section below
    }
}

4. Configure BSPatch Maven Repo

delta ships a pre-built bspatch AAR inside the npm package. Add the following to your android/gradle.properties so Gradle can resolve it:

deltaMavenRepo=../node_modules/@zepto-labs/react-native-delta/maven-repo

Note: Adjust the relative path if your android/ folder is nested deeper (e.g. use ../../node_modules/... in a monorepo).

5. Manifest File

A manifest.json is auto-generated in src/main/assets/ during release builds:

{
  "appId": "yourAppId",
  "appVersion": "1.0.0",
  "jsVersion": 1,
  "bundleVersion": 0,
  "hash": "md5-hash-of-bundle"
}

iOS

1. Podfile

bspatch-ios is a C pod that doesn't define modules by default. Since react-native-delta is a Swift pod that depends on it, you need to enable modular headers for bspatch-ios so Swift can import it. Add the following inside your target block:

target 'YourApp' do
  pod 'bspatch-ios', :modular_headers => true

  # ... rest of your pods
end

2. AppDelegate.h

Import Delta and conform to IDeltaDelegate:

#import <RCTAppDelegate.h>
#import <UIKit/UIKit.h>
@import react_native_delta;

@interface AppDelegate : RCTAppDelegate<IDeltaDelegate>
@end

3. AppDelegate.m

Initialize Delta and configure the bundle URL:

@import react_native_code_delta;

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  self.moduleName = @"YourApp";
  self.initialProps = @{};

  [Delta initialize:self];

  BOOL success = [super application:application didFinishLaunchingWithOptions:launchOptions];
  [Delta checkUpdate];

  return success;
}

- (NSURL *)bundleURL
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
  return [Delta getJSBundlePath];
#endif
}

- (void)onEventOccurredWithEventName:(NSString *)eventName params:(NSDictionary<NSString *,id> *)params {
  // Handle delta lifecycle events — see Events section below
}

@end

4. Info.plist Keys

iOS requires a separate, unique App ID from Android. Use delta-cli to create one for iOS:

# Install delta-cli (if not already installed)
npm install -D @zepto-labs/delta-cli

# Create a registry entry for iOS.
yarn delta-cli createRegistry --appId YOUR_IOS_APP_ID --platform ios --appName "YourAppName"

Important: Choose a unique --appId for iOS. This value must be different from the Android App ID and must not be reused across platforms.

Add the following keys to your Info.plist, using the above App ID for DeltaAppId:

| Key | Type | Description | | ---------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | DeltaAppId | String | Your Delta iOS App ID you used (from createRegistry above) | | DeltaJsVersion | String | Current JS version number (integer starting from 1). Must be unique per native app version — two different app versions cannot share the same value. | | DeltaServerUrl | String | Base URL of the Delta backend server |

Note: DeltaBundleVersion is not required — it is inserted automatically by the build scripts.


Build Process

Delta hooks into the native build process to generate manifests and upload bundles automatically.

JS Version

jsVersion identifies the native binary a JavaScript bundle is compatible with. Two different app versions cannot share the same jsVersion. Each native app version (for example, 1.0.0 and 1.1.0) must use its own unique jsVersion value.

Increment jsVersion when you ship a new native app version to the store, or when you make breaking native changes that require a fresh JS bundle baseline. OTA patches and bundle uploads within the same native app version reuse the same jsVersion and only increment bundleVersion.

Configure jsVersion via DELTA_JS_VERSION on Android and DeltaJsVersion in Info.plist on iOS.

Android

The delta.gradle plugin automatically:

  1. Generates manifest.json — After the JS bundle is created (during createBundle<Variant>JsAndAssets), it generates a manifest with appId, appVersion, jsVersion, bundleVersion, and hash.
  2. Uploads the bundle — After assemble<Variant> or bundle<Variant>, it runs delta-cli createAndroidNativeBundle to upload the bundle to staging.

Important: Delta build tasks only run when the -PdeltaBuild=true flag is passed. Without this flag, the gradle plugin is a no-op.

Command Line:

./gradlew assembleRelease -PdeltaBuild=true

or with bundle:

./gradlew bundleRelease -PdeltaBuild=true

Android Studio:

Add the flag to your run configuration:

  1. Go to RunEdit Configurations
  2. Select your build configuration
  3. In the Gradle section, add -PdeltaBuild=true to the Command line options field

Alternatively, add it to your project's gradle.properties for always-on Delta builds:

deltaBuild=true

iOS

Two Ruby scripts run as part of the Xcode build phases:

Xcode Scheme Setup

  1. Open your app scheme in Xcode (ProductSchemeEdit Scheme…)
  2. Under BuildPre-actions, add a Run Script action:
cat "${SRCROOT}/../.env" > "${SRCROOT}/ProdConfig.xcconfig"
if [ "${CONFIGURATION}" = "Release" ]; then
  ruby "${SRCROOT}/../node_modules/@zepto-labs/react-native-delta/scripts/ios/update_info_plist.rb"
fi
  1. Under ArchivePost-actions, add a Run Script action:
ruby "${SRCROOT}/../node_modules/@zepto-labs/react-native-delta/scripts/ios/upload_delta_bundle.rb"

Note: update_info_plist.rb runs only for Release builds. The bundle upload runs automatically after you Archive the app, not on regular Run builds.


Delta Config

For CLI operations, create a delta.config.json at your project root:

{
  "s3": {
    "bucket": "your-delta-bucket",
    "region": "your-region"
  },
  "lambda": {
    "region": "your-region",
    "getLatestPatch": "<Your Function Name from backend>",
    "getReleaseList": "<Your Function Name from backend>",
    "createRelease": "<Your Function Name from backend>",
    "updateRelease": "<Your Function Name from backend>",
    "getRegistryList": "<Your Function Name from backend>",
    "createRegistry": "<Your Function Name from backend>",
    "invalidateCache": "<Your Function Name from backend>"
  }
}

API Reference

React Native

Import from the package:

import {
  checkUpdate,
  getManifestData,
  updateUserType,
  getUserType,
} from '@zepto-labs/react-native-delta'

checkUpdate()

Triggers a background check for available OTA updates.

checkUpdate()

| Parameter | Type | Description | | --------- | ---- | ------------- | | — | — | No parameters |

Returns: void


getManifestData()

Returns the cached manifest data as a JSON string containing the current bundle information.

const manifest = await getManifestData()

| Parameter | Type | Description | | --------- | ---- | ------------- | | — | — | No parameters |

Returns: Promise<string> — JSON string with manifest data

Response Shape:

{
  "jsVersion": 1,
  "bundleVersion": 0,
  "appVersion": "1.0.0",
  "hash": "md5-hash",
  "status": "ACTIVE"
}

updateUserType(value)

Marks the user as a Delta internal user. Internal users can receive staged/beta rollouts.

updateUserType(true)

| Parameter | Type | Default | Description | | --------- | --------- | ------- | -------------------------------- | | value | boolean | true | Whether to mark user as internal |

Returns: void


getUserType()

Returns whether the current user is marked as a Delta internal user.

const isInternal = await getUserType()

| Parameter | Type | Description | | --------- | ---- | ------------- | | — | — | No parameters |

Returns: Promise<boolean>


Android Native

These methods can be called directly from Kotlin/Java without going through React Native. All methods are accessible via Delta.methodName().


Delta.initialize(delegate)

Initializes the Delta SDK. Must be called before any other Delta method (typically in Application.onCreate). It reads ANDROID_DELTA_ID and DELTA_SERVER_URL from BuildConfig via reflection.

Delta.initialize(this)

| Parameter | Type | Description | | ---------- | ---------------- | -------------------------------------------- | | delegate | IDeltaDelegate | Delegate implementing the required callbacks |


Delta.getJSBundlePath()

Returns the path to the current JavaScript bundle. Use this in getJSBundleFile() to load Delta-managed bundles.

val bundlePath: String = Delta.getJSBundlePath()

Returns: String — file path to the JS bundle


Delta.checkUpdate()

Triggers a background check for available OTA updates. Downloads and applies the update if one is available.

Delta.checkUpdate()

Delta.getManifestData()

Returns the cached manifest data as a JSON string. Returns an empty JSON object {} if no valid manifest exists or if the app version has changed.

val manifest: String = Delta.getManifestData()

Returns: String — JSON string with manifest data


iOS Native

These methods can be called directly from Objective-C/Swift without going through React Native.


Delta.initialize(_:)

Initializes the Delta SDK. Must be called before any other Delta method (typically in didFinishLaunchingWithOptions). It reads the server URL from Info.plist's DeltaServerUrl key.

Objective-C:

[Delta initialize:self];

Swift:

Delta.initialize(self)

| Parameter | Type | Description | | ---------- | ---------------- | ------------------------------------------- | | delegate | IDeltaDelegate | Delegate implementing the required callback |


Delta.getJSBundlePath()

Returns the URL to the current JavaScript bundle. Use this in bundleURL to load Delta-managed bundles.

Objective-C:

NSURL *bundlePath = [Delta getJSBundlePath];

Swift:

let bundlePath: URL? = Delta.getJSBundlePath()

Returns: URL? — URL to the JS bundle file


Delta.checkUpdate()

Triggers a background check for available OTA updates.

Objective-C:

[Delta checkUpdate];

Swift:

Delta.checkUpdate()

Delta.getInternalUser()

Returns whether the current user is marked as a Delta internal user.

Swift:

let isInternal: Bool = Delta.getInternalUser()

Returns: Bool


Events

Delta fires lifecycle events through the onEventOccurred delegate callback. Use these events for analytics, debugging, or custom UI feedback.

Delegate Signature

Android (Kotlin):

override fun onEventOccurred(eventName: String, params: JSONObject) {
    // eventName: one of the event names below
    // params: JSON object with contextual data
}

iOS (Objective-C):

- (void)onEventOccurredWithEventName:(NSString *)eventName params:(NSDictionary<NSString *,id> *)params {
    // eventName: one of the event names below
    // params: dictionary with contextual data
}

Event List

| Event Name | Description | | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | | UPDATE_STATUS | Fired when the update check completes. Params include whether an update is available. | | GET_UPDATE_REQUEST_SUCCESS | The check-update API call returned successfully. | | UPDATE_API_FAILED | The check-update API call failed. Params include exception and reason. | | DOWNLOADING_START | Bundle or patch download has started. Params include status (download_patch, download_bundle, or url_not_found). | | DOWNLOAD_BUNDLE_REQUEST_SUCCESS | Bundle file downloaded successfully from the server. | | DOWNLOAD_BUNDLE_FROM_SERVER_FAILED | Bundle download failed. Params include reason. | | DOWNLOAD_PATCH_REQUEST_SUCCESS | Patch file downloaded successfully from the server. | | DOWNLOAD_PATCH_FROM_SERVER_FAILED | Patch download failed. Params include reason. | | UNZIPPED_BUNDLE_STATUS | Bundle unzip completed. Params include status (BUNDLE_UNZIPPED or BUNDLE_UNZIPPED_FAILED). | | UNZIPPED_PATCH_STATUS | Patch unzip completed. Params include status (PATCH_UNZIPPED or PATCH_UNZIPPED_FAILED). | | BUNDLE_MD5_STATUS | MD5 verification result for the downloaded bundle. Params include status (md5_matched or md5_not_matched). | | PATCH_MD5_STATUS | MD5 verification result for the downloaded patch. Params include status (md5_matched or md5_not_matched). | | PATCH_APPLICATION_STATUS | Patch application result. Params include status (PATCH_APPLIED or PATCH_FAILED). | | UPDATE_INSTALLED | A new bundle has been successfully installed and will be used on next app launch. | | UPDATE_CACHE_DATA | Manifest cache has been updated with new bundle information. | | ROLL_BACK_INITIATED | A rollback has been triggered (server instructed to revert to default bundle). | | ROLL_BACK_FROM_MANIFEST | Rollback detected from manifest state. Params include from (same_app_version or different_app_version). | | ALREADY_UPDATE_IN_PROGRESS_EXIST | An update is already being downloaded/applied; skipping this check. | | MANIFEST_NOT_FOUND | No valid manifest found during check update. | | SHARED_DEFAULT_BUNDLE | Falling back to the default bundled JS. Params include reason. |


Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

Third-Party Licenses

This project depends on the following third-party packages. Their respective licenses apply to those packages.

| Package | Version | License | License Changed? | | ------------------------------------------------------------------------------------------------ | ------- | -------------------------------------------------------- | ---------------- | | @commitlint/config-conventional | 17.0.2 | MIT | No | | @react-native/eslint-config | 0.73.1 | MIT | No | | @types/jest | 29.5.5 | MIT | No | | @types/react | 18.2.44 | MIT | No | | commitlint | 17.0.2 | MIT | No | | del-cli | 5.1.0 | MIT | No | | eslint | 8.51.0 | MIT | No | | jest | 29.7.0 | MIT | No | | lint-staged | 15.2.2 | MIT | No | | prettier | 3.2.5 | MIT | No | | react | 18.2.0 | MIT | No | | react-native | 0.73.6 | MIT | No | | react-native-builder-bob | 0.20.0 | MIT | No | | turbo | 1.10.7 | MPL-2.0 | No | | typescript | 5.2.2 | Apache-2.0 | No |

Credits

Special Thanks