Skip to content

feat(expo): Add Expo config plugin for automated CodePush setup #74

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

saseungmin
Copy link

@saseungmin saseungmin commented Jun 11, 2025

📝 Overview

This PR adds an Expo config plugin that automatically configures CodePush for Expo projects, eliminating the need for manual native code modifications. The plugin handles both iOS and Android platform setup through Expo's prebuild process.

✨ What's Added

  • Expo Config Plugin: Automated CodePush integration for Expo projects
  • Handles both iOS and Android native code modifications
  • Comprehensive warnings for unsupported configurations
  • Zero Manual Setup
  • Documentation Updates (README.md)
    • Added Expo plugin setup guide to installation section

🎯 Usage

Installation

npm install @bravemobile/react-native-code-push

Configuration

Add the plugin to your Expo config:

app.config.js:

export default {
  expo: {
    plugins: ["@bravemobile/react-native-code-push"],
  },
};

Build Process

# Prebuild to apply native changes
npx expo prebuild

🚨 Error Handling

The plugin includes comprehensive warning systems:

  • Unsupported file formats: Clear guidance for manual setup
  • Missing files: Helpful error messages with setup instructions
  • Template variations: Warnings for non-standard Expo templates
image image 스크린샷 2025-06-11 오후 3 28 25

✅ Platform Support

Android

  • Kotlin MainApplication (Expo default)
  • Automatic gradle script integration
  • CodePush import and method implementation

iOS

  • Swift AppDelegate with bridging header
  • Objective-C AppDelegate
  • Automatic CodePush import and bundle URL override

✅ Testing

  • Tested with Expo SDK 52, 53 projects
  • Verified both iOS and Android configurations
  • Confirmed compatibility with default Expo templates
  • Validated error handling for edge cases

🔄 Breaking Changes

None - This is an additive feature that doesn't affect existing functionality.

Copy link
Member

@floydkim floydkim left a comment

Choose a reason for hiding this comment

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

Great work.
Thanks for your contribution and the detailed description.

I’ve added a few comments.
feel free to check them out and let me know what you think.

Comment on lines +54 to +58
"peerDependenciesMeta": {
"expo": {
"optional": true
}
},
Copy link
Member

Choose a reason for hiding this comment

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

👍

const { createRunOncePlugin } = require('expo/config-plugins');
const { withAndroidBuildScriptDependency, withAndroidMainApplicationDependency } = require('./withCodePushAndroid');
const { withIosBridgingHeader, withIosAppDelegateDependency } = require('./withCodePushIos');
const pkg = require('../../package.json');
Copy link
Member

Choose a reason for hiding this comment

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

Does it intend to refer to the @bravemobile/react-native-code-push package?
Just curious.

Comment on lines +53 to +64
action.modResults.contents = androidMainApplicationApplyImplementation(
action.modResults.contents,
'class MainApplication : Application(), ReactApplication {',
'import com.microsoft.codepush.react.CodePush\n',
true,
);

action.modResults.contents = androidMainApplicationApplyImplementation(
action.modResults.contents,
'object : DefaultReactNativeHost(this) {',
' override fun getJSBundleFile(): String = CodePush.getJSBundleFile()\n',
);
Copy link
Member

Choose a reason for hiding this comment

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

Is the MainApplication file written in Kotlin starting from Expo SDK 50?
Is there no need to support the case where it is written in Java?

@@ -35,7 +35,30 @@ The following changes are optional but recommended for cleaning up the old confi
npm install @bravemobile/react-native-code-push
```

### 2. iOS Setup
### 2. Expo Setup
Copy link
Member

Choose a reason for hiding this comment

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

Sorry, but since our team, as maintainers, doesn’t use Expo in our environment, supporting Expo has a lower priority compared to RN CLI projects.
Although Expo is recommended, our library still prioritizes RN CLI support.

so, please move the Expo setup instructions to come after the iOS/Android sections. 🙏

npx expo prebuild
```

>[!NOTE] The plugin automatically handles all native iOS and Android code modifications. No manual editing of AppDelegate, MainApplication, or gradle files is required.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
>[!NOTE] The plugin automatically handles all native iOS and Android code modifications. No manual editing of AppDelegate, MainApplication, or gradle files is required.
> [!NOTE]
> The plugin automatically handles all native iOS and Android code modifications. No manual editing of AppDelegate, MainApplication, or gradle files is required.

Note

The plugin automatically handles all native iOS and Android code modifications. No manual editing of AppDelegate, MainApplication, or gradle files is required.

Comment on lines +122 to +129
'withIosBridgingHeader',
`
Failed to detect ${bridgingHeaderFilePath} file.
Please add CodePush integration manually:
#import <CodePush/CodePush.h>

Supported format: Expo SDK default template.
`
Copy link
Member

Choose a reason for hiding this comment

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

It might be a good idea to add a reference link here as well.

e.g.
https://github.com/Soomgo-Mobile/react-native-code-push#2-edit-appdelegate-code

Copy link
Member

Choose a reason for hiding this comment

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

👍

Comment on lines +64 to +69
action.modResults.contents = iosApplyImplementation(
action.modResults.contents,
`return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];`,
`return [CodePush bundleURL];`,
true,
);
Copy link
Member

Choose a reason for hiding this comment

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

I was just wondering..
Expo plugins probably don’t modify and commit changes to AppDelegate/MainApplication file.

If so, the code developers see might be different from what’s actually used at build time.
I think this could be confusing. Especially if someone tries to search the code.
And if someone modified the code, this plugin might not work correctly.

This plugin is great!
but from a maintenance perspective, I personally think it’s better for developers to update and manage their code manually.

No worries, this PR won't be rejected :)

Comment on lines +44 to +46
const bridgingHeaderPath = config.buildSettings[
'SWIFT_OBJC_BRIDGING_HEADER'
].replace(/"/g, '');
Copy link
Member

Choose a reason for hiding this comment

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

I suspect that value of bridgingHeaderPath is a file name, not a path 🤔
I think it would be better to rename to bridgingHeaderFile.

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.

2 participants