DeployPulse

Optimize Assets

OTA update size directly affects download success rates on poor networks and the time users spend waiting for an update to apply. This page covers both built-in DeployPulse optimizations and app-side best practices for keeping bundle sizes small.


Built-in: Differential Packages

DeployPulse automatically generates a differential package for every release after the first. Only files that changed since the previous release are included in the download — the unchanged parts of the bundle are reused from the device's cached copy.

The diff badge in the dashboard's release history confirms that a differential package was generated. No configuration is needed.


Use Hermes

Hermes is the default JavaScript engine in React Native 0.70 and later. If your project was created with RN 0.70+, Hermes is already enabled - no changes needed.

For projects on older React Native versions, enable Hermes in your native config:

android/app/build.gradle

project.ext.react = [
    enableHermes: true
]

ios/Podfile

use_react_native!(
  :hermes_enabled => true
)

No special dpctl flags are needed when using Hermes. dpctl release-react produces a standard JavaScript bundle that Hermes compiles to bytecode on the device at first run and caches from then on.


Exclude Source Maps

Source maps can double the bundle size if accidentally included in the OTA release zip. Always output them to a path outside --outputDir:

dpctl release-react MyApp-iOS ios \
  --outputDir ./release \
  --sourcemapOutput ./sourcemaps/main.jsbundle.map \
  --dev false

If you use Sentry, upload the map file separately after releasing. See the Sentry Integration guide.


Image Optimization

Images frequently account for 60–80% of bundle size. A few changes can have a large impact:

  • react-native-imagemin-asset-plugin — Metro plugin that automatically compresses PNG, JPG, and WebP assets at build time with no quality loss.
  • SVGO — lossless SVG optimization for react-native-svg assets. Run as a build step: svgo --folder ./src/assets/icons.
  • Remove @1x assets — modern Android and iOS devices no longer use @1x images. Removing them reportedly reduces bundle size by ~12%.
  • Avoid data:image URIs — inline base64 images inflate the JS bundle and prevent differential updates from being effective. Always reference assets by path.

Reduce JS Bundle Size

  • react-native-bundle-visualizer — runs Metro and opens an interactive treemap to identify which dependencies are largest.
  • Knip — static analysis tool that detects unused exports and files. Removing dead code shrinks the bundle and improves diff efficiency between releases.
  • Avoid large JSON files in the bundle — localization files and feature flag payloads are common offenders. Lazy-load them at runtime or fetch from a remote endpoint instead of bundling.

Font Optimization

Fontmin generates subset fonts that contain only the Unicode characters your app actually uses. Subsetting a custom font from 400KB to 40KB is common for apps that use a limited character set.


Release Flags

Always build releases with:

dpctl release-react MyApp-iOS ios \
  --deployment Production \
  --dev false \
  --minify true
  • --dev false — disables the React Native DevTools bridge, assertions, and verbose logging. Required for production.
  • --minify true — applies additional Terser minification on top of Metro's default output.

Further Reading