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

@ducky0203/react-native-code-push

v1.0.0

Published

React Native plugin for the CodePush service (targets React Native 0.85.3)

Readme

@ducky0203/react-native-code-push

A React Native plugin that provides client-side integration with a CodePush service, allowing you to easily add a dynamic, over-the-air update experience to your React Native app.

This package is a maintained fork of the original microsoft/react-native-code-push brought up to date with React Native 0.85.3 (New Architecture / Bridgeless mode supported).

Current version: v1.0.0 — targeting React Native 0.85.3. Maintained by DuckyPham.


Table of contents


How does it work?

A React Native app is composed of JavaScript files and any accompanying images, which are bundled together by the Metro bundler and distributed as part of a platform-specific binary (an .ipa or .apk file). Once the app is released, updating either the JavaScript code (bug fixes, new features) or image assets requires you to recompile and redistribute the entire binary, which of course includes any review time associated with the store(s) you are publishing to.

The CodePush plugin helps get product improvements in front of your end users instantly by keeping your JavaScript and images synchronised with updates you release to a CodePush-compatible server. This way, your app gets the benefits of an offline mobile experience as well as the “web-like” agility of side-loading updates as soon as they are available.

To ensure that your end users always have a functioning version of your app, the CodePush plugin maintains a copy of the previous update, so that if you accidentally push an update which includes a crash, it can automatically roll back.

Note: Any product changes which touch native code (e.g. modifying your AppDelegate.m/MainActivity.kt file, adding a new plugin) cannot be distributed via CodePush, and must be updated through the appropriate store(s).

Supported React Native versions

  • iOS 15.5+ (required by SSZipArchive 2.5+, which bundles zlib 1.2.12 to address CVE-2018-25032)
  • Android API 24+ (TLS 1.2 compatible devices)

| React Native version | Supporting plugin version | |----------------------|-------------------------------------------------| | 0.85.3 | v1.0.0 (New Architecture / Bridgeless) |

This 1.0.x line tracks React Native 0.85.3 specifically. Older RN versions (≤ 0.84) are not supported — use the upstream react-native-code-push or an earlier fork for those.

Heads-up — host app Podfile: React Native 0.85.3 templates default the iOS deployment target to 15.1, but this plugin requires 15.5. You must raise the floor in your host app's ios/Podfile:

platform :ios, '15.5'

Otherwise CocoaPods will fail with:

[!] CocoaPods could not find compatible versions for pod "SSZipArchive":
    Specs satisfying the dependency were found, but they required a
    higher minimum deployment target.

Supported components

When using the React Native asset system (require("./foo.png")), the following list represents the set of core components (and props) whose referenced images and videos can be updated via CodePush:

| Component | Prop(s) | |-------------------------------------------------|------------------------------------------| | Image | source | | MapView.Marker (Requires react-native-maps >=O.3.2) | image | | ProgressViewIOS | progressImage, trackImage | | TabBarIOS.Item | icon, selectedIcon | | ToolbarAndroid (React Native 0.21.0+) | actions[].icon, logo, overflowIcon | | Video | source |

The following list represents the set of components (and props) that don't currently support their assets being updated via CodePush, due to their dependency on static images and videos (i.e. using the { uri: "foo" } syntax):

| Component | Prop(s) | |-------------|----------------------------------------------------------------------| | SliderIOS | maximumTrackImage, minimumTrackImage, thumbImage, trackImage | | Video | source |

Note: CodePush only works with Video components when using require in the source prop, e.g.:

<Video source={require("./foo.mp4")} />

Getting started

Install the plugin in your React Native project:

yarn add @ducky0203/react-native-code-push
# or
npm install --save @ducky0203/react-native-code-push

Then continue with the native module setup:

Backend: This client talks to any CodePush-compatible server. The default server URL is https://codepush.appcenter.ms/, but the original App Center / Microsoft CodePush service is sunset. You should run your own backend (such as code-push-server) or use a hosted alternative, and configure the URL via the CodePushServerURL key in Info.plist (iOS) or the CodePushServerUrl string resource in strings.xml (Android).

Plugin usage

With the CodePush plugin installed and linked, and your app asking CodePush where to get the right JS bundle from, the only thing left is to add the necessary code to your app to control the following policies:

  1. When (and how often) to check for an update? (for example, on app start, in response to clicking a button in a settings page, periodically at some fixed interval).
  2. When an update is available, how to present it to the end user?

The simplest way to do this is to "CodePush-ify" your app's root component. To do so, you can choose one of the following two options:

  • Option 1: Wrap your root component with the codePush higher-order component:

    • For a class component

      import codePush from "@ducky0203/react-native-code-push";
      
      class MyApp extends Component {
      }
      
      MyApp = codePush(MyApp);
    • For a functional component

      import codePush from "@ducky0203/react-native-code-push";
      
      let MyApp: () => React$Node = () => {
      }
      
      MyApp = codePush(MyApp);
  • Option 2: Use the ES7 decorator syntax:

    NOTE: Decorators are not yet supported in Babel 6.x pending proposal update. You may need to enable it by installing and using babel-preset-react-native-stage-0.

    • For a class component

      import codePush from "@ducky0203/react-native-code-push";
      
      @codePush
      class MyApp extends Component {
      }
    • For a functional component

      import codePush from "@ducky0203/react-native-code-push";
      
      const MyApp: () => React$Node = () => {
      }
      
      export default codePush(MyApp);

By default, CodePush will check for updates on every app start. If an update is available, it will be silently downloaded, and installed the next time the app is restarted (either explicitly by the end user or by the OS), which ensures the least invasive experience for your end users. If an available update is mandatory, then it will be installed immediately, ensuring that the end user gets it as soon as possible.

If you would like your app to discover updates more quickly, you can also choose to sync up with the CodePush server every time the app resumes from the background.

  • For a class component

    let codePushOptions = { checkFrequency: codePush.CheckFrequency.ON_APP_RESUME };
    
    class MyApp extends Component {
    }
    
    MyApp = codePush(codePushOptions)(MyApp);
  • For a functional component

    let codePushOptions = { checkFrequency: codePush.CheckFrequency.ON_APP_RESUME };
    
    let MyApp: () => React$Node = () => {
    }
    
    MyApp = codePush(codePushOptions)(MyApp);

Alternatively, if you want fine-grained control over when the check happens (like a button press or timer interval), you can call CodePush.sync() at any time with your desired SyncOptions, and optionally turn off CodePush's automatic checking by specifying a manual checkFrequency:

let codePushOptions = { checkFrequency: codePush.CheckFrequency.MANUAL };

class MyApp extends Component {
    onButtonPress() {
        codePush.sync({
            updateDialog: true,
            installMode: codePush.InstallMode.IMMEDIATE
        });
    }

    render() {
        return (
            <View>
                <TouchableOpacity onPress={this.onButtonPress}>
                    <Text>Check for updates</Text>
                </TouchableOpacity>
            </View>
        )
    }
}

MyApp = codePush(codePushOptions)(MyApp);

If you would like to display an update confirmation dialog (an "active install"), configure when an available update is installed (like force an immediate restart) or customise the update experience in any other way, refer to the codePush() API reference.

NOTE: If you are using Redux and Redux Saga, you can alternatively use the react-native-code-push-saga module, which allows you to customise when sync is called in a perhaps simpler/more idiomatic way.

Releasing updates

Once your app is configured and distributed to your users and you have made some JS or asset changes, it's time to release them. The recommended way to do that is via the code-push CLI, which will bundle your JavaScript files, asset files, and release the update to the CodePush server.

npm install -g code-push-cli

NOTE: Before you can start releasing updates, please log into your CodePush server using the code-push login command (use --serverUrl to point at your self-hosted server).

In its most basic form, this command only requires application name and platform (ios/android):

code-push release-react <appName> <platform ios/android>
code-push release-react MyApp android -d Production

The release-react command enables such a simple workflow because it provides many sensible defaults (like generating a release bundle, assuming your app's entry file on iOS is either index.ios.js or index.js). However, all of these defaults can be customised to allow incremental flexibility as necessary, which makes it a good fit for most scenarios.

# Release a mandatory update with a changelog
code-push release-react MyApp ios -m --description "Modified the header color"

# Release an update for an app that uses a non-standard entry file name, and also capture
# the sourcemap file generated by react-native bundle
code-push release-react MyApp ios --entry-file MyApp.js --sourcemapOutput ../maps/MyApp.map

# Release a dev Android build to just 1/4 of your end users
code-push release-react MyApp android --rollout 25 --development true

# Release an update that targets users running any 1.1.* binary
code-push release-react MyApp android --targetBinaryVersion "~1.1.0"

The CodePush client supports differential updates, so even though you are releasing your JS bundle and assets on every update, your end users will only download the files they need.

For more details about how the release-react command works, as well as the various parameters it exposes, refer to the CLI docs. Additionally, if you would prefer to handle running the react-native bundle command yourself, refer to the release command for more details.

NOTE: CodePush updates should be tested in modes other than Debug mode. In Debug mode, the React Native app always downloads the JS bundle generated by the packager, so the JS bundle downloaded by CodePush does not apply.

Multi-Deployment Testing

In our getting started docs we illustrated how to configure the CodePush plugin using a specific deployment key. However, in order to effectively test your releases, it is critical that you leverage the Staging and Production deployments that are auto-generated when you first create your CodePush app (or any custom deployments you may have created). This way, you never release an update to your end users that you haven't been able to validate yourself.

NOTE: The client-side rollback feature can help unblock users after installing a release that resulted in a crash, and server-side rollbacks (i.e. code-push rollback) allow you to prevent additional users from installing a bad release once it's been identified.

Workflow:

  1. Release a CodePush update to your Staging deployment using code-push release-react (or code-push release if you need more control).
  2. Run your staging/beta build of your app, sync the update from the server, and verify it works as expected.
  3. Promote the tested release from Staging to Production using the code-push promote command.
  4. Run your production/release build of your app, sync the update from the server, and verify it works as expected.

For platform-specific demo setups see:

Dynamic Deployment Assignment

The above section illustrated how you can leverage multiple CodePush deployments in order to effectively test your updates before broadly releasing them. However, since that workflow statically embeds the deployment assignment into the actual binary, a staging or production build will only ever sync updates from that deployment. If you want to be able to perform A/B tests, or provide early access of your app to certain users, it can prove very useful to be able to dynamically place specific users (or audiences) into specific deployments at runtime.

To achieve this kind of workflow, all you need to do is specify the deployment key you want the current user to synchronise with when calling the codePush method. When specified, this key will override the "default" one that was provided in your app's Info.plist (iOS) or MainActivity (Android) files. This allows you to produce a build for staging or production that is also capable of being dynamically "redirected" as needed.

// Imagine that "userProfile" is a prop that this component received
// which includes the deployment key that the current user should use.
codePush.sync({ deploymentKey: userProfile.CODEPUSH_KEY });
# Create your new deployment to hold releases of a specific app variant
code-push deployment add MyApp test-variant-one

# Target any new releases at that custom deployment
code-push release-react MyApp android -d test-variant-one

API Reference

Store Guideline Compliance

Android Google Play and iOS App Store have corresponding guidelines that have rules you should be aware of before integrating the CodePush solution within your application.

Google play

The third paragraph of the Device and Network Abuse topic describes that updating source code by any method other than Google Play's update mechanism is restricted, but this restriction does not apply to updating JavaScript bundles.

This restriction does not apply to code that runs in a virtual machine and has limited access to Android APIs (such as JavaScript in a webview or browser).

That fully allows CodePush as it updates just JS bundles and can't update the native code part.

App Store

Paragraph 3.3.2, since back in 2015's Apple Developer Program License Agreement fully allowed performing over-the-air updates of JavaScript and assets — and in its latest version (20170605) downloadable here this ruling is even broader:

Interpreted code may be downloaded to an Application but only so long as such code: (a) does not change the primary purpose of the Application by providing features or functionality that are inconsistent with the intended and advertised purpose of the Application as submitted to the App Store, (b) does not create a store or storefront for other code or applications, and (c) does not bypass signing, sandbox, or other security features of the OS.

CodePush allows you to follow these rules in full compliance, so long as the update you push does not significantly deviate your product from its original App Store-approved intent.

To further remain in compliance with Apple's guidelines we suggest that App Store-distributed apps don't enable the updateDialog option when calling sync, since in the App Store Review Guidelines it is written that:

Apps must not force users to rate the app, review the app, download other apps, or other similar actions in order to access functionality, content, or use of the app.

Debugging / Troubleshooting

The sync method includes a lot of diagnostic logging out-of-the-box, so if you're encountering an issue when using it, the best thing to try first is examining the output logs of your app.

The simplest way to view these logs is to add the flag --debug for each command. This will output a log stream that is filtered to just CodePush messages.

Additionally, you can also use any of the platform-specific tools to view the CodePush logs: the Chrome DevTools Console, the Xcode Console (iOS), the OS X Console (iOS), and/or adb logcat (Android), and look for messages which are prefixed with [CodePush].

Note that by default, React Native logs are disabled on iOS in release builds, so if you want to view them in a release build, you need to make the following changes to your AppDelegate.m file:

  1. Add an #import <React/RCTLog.h> statement.

  2. Add the following statement to the top of your application:didFinishLaunchingWithOptions method:

    RCTSetLogThreshold(RCTLogLevelInfo);

Now you'll be able to see CodePush logs in either debug or release mode, on both iOS and Android. If examining the logs doesn't provide an indication of the issue, please refer to the following common issues for additional resolution ideas:

| Issue / Symptom | Possible solution | |-----------------|-------------------| | Compilation error | Double-check that your version of React Native is compatible with the CodePush version you are using. | | Network timeout / hang when calling sync or checkForUpdate in the iOS Simulator | Try resetting the simulator by selecting the Simulator -> Reset Content and Settings.. menu item, and then re-running your app. | | Server responds with a 404 when calling sync or checkForUpdate | Double-check that the deployment key you added to your Info.plist (iOS), build.gradle (Android) or that you're passing to sync / checkForUpdate, is in fact correct. | | Update not being discovered | Double-check that the version of your running app (like 1.0.0) matches the version you specified when releasing the update to CodePush. Make sure that you are releasing to the same deployment that your app is configured to sync with. | | Update not being displayed after restart | If you're not calling sync on app start, you need to explicitly call notifyApplicationReady on app start, otherwise the plugin will think your update failed and roll it back. | | I've released an update for iOS but my Android app also shows an update and it breaks it | Be sure you have different deployment keys for each platform in order to receive updates correctly. | | I've released a new update but changes are not reflected | Be sure that you are running the app in modes other than Debug. | | No JS bundle is being found when running your app against the iOS simulator | By default, React Native doesn't generate your JS bundle when running against the simulator. Build for a real device or for Release to generate it. |

TypeScript Consumption

This module ships its *.d.ts file as part of its NPM package, which allows you to simply import it and receive intellisense in supporting editors (like Visual Studio Code) as well as compile-time type checking if you're using TypeScript. For the most part, this behaviour should just work out of the box. However, if you've specified es6 as the value for either the target or module compiler option in your tsconfig.json file, then just make sure that you also set the moduleResolution option to node. This ensures that the TypeScript compiler will look within the node_modules for the type definitions of imported modules.


Development

This section is for contributors working on the plugin itself (not for consuming it in an app).

Install dependencies:

yarn install

Linting

The shipped JavaScript source is linted with ESLint (see eslint.config.mjs); the TypeScript test suite is linted separately with TSLint.

yarn lint      # ESLint over the published JS (CodePush.js, scripts/, …)
yarn tslint    # TSLint over the TypeScript tests

Tests

yarn test          # build + run the Mocha suite for both platforms
yarn test:android  # Android only
yarn test:ios      # iOS only

Releasing to npm

yarn lint runs automatically before publishing (via the prepublishOnly hook), so a lint failure blocks the release.

# 1. Bump the version (updates package.json and creates a git tag)
npm version patch   # or: minor / major

# 2. Publish the scoped package (public access is required for @scope packages)
npm run release     # runs: npm publish --access public

Note: publishing requires npm auth with rights to the @ducky0203 scope (npm login). Make sure the version in package.json is correct before releasing — this line of the README should always match it.


License

MIT — see LICENSE.md. This is a community fork; please refer to the upstream microsoft/react-native-code-push project for the original copyright notice.