Migrating from CodePush
Migrating from CodePush
This guide covers moving from any CodePush-compatible client and server (community forks, hosted successors, or a self-hosted CodePush-compatible API) to self-hosted Codemagic Patch. The wire protocol and package names differ by fork; the apps / deployments / sync() mental model usually transfers. For trade-offs, see How Patch compares.
The Patch SDK ships in the native binary. Plan a store release (or internal distribution build) that embeds Patch before OTA updates can run through your Patch server. You cannot swap the update client purely over the air.
Concept mapping
| CodePush fork (typical) | Codemagic Patch |
|---|---|
| Hosted or self-hosted CodePush-compatible server | Self-hosted Patch stack on your domains |
| App access key / service token | GitHub OAuth (dashboard) + cm_pat_… API tokens (CLI/CI) |
| Deployment key in native config | CodemagicPatchDeploymentKey (same idea) |
Staging / Production deployments | Same channel names by default |
codePush.sync() / HOC wrapper | sync() from @codemagic/react-native-patch |
release-react (CodePush CLI) | cmpatch release-react |
--mandatory, rollout, target binary version | Same flags on cmpatch release-react / release patch |
notifyAppReady() | Called automatically by sync(); manual if not using sync() |
Install modes (ON_NEXT_RESTART, IMMEDIATE, etc.) and mandatoryInstallMode map closely, see Applying updates.
1. Stand up Patch
Follow Install (or the Local quickstart to try the stack locally first). You need:
- API URL →
CodemagicPatchApiUrl - Download base URL →
CodemagicPatchDownloadBaseUrl
Create apps and deployments to mirror your CodePush layout (one app per platform is the usual pattern):
cmpatch app create --name MyApp-iOS
cmpatch app create --name MyApp-Android
cmpatch deployment list --app MyApp-iOS --format table
Copy each deployment key into native config when you integrate the SDK.
2. Replace the client SDK
Remove your CodePush client package and native wiring (package name varies by fork):
yarn remove @code-push-next/react-native-code-push # or your fork's package
yarn add @codemagic/react-native-patch
cd ios && pod install && cd ..
Wire Patch per Native setup: bare RN (Info.plist / strings.xml + bundle selection) or Expo (config plugin + prebuild).
Replace CodePush calls in JS (example uses @code-push-next; adjust the import for your fork):
// Before (CodePush)
import codePush from "@code-push-next/react-native-code-push";
codePush.sync({ installMode: codePush.InstallMode.ON_NEXT_RESTART });
// After (Patch)
import { sync } from "@codemagic/react-native-patch";
void sync({ installMode: "ON_NEXT_RESTART" });
Remove the codePush(...)(App) HOC if you used it, call sync() from a useEffect or app entry instead. Class-component HOC hooks (codePushDownloadDidProgress, etc.) have no direct equivalent; use sync(options, onProgress) or manual control.
3. Point CI at Patch
Install and authenticate the Patch CLI:
npm install -g @codemagic/patch-cli
cmpatch config set server-url https://updates.example.com
cmpatch token create --name ci # store cm_pat_… as a CI secret
Swap your fork's release / release-react CI steps for:
cmpatch release-react \
--platform ios \
--deployment Production \
--release-notes "…" \
--yes
See CI integration.
4. Cut over
- Publish a native build with the Patch SDK and deployment keys embedded (Staging first).
- Publish an OTA release to that deployment with
cmpatch release-reacttargeting the same binary version users install. - Validate on Staging, then repeat for Production.
- Decommission the old CodePush server or SaaS once no active binaries still call it.
Checklist
- Patch server running with HTTPS and GitHub OAuth configured
- Apps and deployments created; keys copied into native config
- CodePush package and native wiring removed; Patch SDK integrated
-
sync()(or manual API) replaces CodePush sync/HOC - CI secrets and release commands updated to
cmpatch - New store/internal binary shipped; OTA tested on Staging before Production