// Frequently asked

FAQs

Answers to common questions about DeployPulse and CodePush.

Last updated: September 28, 2026

DeployPulse supports React Native apps on both iOS and Android. We also support Expo apps - both Expo CNG (bare workflow using the CodePush SDK) and the Expo Updates v1 protocol (managed and bare workflow using expo-updates). Flutter and other frameworks are not currently supported.

CodePush was developed by Microsoft. In 2024, Microsoft announced that CodePush would be deprecated and open-sourced the technology. DeployPulse launched as a managed hosted replacement, using the same CodePush protocol to push updates to your React Native apps. DeployPulse is not affiliated with Microsoft in any way.

You can push via OTA:

  • JavaScript bundle changes
  • Static assets - images, fonts, audio, video
  • Bug fixes, UI changes, and JavaScript-level changes that stay within your app's intended and advertised purpose

You cannot push via OTA:

  • Native code or native module changes
  • New device permissions
  • Changes that fundamentally alter the app's core purpose
  • Anything requiring a binary rebuild or new SDK version

See the Apple App Store Review Guidelines and Google Play Developer Policy for the authoritative platform rules.

The permission comes from the Apple Developer Program License Agreement, section 3.3.1(B) (Executable Code): interpreted code may be downloaded to an app so long as it:

  • Does not change the app's primary purpose by providing features or functionality inconsistent with its intended and advertised purpose
  • Does not bypass signing, sandbox, or other security features of the OS
  • Does not create a store or storefront for other apps

App Store Review Guideline 2.5.2 is the matching restriction: an app may not download, install or execute code that introduces or changes features or functionality. Read together, the line Apple draws is your app's advertised purpose, not the size of the change.

You cannot push native code, new entitlements, or changes that would require App Store re-review. DeployPulse signs releases with RS256 so your app can verify an update came from you; that is our integrity feature, not an Apple requirement.

Google Play's Device and Network Abuse policy bars an app from updating itself outside Google Play, then carves out an exception: the restriction does not apply to “code that runs in a virtual machine or an interpreter where either provides indirect access to Android APIs”. A React Native JavaScript bundle runs in exactly that kind of interpreter. The policy does not permit:

  • Replacing or updating the APK/AAB outside of Google Play
  • Downloading native libraries (.so files) not included in the original package
  • Delivering functionality that itself violates Google Play policies

React Native JavaScript bundle updates fall within the permitted interpreted code category and are safe to push via DeployPulse.

Yes. DeployPulse supports Expo in two ways:

  • Expo CNG (bare workflow) - apps using the @deploypulseio/react-native-code-push SDK work exactly like standard React Native apps. Its Expo config plugin sets up the native files at prebuild time, and DeployPulse is already its default server.
  • Expo Updates v1 protocol - managed and bare workflow apps using the expo-updates package are supported natively. Point your updates.url at DeployPulse and push releases with dpctl release-expo - no CodePush SDK required.

See our Expo setup guide for full instructions.

Code signing is optional but strongly recommended, particularly on iOS where Apple's guidelines encourage it for interpreted code updates.

DeployPulse supports RS256 JWT code signing:

  • Generate an RSA key pair with dpctl app set-public-key
  • The CLI signs each release bundle at upload time using your private key
  • DeployPulse verifies the signature server-side before accepting the release
  • The CodePush SDK verifies the signature on-device before applying the update

See our code signing guide for setup instructions.

DeployPulse has two safeguards:

  • Auto-rollback - monitors the error rate on every new release. If it exceeds a configurable threshold (e.g. 5%) within a configurable time window, DeployPulse automatically rolls back to the previous stable release and notifies you by email. Configured per deployment in the dashboard.
  • Manual rollback - roll back any release at any time from the Deployments page in the dashboard or via dpctl rollback <app> <deployment>.

Gradual rollouts (e.g. 10% of users first) are also supported and are a good way to catch issues before they reach your full user base.

Install the CodePush SDK in your React Native app, then use the DeployPulse CLI to push updates. See our quickstart guide for full setup instructions.

DeployPulse publishes a GitHub Action, deploypulseio/setup-dpctl, that installs the dpctl CLI into your workflow. Because dpctl is an ordinary command-line tool, it also works in any CI system that can run shell commands, including Bitrise, CircleCI, GitLab CI, and Jenkins. Store an access key as a CI secret, authenticate with it, and run the release command as a build step. See the CI/CD setup guides for each provider.

You can release an update to a percentage of your devices rather than all of them at once. Set the rollout percentage on the release, watch the error rate and the version adoption curve in the dashboard, then raise the percentage when the release looks healthy. Devices that already received the update keep it when you change the percentage.

Both deliver over-the-air updates to React Native apps, but they assume different toolchains. DeployPulse is a drop-in replacement for Microsoft's CodePush and works with the react-native-code-push SDK, so an app already using CodePush migrates by changing one server URL. DeployPulse also supports the Expo Updates v1 protocol. EAS Update is built around the expo-updates package and the Expo managed workflow, so adopting it means adopting the Expo toolchain.

Yes. Over-the-air updates replace the JavaScript bundle and its assets, so delivery does not depend on whether your app runs the legacy architecture or the New Architecture with the Fabric renderer and TurboModules. No additional configuration is required. See the New Architecture guide for details.

No. Every plan, Free included, has unlimited apps, deployments and releases. Plans are sized by monthly active users and bandwidth instead.

Plans are sized by monthly active users and bandwidth. Free covers 10,000 monthly active users and 100 GB of bandwidth a month. Starter is $20/month for 50,000 users and 1 TB, Growth $50 for 150,000 and 2.5 TB, Business $100 for 300,000 and 5 TB, Scale $250 for 750,000 and 10 TB, and Pro $500 for 1,500,000 and 25 TB. Yearly billing costs ten times the monthly price, so two months are free. Paid plans are never cut off: bandwidth past your allowance is billed at $0.01 per GB, and going over your plan's users is not charged. Free is a hard cap. An active user is a device that checks for or downloads an update in a calendar month, counted once however often it checks. See the pricing section for everything each plan includes.

How long an uploaded build is kept depends on your plan: 3 months on Free, 1 year on Starter and Growth, 3 years on Business, Scale, and Pro, and unlimited on Enterprise, where builds never expire. You can delete a deployment yourself at any time. See the pricing section for the current limits on each plan.

Cancel anytime in your account under Settings → Billing.

Email support@deploypulse.io with bug reports or feature requests. We appreciate the feedback.