Skip to content

Conversation

@trentrand
Copy link
Contributor

  • Adds enableCompression config option
  • Implements build phase to compress main.jsbundle using zlib
  • Injects runtime decompression logic into AppDelegate.swift
  • Handles cache invalidation to prevent stale bundle loading

Resolves #1

Copilot AI review requested due to automatic review settings January 15, 2026 00:03
@trentrand trentrand marked this pull request as draft January 15, 2026 00:03
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds JS bundle compression support for iOS App Clips to reduce bundle size. The implementation includes build-time compression using zlib during Release builds, runtime decompression in AppDelegate, and cache invalidation to prevent stale bundles.

Changes:

  • Added enableCompression configuration option across plugin components
  • Implemented Xcode build phase to compress main.jsbundle using Node.js zlib
  • Injected Swift decompression logic into AppDelegate with fallback handling

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 20 comments.

File Description
plugin/src/xcode/addBuildPhases.ts Adds shell script build phase for bundle compression in Release builds
plugin/src/withXcode.ts Passes enableCompression parameter to build phase configuration
plugin/src/withCompression.ts Implements AppDelegate modification to inject bundle decompression logic
plugin/src/index.ts Adds enableCompression config option and wires up withCompression plugin

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@trentrand trentrand force-pushed the compress-jsbundle branch 2 times, most recently from 0153fa9 to 7785d58 Compare January 15, 2026 00:30
@nathan-ahn
Copy link
Collaborator

@trentrand Woah this looks great! Let me know once this is ready for review, and I'd be happy to help out with testing. We have an internal ticket for this feature that's been sitting in backlog for the past year and a half, so I'd also be happy to give this a shot in production if that can help validate the implementation here.

This introduces JavaScript bundle compression functionality for iOS App Clips to help meet Apple's strict size limits. The implementation includes a new `enableCompression` parameter that compresses the main.jsbundle using gzip during the build process and automatically decompresses it at runtime using native Swift zlib APIs.

Added detailed documentation about App Clip size constraints and optimization strategies.
@trentrand trentrand marked this pull request as ready for review January 22, 2026 23:27
@trentrand
Copy link
Contributor Author

trentrand commented Jan 22, 2026

Hey @nathan-ahn, I'm glad you're excited about this too! I pushed some additional changes and marked this as ready for review.

In my own app, Stamp Cards, the .jsbundle was reduced 56% from 3597 KB → 1566 KB.

Published here for testing: "react-native-app-clip": "npm:@trentrand/react-native-app-clip@0.7.0-beta.3",

@trentrand
Copy link
Contributor Author

I'm going to adjust 74cc3a3 to inject .env from PROJECT_DIR rather than PROJECT_ROOT, that way we're not assuming a monorepo-like directory.

Ensure environment variables are available during the bundling process for the App Clip target. The file is sourced from project root.
@nathan-ahn
Copy link
Collaborator

Thanks for the published package for testing! No issues in building on my end, and the main.jsbundle.gz file is generated correctly. Here's some results in file sizes that I'm seeing in my own app.

main.jsbundle (simulator build): 12 MB
main.jsbundle.gz (simulator build): 4.6 MB (7.4 MB smaller)

Compressed App Clip File Size (enableCompression: false): 34 MB
Compressed App Clip File Size (enableCompression: true): 36.4 MB (2.4 MB larger)

Even though the jsbundle file itself is significantly smaller, I'm seeing that the resulting final compressed file size is 2.4 MB larger. My guess is that compressing main.jsbundle makes the final round of compression less efficient. Are you seeing similar results on your end once submitted to TestFlight?

@trentrand
Copy link
Contributor Author

trentrand commented Jan 26, 2026

Interesting. I am getting good results in both the jsbundle and final app clip size:

main.jsbundle (iphone 13 device build): 3.51 MB
main.jsbundle.gz (iphone 13 device build): 1.53 MB (1.98 MB smaller)

Compressed App Clip File Size (enableCompression: false): 17.95 MB
Compressed App Clip File Size (enableCompression: true): 15.9 MB (2.04 MB smaller)


Here's my process (repeated with enableCompression false & true):

  1. bunx expo prebuild --clean
  2. cd ios && bunx pod install
  3. open StampCards.xcworkspace
  4. Edit Scheme > Archive > Build Configuration: Release (for both main and clip)
  5. Product > Archive
  6. Organizer > Distribute App > AppStore Connect
  7. Check the size from the failed upload message in AppStore Connect

The failures confirm the sizes above - build 104 showed 16 MB, build 105 showed 18 MB (both over the 15 MB limit).


I suspect our results differ due to double compression. Apple compresses the entire .ipa during archiving. Pre-compressed data (like .gz) doesn't compress well a second time and can even expand a bit.

For me, the 1.98 MB bundle savings outweighs any penalty. For you, with a much larger 7.4 MB bundle reduction, maybe the double-compression penalty scales up and ends up costing more than it saves.

Seems like enableCompression helps some apps but not others - so users should test real-world scenarios to see which way their app goes.

@nathan-ahn
Copy link
Collaborator

@trentrand Super good to know. Considering that there'll be at least one person benefiting from this feature (and I'm sure many others), I'm open to merging this in. Could you update the README to make it clear that this feature may increase the resulting bundle size and that developers should experiment for themselves before enabling in production?

@trentrand
Copy link
Contributor Author

trentrand commented Jan 26, 2026

Absolutely! I updated documentation with these notes in 6749ad4

@nathan-ahn nathan-ahn merged commit 892aa16 into bndkt:main Jan 26, 2026
@nathan-ahn
Copy link
Collaborator

Lovely, thank you for the contribution! Just released in 0.7.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Evaluate to (optionally) include react-native-compressed-jsbundle

2 participants