When deploying a React Native project to iOS, one detail is often overlooked: although JS code is bundled, it is not unreadable. If you directly unpack the IPA, you can find the .jsbundle file in the resource directory, and after formatting, business logic can still be discerned.

In a React Native project containing payment and membership modules, we specifically performed code encryption and structure hiding. The goal is not absolute protection but to significantly increase the cost of code reading while not affecting application operation.


Handling JS Bundle During React Native Build Phase

When releasing React Native for iOS, a JS bundle file is generated, for example:

main.jsbundle

This file is located at:

Payload/App.app/main.jsbundle

If opened directly, you can see compressed JS, but after formatting, it remains readable.


Generating Compressed Bundle with Metro

During the build phase, you can execute:

npx react-native bundle \
--platform ios \
--dev false \
--entry-file index.js \
--bundle-output main.jsbundle \
--assets-dest ./assets

--dev false disables development mode, reducing debug information.


Further Compression with Terser

After generating the bundle, you can compress it again with terser:

terser main.jsbundle -o main.min.jsbundle

After compression:

  • Variable names are shortened
  • Code structure becomes single-line
  • Readability significantly decreases

Then replace the original bundle with the compressed file.


Handling Critical Strings in JS

In React Native projects, some logic is triggered by strings, for example:

"login_success"
"vip_purchase"
"payment_callback"

If these strings are directly exposed in the bundle, they can still aid in logic analysis.

You can perform a simple replacement before bundling, for example:

"login_success" → "a1b2c3"

This step can be automated with a script, such as a Node.js script for batch replacement.

Note that such replacements must be consistent with business logic; otherwise, they may affect operation.


Viewing React Native Resource Structure in IPA

After building the IPA, you can unpack it to view:

Payload/App.app/

React Native-related content includes:

  • main.jsbundle
  • Image resources
  • Font files
  • JSON configurations

If the resource directory retains the development structure, for example:

assets/images/vip_banner.png
assets/config/payment.json

These paths themselves are information.


Handling Resources and JS Files at the IPA Level

React Native’s bundle and resources are already packaged into the IPA, so they can be processed directly at the IPA level.

Ipa Guard supports unified processing of resource files, including:

  • JS
  • JSON
  • Images
  • HTML
  • Audio

After loading the IPA in the tool, go to the resource module and select JS and image types.

After execution:

main.jsbundle → x92kd.bundle
vip_banner.png → a83kd.png

The tool synchronously updates resource reference paths, so it does not affect operation.
File Name Obfuscation


Obfuscating Symbols for Native Modules

React Native projects still contain iOS native code, for example:

  • Native bridge modules
  • Third-party SDKs
  • Objective-C / Swift files

These parts remain as Mach-O binaries in the IPA.

Using Ipa Guard, you can obfuscate these symbols:

  • Class names
  • Method names
  • Parameter names
  • Variable names

For example:

RNPaymentModule → k39sd2
handleLogin → a8d2k1

After obfuscation, viewing the binary with strings shows the original names have disappeared.
Code Obfuscation


Modifying Resource MD5 and Image Features

If multiple applications share the same resources, such as UI icons or background images, you can process the resource MD5.

After enabling image processing options in Ipa Guard:

  • Image content remains consistent
  • MD5 values change

This prevents resources from being easily identified by comparison.
Modify MD5


Cleaning Up Debug Information

React Native build processes may include log strings.

You can run:

strings AppBinary | grep React

If the output contains debug information, it can be cleaned up during IPA processing.

Ipa Guard supports removing some debug information to make the binary cleaner.


Re-signing and Installation Testing

All IPA modifications cause the signature to become invalid, so re-signing is required.

You can use the command:

kxsign sign app.ipa \
-c cert.p12 \
-p password \
-m dev.mobileprovision \
-z test.ipa \
-i

Alternatively, you can configure certificates directly in Ipa Guard and complete the signing.

After connecting the device, the application will install automatically.
Re-signing


Verifying React Native Operation Status

After installation, key tests include:

  • Whether JS pages load normally
  • Whether Bridge calls work correctly
  • Critical processes like login and payment
  • Whether dynamically loaded resources succeed

If certain modules are abnormal, you can return to resource or symbol configurations to adjust.


React Native code encryption should not rely solely on JS compression. Bundle processing is only the first step; resource structure, native module symbols, and IPA-level information also affect code exposure.

In practical projects, by handling JS with Metro + terser and combining Ipa Guard for IPA resource obfuscation and binary symbol processing, overall security can be enhanced without modifying the source code structure.

Reference link: https://ipaguard.com/tutorial/zh/1/1.html