Skip to main content

Ship Your First Patch Bundle

This guide will walk you through creating and deploying your first patch update (differential update). Patch updates only send the differences between two bundles, resulting in significantly smaller download sizes and faster updates for your users.

Estimated Time

⏱️ 15-20 minutes (assumes you already have DOTA set up)


🎯 What You'll Accomplish​

By the end of this guide, you will:

  • βœ… Understand what patch updates are and when to use them
  • βœ… Generate a patch bundle from two versions
  • βœ… Deploy the patch update via CLI
  • βœ… Monitor the patch deployment
  • βœ… Understand the benefits and size savings

What is a Patch Update?​

A patch update (also called a differential update) contains only the differences between two bundle versions, rather than the entire bundle.

Size Comparison Example​

Full Bundle Update:    23.1 MB β†’ 8.14 MB
Patch Bundle Update: 23.1 MB β†’ 2.3 MB (90% smallerπŸ”₯)

When to Use Patch Updates​

βœ… Use Patch Updates When:

  • Making small code changes or bug fixes
  • Updating a few components
  • Minor feature additions
  • Optimizing download times and bandwidth

❌ Use Full Updates When:

  • Major refactoring or restructuring
  • Significant feature releases
  • First release to a deployment
  • No previous bundle available

Prerequisites​

Before starting, ensure you have:

  • βœ… DOTA Server running
  • βœ… CLI installed and authenticated
  • βœ… Your React Native app with DOTA SDK integrated (@d11/dota >= v1.1.0)
  • βœ… At least one previous release deployed (the "old" bundle)
  • βœ… Made code changes for the new version
Already Set Up?

If you haven't completed the initial setup, follow the Full Setup Guide first.


Step 1: Save Your Current Bundle (Old Version)​

Before making changes, you need to save your current bundle as the "old" version.

1.1 Prepare the current (base) bundle

If you completed bundle setup in the Full Setup Guide, each Release build copies the currently shipped bundle to the .dota/<platform> folder. This becomes the base for generating your patch.

1.2 Create a Backup Directory

mkdir -p .dota-versions

1.3 Copy Current Bundle as "Old Version"

cp -r .dota/ios .dota-versions/v1.0.0-ios
Version Naming

Use semantic versioning in your backup folder names (e.g., v1.0.0, v1.1.0) to keep track easily.


Step 2: Make Your Code Changes​

Now make your updates to the React Native code.

2.1 Edit Your Code

Make your desired changes, for example:

// Before
<Text>Welcome to My App</Text>

// After
<Text>Welcome to My App - Now with awesome updates!</Text>

2.2 Test Your Changes

Run your app in Release mode to verify:

yarn ios --mode=Release

Step 3: Generate New Bundle (After Changes)​

New bundle will automatically be updated in the respective platform directory .dota/ios/ (iOS) and .dota/android/ (Android).

Smaller Patches

Enable Base Bytecode Optimization before generating the new bundle to reduce patch size further.


Step 4: Create the Patch Bundle​

Now create the patch that contains only the differences.

4.1 Use CLI to Create Patch​

yarn code-push-standalone create-patch \
./.dota-versions/v1.0.0-ios \
./.dota/ios \
./.dota/patches/ios

Command Breakdown

  • First argument: Path to old bundle (before changes)
  • Second argument: Path to new bundle (after changes)
  • Third argument: Output directory for patch files

4.2 Verify Patch Was Created​

# Check patch directory
ls -lh .dota/patches/ios
# or
ls -lh .dota/patches/android

You should see the patch file (bundle.patch) created.

4.3 Include Assets​

Make sure to copy all assets generated inside ./.dota/<platform> to new .dota/patches/<platform> directory. This will ensure correct asset loading.

Patch Created

βœ… Your differential patch bundle has been generated!


Step 5: Deploy the Patch Update​

Deploy your patch update using the CLI.

CLI Only

Patch updates can only be deployed via CLI, not through the Web Panel.

5.1 Deploy to Staging First​

yarn code-push-standalone release MyApp-iOS ./.dota/patches/ios "1.0.0" \
--deploymentName Staging \
--description "Bug fixes (patch update)" \
--isPatch true \
--compression brotli

Important Flags​

FlagValueWhy
--isPatchtrueRequired - Tells DOTA this is a patch bundle
--compressionbrotliRecommended - Best compression for patches
--deploymentNameStagingTest in staging first
Critical

Always use --isPatch true when deploying a patch bundle. Without this flag, the deployment will fail or behave incorrectly.


Step 6: Test the Patch Update​

6.1 Restart Your App

Close and reopen the test app that uses the Staging deployment key. Rebuild the app with your original (pre‑change) code so it ships the old bundle; the patch will then apply on launch.

6.2 Monitor Download

The patch update is significantly smaller, so you should see:

  • ⚑ Faster download
  • πŸ“‰ Less bandwidth usage
  • πŸš€ Quicker installation

6.3 Verify Changes Applied

After the app restarts, confirm your code changes are visible.

Use codePush.sync to observe patch-related status events (see API Reference β†’ sync) and impact on download size:

codePush.sync(
{},
(status) => {
switch (status) {
case codePush.SyncStatus.PATCH_APPLIED_SUCCESS:
// Patch applied successfully
break;
case codePush.SyncStatus.UPDATE_INSTALLED:
// Update installed; activation depends on installMode
break;
}
},
({ receivedBytes, totalBytes }) => {
console.log(`Downloaded ${receivedBytes} of ${totalBytes} bytes`);
}
);

For the full list of statuses, see SyncStatus.

6.4 Check Dashboard

In the Web Panel, you should see:

  • 🏷️ "patch" tag on the release
  • πŸ“Š Smaller bundle size reported
  • πŸ“ˆ Faster adoption metrics
Patch Indicator

Releases marked with "patch" in the dashboard indicate a differential update was deployed.


Step 7: Deploy to Production​

After testing successfully in Staging, promote to Production.

7.1 Promote via CLI

yarn code-push-standalone promote MyApp-iOS Staging Production

Or deploy directly to Production:

yarn code-push-standalone release MyApp-iOS ./.dota/patches/ios "1.0.0" \
--deploymentName Production \
--description "Bug fixes (patch update)" \
--isPatch true \
--compression brotli \
--mandatory
Gradual Rollout

For production patches, consider gradual rollout:

yarn code-push-standalone release MyApp-iOS ./.dota/patches/ios "1.0.0" \
--deploymentName Production \
--isPatch true \
--compression brotli \
--rollout 25 # Start with 25% of users

Understanding Patch Benefits​

File Size Comparison​

Bundle TypeOriginalWith DeflateWith Brotli
Uncompressed Full Bundle24.5 MB11.04 MB8.14 MB
Uncompressed Patch Bundle~24.5 MB3.82 MB2.9 MB (90% πŸ”₯ smaller)

User Experience Impact​

Full Bundle:

  • πŸ“₯ 8-11 MB download
  • ⏱️ 30-60 seconds on 4G
  • πŸ”‹ More battery usage

Patch Bundle:

  • πŸ“₯ 2-3 MB download
  • ⏱️ 5-10 seconds on 4G
  • πŸ”‹ Minimal battery impact

Best Practices for Patch Updates​

1. Keep Old Bundles​

Always save your previous bundles before generating new ones:

# Create versioned backups
.dota-versions/
β”œβ”€β”€ v1.0.0-ios/
β”œβ”€β”€ v1.0.1-ios/
β”œβ”€β”€ v1.1.0-ios/
β”œβ”€β”€ v1.0.0-android/
└── v1.0.1-android/

2. Use Brotli Compression​

--compression brotli

Brotli provides the best compression for patches, making them even smaller.

3. Test Patches in Staging​

Always test patch updates in Staging before Production:

# Test first
... --deploymentName Staging --isPatch true

# Then promote
yarn code-push-standalone promote MyApp Staging Production

4. Document Your Patches​

Use descriptive release notes:

--description "v1.0.1: Fixed login bug, improved image caching (patch)"

5. Fallback Strategy​

DOTA automatically falls back to full bundle if patch application fails. Always have a rollback plan:

# If issues arise, deploy a full bundle
yarn code-push-standalone release MyApp ./.dota/ios "1.0.0" \
--deploymentName Production \
--isPatch false \
--mandatory

Workflow for Regular Patch Updates​

Here's a repeatable workflow for your team:

Standard Patch Deployment Process​

# 1. Save current bundle (before changes)
cp -r .dota/ios .dota-versions/v1.0.0-ios

# 2. Make your code changes
# (edit your React Native code)

# 3. Generate new bundle (after changes). Created during build process

# 4. Create patch
yarn code-push-standalone create-patch \
./.dota-versions/v1.0.0-ios \
./.dota/ios \
./.dota/patches/ios

# 5. Include Assets

# 6. Deploy patch to staging
yarn code-push-standalone release MyApp-iOS ./.dota/patches/ios "1.0.0" \
-d Staging \
--isPatch true \
--compression brotli \
-des "v1.0.1: Bug fixes"

# 7. Test in staging

# 8. Promote to production
yarn code-push-standalone promote MyApp-iOS Staging Production

Troubleshooting​

Patch Creation Fails​

Possible Causes:

  • Old bundle path is incorrect
  • New bundle path is incorrect
  • Bundles are identical (no changes)
  • Base bundle mismatch: the patch was generated against a different base than the bundle shipped in the installed app (commonly happens if build‑time bundle copy was skipped in favor of manual generation).

Solution:

# Verify paths exist
ls .dota-versions/v1.0.0-ios
ls .dota/ios

# Use Build Time Bundle generation way

Patch Deployment Fails​

Common Issues:

  • Forgot --isPatch true flag
  • Wrong bundle type (trying to patch a patch)
  • Assets missing

Solution:

# Always include --isPatch true
yarn code-push-standalone release MyApp ./.dota/patches/ios "1.0.0" \
--isPatch true \
--compression brotli

Patch Not Applying​

Possible Causes:

  • Base bundle mismatch
  • User has different version than patch expects
  • Corrupted patch file

Solution:

  • Deploy a full bundle as fallback
  • Verify target version matches
  • Regenerate the patch

Assets Not Updating​

Problem: Images or assets not updating with patch

Solution:

# Ensure assets are included with patch
cp -r .dota/ios/assets .dota/patches/ios/

Advanced Patch Strategies​

Version Chain Management​

For multiple sequential patches:

# v1.0.0 β†’ v1.0.1 (patch)
create-patch v1.0.0 β†’ v1.0.1

# v1.0.1 β†’ v1.0.2 (patch)
create-patch v1.0.1 β†’ v1.0.2

# v1.0.2 β†’ v1.1.0 (full bundle - major update)
release v1.1.0 --isPatch false

Quick Reference​

File Structure​

.dota/
β”œβ”€β”€ ios/ # Current/new bundle
β”œβ”€β”€ android/ # Current/new bundle
└── patches/ # Generated patches
β”œβ”€β”€ ios/
└── android/

.dota-versions/ # Backup old bundles
β”œβ”€β”€ v1.0.0-ios/
β”œβ”€β”€ v1.0.1-ios/
β”œβ”€β”€ v1.0.0-android/
└── v1.0.1-android/

Comparison: Patch vs Full Update​

AspectFull BundlePatch Bundle
Size8-11 MB2-3 MB
Download Time30-60s on 4G5-10s on 4G
DeploymentCLI or Web PanelCLI only
Use CaseMajor updatesMinor updates
RiskLower (complete bundle)Low (auto-fallback)
User ImpactHigher bandwidthMinimal bandwidth
SetupSimpleRequires old bundle

Success Checklist​

Before deploying patches to production:

  • Old bundle is properly backed up
  • New bundle generated successfully
  • Patch created without errors
  • --isPatch true flag is used
  • Assets are included if needed
  • Tested in Staging environment
  • Version targeting is correct
  • Rollback plan is ready
  • Monitoring is enabled

Need Help?​


Congratulations! πŸŽ‰ You've successfully deployed your first patch update! Your users will appreciate the faster downloads and minimal data usage.