Repository navigation
Description
Description
The Release artifacts of the prebuilt iOS frameworks keep their local symbols and a debug map, and an app's Release archive embeds them as they are. strip -x removes 9.3 MB, 48% of the three binaries (ios-arm64 slice, React Native 0.88.1):
| Framework | Published | After strip -x |
|---|---|---|
| React | 11,894,280 | 6,370,280 (-46%) |
| hermesvm | 6,360,048 | 3,002,976 (-53%) |
| ReactNativeDependencies | 1,258,544 | 828,712 (-34%) |
The debug maps point to object files on the build machine, such as /Users/runner/work/react-native/react-native/packages/react-native/.build/output/spm/Release/Build/Intermediates.noindex/... and /Users/runner/work/hermes/hermes/build_iphoneos/.... The artifacts ship no dSYMs. Our app uses the prebuilt frameworks, the default in 0.88. In its Xcode archive the three binaries are byte-identical to the published ones, because Xcode strips only the targets it builds.
Likely cause: the Release artifacts are linked without the strip step that an Xcode archive applies to its own targets.
Related: meta/hermes#1920 (hermesvm size against the 15 MB App Clip limit).
We found this while tracking the Release sizes of the React Native example apps of Evolu (https://evolu.dev), a local-first platform.
Steps to reproduce
On macOS, run:
base=https://repo.reactnative.dev/maven2/com/facebook
for path in \
react/react-native-artifacts/0.88.1/react-native-artifacts-0.88.1-reactnative-core-release.tar.gz \
react/react-native-artifacts/0.88.1/react-native-artifacts-0.88.1-reactnative-dependencies-release.tar.gz \
hermes/hermes-ios/260318099.0.5/hermes-ios-260318099.0.5-hermes-ios-release.tar.gz; do
dir=$(mktemp -d) && curl -sSfL "$base/$path" | tar -xz -C "$dir"
for framework in $(find "$dir" -path '*/ios-arm64/*.framework' -type d); do
binary="$framework/$(basename "$framework" .framework)"
cp "$binary" "$dir/stripped" && strip -x "$dir/stripped"
echo "$(basename "$binary"): $(stat -f %z "$binary") -> $(stat -f %z "$dir/stripped") bytes after strip -x"
done
doneReact Native Version
0.88.1
Affected Platforms
Runtime - iOS, Build - MacOS
Output of npx @react-native-community/cli info
Not app-specific: the script reads the published Maven artifacts. macOS 26.6.2, Xcode 27.2.
Stacktrace or Logs
React: 11894280 -> 6370280 bytes after strip -x
ReactNativeDependencies: 1258544 -> 828712 bytes after strip -x
hermesvm: 6360048 -> 3002976 bytes after strip -x
MANDATORY Reproducer
The script in Steps to reproduce: it reads the published artifacts, no app needed
Screenshots and Videos
No response
Activity
react-native-bot commentedon Nov 2, 2026
Warning
Missing reproducer: We could not detect a reproducible example in your issue report. Reproducers are mandatory and we can accept only one of those as a valid reproducer:
You can read more about about it on our website: How to report a bug.
dave-otf commentedon Nov 3, 2026
The artifact-fetch script and the exact before/after sizes look like a reproducible build report, even if the bot didn’t recognize them as a project reproducer. Could the report clarify whether the team needs a minimal Xcode archive comparison in addition to those published-artifact measurements? That would make it easier to distinguish the prebuilt framework bytes from anything Xcode strips during the app archive.
steida commentedon Nov 3, 2026
An Xcode archive doesn't strip them either. In an unsigned Release device archive (
xcodebuild archive, Xcode 26.6) of an app on React Native 0.88.1, the embeddedReact.framework/Reactandhermesvm.framework/hermesvmstill have their local symbols, andstrip -xtakes React from 11.9 to 6.3 MB and hermesvm from 6.4 to 3.0 MB. Xcode strips the targets it builds, not the prebuilt frameworks it embeds. For a whole app, our minimal app's Release.appgoes from 24.4 MB to 15.1 MB with only these frameworks stripped.The script in the report reads the published artifacts, so it reproduces this without an app.