Documentation Index
Fetch the complete documentation index at: https://mintlify.com/facebook/react-native/llms.txt
Use this file to discover all available pages before exploring further.
RAM Bundles and Inline Requires
Reduce your React Native app’s startup time by using RAM (Random Access Module) bundles and inline requires to load JavaScript code on-demand.
What are RAM Bundles?
RAM bundles split your JavaScript bundle into multiple files, allowing the app to load only the modules it needs at startup, deferring the rest until required.
Traditional Bundle
index.bundle (5MB)
├── App code
├── Dependencies
├── Screens (all)
└── Utilities (all)
All code loads at startup, increasing time-to-interactive.
RAM Bundle
index.bundle (small startup bundle)
├── js-modules/
│ ├── 0.js (Home screen)
│ ├── 1.js (Profile screen)
│ ├── 2.js (Heavy utility)
│ └── ...
Only essential code loads at startup; modules load on-demand.
Benefits
- Faster Startup: Only load essential modules initially
- Reduced Memory: Lower initial memory footprint
- Better User Experience: App becomes interactive sooner
- Scalable: Benefits increase with app size
Enabling RAM Bundles
Android
Modify android/app/build.gradle:
project.ext.react = [
enableHermes: true,
bundleCommand: "ram-bundle",
extraPackagerArgs: []
]
apply from: "../../node_modules/react-native/react.gradle"
Or configure in react.gradle:
def bundleCommand = "ram-bundle"
def bundleConfig = "metro.config.js"
iOS
Modify the bundle phase script in Xcode:
Open Xcode project
Open ios/YourApp.xcworkspace.
Edit build phase
Select your target > Build Phases > Bundle React Native code and images.
Update script
Change the script to use ram-bundle:export BUNDLE_COMMAND="ram-bundle"
export NODE_BINARY=node
../node_modules/react-native/scripts/react-native-xcode.sh
Alternatively, modify ios/YourApp/AppDelegate.mm:
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
Metro Configuration
Configure Metro bundler for RAM bundles in metro.config.js:
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const config = {
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true, // Enable inline requires
},
}),
},
};
module.exports = mergeConfig(getDefaultConfig(__dirname), config);
Inline Requires
Inline requires defer module loading until they’re actually needed.
Without Inline Requires
import React from 'react';
import { View, Text } from 'react-native';
import HeavyComponent from './HeavyComponent';
import RarelyUsedUtil from './RarelyUsedUtil';
// All imports load at startup
const App = () => {
return (
<View>
<Text>App</Text>
</View>
);
};
Everything loads immediately, even unused modules.
With Inline Requires
import React from 'react';
import { View, Text } from 'react-native';
const App = () => {
return (
<View>
<Text>App</Text>
</View>
);
};
// Load only when needed
const openHeavyScreen = () => {
const HeavyComponent = require('./HeavyComponent').default;
// Use HeavyComponent
};
const useRareUtil = () => {
const RarelyUsedUtil = require('./RarelyUsedUtil').default;
return RarelyUsedUtil.process();
};
Modules load on-demand, reducing startup time.
Automatic Inline Requires
Babel plugin automatically converts imports to inline requires:
npm install --save-dev babel-plugin-transform-inline-requires
Update babel.config.js:
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
'transform-inline-requires',
],
};
Now all non-top-level imports automatically become inline requires:
// Before transformation
import { useEffect } from 'react';
import MyComponent from './MyComponent';
function App() {
useEffect(() => {
console.log('mounted');
}, []);
return <MyComponent />;
}
// After transformation
import { useEffect } from 'react';
function App() {
const MyComponent = require('./MyComponent').default;
useEffect(() => {
console.log('mounted');
}, []);
return <MyComponent />;
}
Navigation Lazy Loading
Combine inline requires with navigation:
React Navigation
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
const App = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={require('./screens/Home').default}
/>
<Stack.Screen
name="Profile"
component={require('./screens/Profile').default}
/>
<Stack.Screen
name="Settings"
// Lazy load heavy screens
component={require('./screens/Settings').default}
/>
</Stack.Navigator>
);
};
React Navigation with getComponent
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
const App = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
getComponent={() => require('./screens/Home').default}
/>
<Stack.Screen
name="Profile"
getComponent={() => require('./screens/Profile').default}
/>
</Stack.Navigator>
);
};
Conditional Requires
Load modules based on conditions:
import { Platform } from 'react-native';
const getAnalytics = () => {
if (Platform.OS === 'ios') {
return require('./analytics/ios').default;
} else {
return require('./analytics/android').default;
}
};
const analytics = getAnalytics();
Measuring Impact
Before Optimization
const startTime = Date.now();
import('./App').then(() => {
const loadTime = Date.now() - startTime;
console.log(`App loaded in ${loadTime}ms`);
});
Monitor Bundle Size
# Generate bundle
npx react-native bundle \
--platform android \
--dev false \
--entry-file index.js \
--bundle-output output.bundle \
--ram-bundle
# Check size
ls -lh output.bundle
ls -lh js-modules/
Startup Time Profiling
import { performance } from 'react-native';
performance.mark('app-start');
// In your App component
useEffect(() => {
performance.mark('app-interactive');
performance.measure(
'startup-time',
'app-start',
'app-interactive'
);
const measure = performance.getEntriesByName('startup-time')[0];
console.log(`Startup time: ${measure.duration}ms`);
}, []);
Best Practices
Do Inline Require
- Heavy screens/components
- Rarely used utilities
- Platform-specific code
- Large third-party libraries
- Analytics and tracking code
const openCamera = () => {
const Camera = require('react-native-camera').RNCamera;
// Use camera
};
Don’t Inline Require
- Core dependencies (React, React Native)
- Frequently used components
- Small utilities
- Critical path code
// Keep these as imports
import React from 'react';
import { View, Text } from 'react-native';
Hermes + RAM Bundles
Combine Hermes bytecode with RAM bundles for maximum optimization:
// android/app/build.gradle
project.ext.react = [
enableHermes: true,
bundleCommand: "ram-bundle",
hermesCommand: "../../node_modules/react-native/sdks/hermesc/%OS-BIN%/hermesc"
]
Benefits:
- Bytecode compilation is faster than JavaScript parsing
- RAM bundles reduce initial load
- Combined: significantly faster startup
Debugging RAM Bundles
Inspect Module Loading
if (__DEV__) {
const originalRequire = require;
global.require = function(moduleName) {
console.log(`Loading module: ${moduleName}`);
return originalRequire(moduleName);
};
}
Bundle Analyzer
Analyze your bundle composition:
npm install --save-dev react-native-bundle-visualizer
npx react-native-bundle-visualizer
Common Issues
Module Not Found
Ensure correct path in require:
// Wrong
const Component = require('MyComponent').default;
// Right
const Component = require('./MyComponent').default;
Hot Reloading
Inline requires work with Fast Refresh:
const MyComponent = require('./MyComponent').default;
// Fast Refresh still works
Static Imports in Render
Avoid require in render method:
// Bad: requires on every render
const App = () => {
const Component = require('./Component').default;
return <Component />;
};
// Good: require once
const Component = require('./Component').default;
const App = () => <Component />;
Typical improvements with RAM bundles + inline requires:
- Startup time: 20-40% faster
- Initial memory: 15-30% lower
- Time to interactive: 25-50% faster
Gains scale with app size and complexity.
Next Steps