Rn bundle size
Skill almasumdev/awesome-react-native-agent-skills/.github/skills/performance/rn-bundle-size
Curated agent skills, conventions, and workflows for building React Native apps with AI coding agents.
npx -y skills add almasumdev/awesome-react-native-agent-skills --skill rn-bundle-sizeAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Expert guidance on shrinking React Native bundle size with Hermes bytecode, Metro config, tree shaking, and inline requires. Use when asked about bundle size, startup, or Metro configuration.
SKILL.md
3.7 KB, as published. Nobody here has run it
React Native Bundle Size
Instructions
A smaller bundle parses faster and starts faster. Target the JS bundle first -- native code changes are a distant second.
1. Hermes Bytecode
Hermes compiles JS to bytecode at build time, cutting parse cost and reducing app size.
android/gradle.properties:hermesEnabled=trueios/Podfile::hermes_enabled => true(default in modern templates)
Verify at runtime:
export const isHermes = !!(globalThis as { HermesInternal?: unknown }).HermesInternal;
2. Metro Config
metro.config.js:
const { getDefaultConfig } = require('expo/metro-config'); // or '@react-native/metro-config'
const config = getDefaultConfig(__dirname);
config.transformer = {
...config.transformer,
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: true,
inlineRequires: true,
},
}),
minifierConfig: {
keep_classnames: false,
keep_fnames: false,
mangle: { keep_classnames: false, keep_fnames: false },
compress: { drop_console: false },
},
};
config.resolver = {
...config.resolver,
unstable_enablePackageExports: true,
};
module.exports = config;
inlineRequires defers require calls until first use -- large cold-start wins. experimentalImportSupport enables ESM semantics so Metro can drop unused named exports.
3. Tree Shaking Friendly Imports
Never pull a whole icon or util library:
// Bad -- pulls the whole package
import _ from 'lodash';
_.debounce(fn, 200);
// Good -- only pulls the one function
import debounce from 'lodash/debounce';
debounce(fn, 200);
For icon sets, prefer @expo/vector-icons/<FontName> sub-paths or react-native-svg with individually imported SVGs.
4. Source Maps and Analysis
Generate a bundle and analyze it:
npx react-native bundle \
--platform android \
--dev false \
--entry-file index.js \
--bundle-output dist/android.bundle \
--sourcemap-output dist/android.map
npx react-native-bundle-visualizer --platform android
Look for:
- Duplicated copies of
react,scheduler, or any polyfill (indicates misconfigured resolver). - Full
momentorlodashbuilds (replace withdate-fns/dayjs/ per-function imports). - Large asset bundles -- move images to remote CDN or OTA delivery where possible.
5. Native Size
-
Android: enable R8 (
android.enableR8=true) and split APKs by ABI:android { splits { abi { enable true reset() include 'arm64-v8a', 'armeabi-v7a', 'x86_64' universalApk false } } } -
iOS: enable bitcode-free thinning (
ENABLE_BITCODE = NOis now the default), strip debug symbols from release, and compressAssets.carby using an asset catalog.
6. Shipping Deltas
- Use
expo-updates(EAS Update) or CodePush to ship JS-only fixes without a store review. - Keep native modules out of hot-fix cycles; updates that change native code require a full build.
7. Dev-Only Code
Guard dev-only tooling so it never lands in release:
if (__DEV__) {
require('./devtools/reactotron');
}
Checklist
- Hermes is enabled on both platforms.
-
inlineRequiresandexperimentalImportSupportare on inmetro.config.js. - No full-library imports of
lodash,moment, or icon packs. - A bundle visualizer report has been captured and inspected.
- Android release builds use R8 and ABI splits; iOS release strips debug symbols.
- Dev-only tools (Reactotron, DevMenu helpers) are guarded by
__DEV__.