React Native Integration
ByteHide Shield provides special support for React Native applications, allowing you to protect your JavaScript code from reverse engineering and unauthorized access. This guide explains how to install and use the Shield React Native plugin.
Installation
Install the ByteHide Shield React Native plugin from npm:
npm install --save-dev @bytehide/react-native-shield
Or with yarn:
yarn add --dev @bytehide/react-native-shield
Integration Methods
There are several ways to integrate Shield with your React Native project. Choose the method that best fits your workflow:
Method 1: Using a Standalone Script
Create a script file in the root of your project (e.g., obfuscate.js
) and add the following code:
// obfuscate.js
const shield = require('@bytehide/react-native-shield');
const distDir = './dist'; // Path to your bundle directory
const projectToken = 'your-project-token'; // Your ByteHide project token
const replace = true; // Whether to replace original files
const excludePatterns = []; // Patterns to exclude from obfuscation
const obfuscatedExtension = '.obf'; // Extension for obfuscated files
shield
.obfuscate(distDir, projectToken, replace, excludePatterns, obfuscatedExtension)
.then(() => console.log('Obfuscation completed successfully!'))
.catch((err) => console.error('Error during obfuscation:', err));
Run the script manually:
node obfuscate.js
Method 2: Adding to package.json Scripts
Add the obfuscation step as a script in your project's package.json
:
// package.json
{
"scripts": {
"build": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output ./dist/index.android.bundle --assets-dest ./dist",
"obfuscate": "node obfuscate.js",
"build:protected": "npm run build && npm run obfuscate"
}
}
Then you can run:
npm run build:protected
Method 3: Integration into Build Processes
For Android (build.gradle)
Add a custom task to android/app/build.gradle
:
// android/app/build.gradle
task obfuscateJs(type: Exec) {
commandLine "node", "${project.rootDir}/../obfuscate.js"
}
preBuild.dependsOn obfuscateJs
For iOS (Run Script in Xcode)
- Open your project in Xcode
- Select your target and go to Build Phases
- Click "+" and select "New Run Script Phase"
- Add the following script:
node "$SRCROOT/../obfuscate.js"
Method 4: Using CLI Commands
You can use the CLI command directly:
npx @bytehide/react-native-shield obfuscate \
--src ./dist \
--projectToken your-project-token \
--replace true \
--exclude "*.test.js,*.spec.js" \
--obfuscatedExtension .obf
Configuration Options
The React Native Shield plugin accepts the following options:
Option | Type | Default | Description |
---|---|---|---|
src / distDir | string | Required | Path to the directory containing files to be protected |
projectToken | string | Required | Your ByteHide project token |
replace | boolean | false | Whether to replace original files with obfuscated versions |
exclude | string | '' | Comma-separated list of glob patterns to exclude |
obfuscatedExtension | string | '.obf' | File extension for obfuscated files (when replace is false ) |
React Native-Specific Considerations
When protecting React Native applications, consider the following best practices:
Performance Impact
Obfuscation can affect the startup time and runtime performance of React Native apps. To minimize this impact:
- Exclude files that don't need protection (e.g., UI components, styles)
- Apply lighter protection settings to performance-critical code
- Test thoroughly on low-end devices to ensure acceptable performance
Hermes Compatibility
If you're using Hermes (React Native's JavaScript engine):
- Test your obfuscated code thoroughly with Hermes enabled
- Some advanced obfuscation techniques may not be compatible with Hermes
- Consider using the
target: 'hermes'
option if available in your configuration
Bundle Size
Obfuscation can increase bundle size. To minimize this:
- Use the
compact
option to reduce whitespace - Be selective with protection options that add significant overhead
- Consider using Shield only for production builds
Advanced Configuration
You can customize the protection settings by adding a configuration file:
// shield.config.js
module.exports = {
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 0.5,
stringArray: true,
stringArrayEncoding: ['base64'],
selfDefending: false,
identifierNamesGenerator: 'hexadecimal',
compact: true,
target: 'browser', // or 'node' depending on your build setup
// React Native specific exclusions
reservedNames: [
'^React$',
'^Component$',
'^useState$',
'^useEffect$',
'^StyleSheet$',
'^Animated$',
],
// Exclude common React Native patterns
reservedStrings: [
'react-native',
'ReactNative',
'^StyleSheet.create$'
]
};
Then reference this in your obfuscation script:
// obfuscate.js
const shield = require('@bytehide/react-native-shield');
const config = require('./shield.config.js');
shield
.obfuscate('./dist', 'your-project-token', true, [], '.obf', config)
.then(() => console.log('Obfuscation completed successfully!'))
.catch((err) => console.error('Error during obfuscation:', err));
Custom React Native CLI Integration
You can create a custom React Native CLI command by adding a react-native.config.js
file:
// react-native.config.js
module.exports = {
commands: [
{
name: 'obfuscate',
func: () => {
const shield = require('@bytehide/react-native-shield');
const distDir = './dist';
const projectToken = process.env.BYTEHIDE_PROJECT_TOKEN || 'your-project-token';
shield
.obfuscate(distDir, projectToken, true)
.then(() => console.log('Obfuscation completed successfully!'))
.catch((err) => console.error('Error during obfuscation:', err));
},
},
],
};
Then run it with:
npx react-native obfuscate
Complete Example Workflow
Here's a complete workflow for integrating Shield into a React Native project:
- Install the plugin
npm install --save-dev @bytehide/react-native-shield
- Create a configuration file
// shield.config.js
module.exports = {
controlFlowFlattening: true,
stringArray: true,
stringArrayEncoding: ['base64'],
deadCodeInjection: false,
selfDefending: false,
compact: true,
target: 'browser',
reservedNames: [
'^React$', '^Component$', '^useState$', '^useEffect$'
]
};
- Create an obfuscation script
// obfuscate.js
const shield = require('@bytehide/react-native-shield');
const config = require('./shield.config.js');
const isProd = process.env.NODE_ENV === 'production';
const projectToken = process.env.BYTEHIDE_PROJECT_TOKEN;
if (!projectToken) {
console.error('Error: BYTEHIDE_PROJECT_TOKEN environment variable is required');
process.exit(1);
}
// Apply more aggressive protection in production
if (isProd) {
config.deadCodeInjection = true;
config.selfDefending = true;
}
shield
.obfuscate('./dist', projectToken, true, ['*.map'], '', config)
.then(() => console.log('Obfuscation completed successfully!'))
.catch((err) => console.error('Error during obfuscation:', err));
- Add scripts to package.json
{
"scripts": {
"build:android": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output ./dist/index.android.bundle --assets-dest ./dist",
"build:ios": "react-native bundle --platform ios --dev false --entry-file index.js --bundle-output ./dist/main.jsbundle --assets-dest ./dist",
"obfuscate": "cross-env NODE_ENV=production node obfuscate.js",
"build:protected:android": "npm run build:android && npm run obfuscate",
"build:protected:ios": "npm run build:ios && npm run obfuscate"
}
}
- Configure CI/CD
For GitHub Actions:
# .github/workflows/build.yml
name: Build Protected App
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm ci
- name: Build and protect Android bundle
run: npm run build:protected:android
env:
BYTEHIDE_PROJECT_TOKEN: ${{ secrets.BYTEHIDE_PROJECT_TOKEN }}
Troubleshooting
Common Issues
Obfuscation Errors
If you encounter errors during obfuscation:
- Check that you're using the correct project token
- Ensure your bundle is properly generated before obfuscation
- Try excluding problematic files using the
exclude
option
App Crashes After Obfuscation
If your app crashes after obfuscation:
- Start with lighter protection settings and gradually increase
- Add more items to
reservedNames
andreservedStrings
to preserve critical code - Test with different levels of protection to find the right balance
Next Steps
- Get your project token
- Learn about protection options
- Configure exclusions and reserved items
- Explore React Native mobile considerations