├── .gitattributes ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── enhancement.yml ├── PULL_REQUEST_TEMPLATE └── workflows │ ├── lint-md.yml │ └── test.yml ├── .gitignore ├── CONTRIBUTING.md ├── README.md ├── apps ├── app │ ├── .gitignore │ ├── App.tsx │ ├── app.config.js │ ├── app.json │ ├── assets │ │ ├── adaptive-icon.png │ │ ├── favicon.png │ │ ├── icon.png │ │ └── splash.png │ ├── meta │ │ └── screenshots │ │ │ └── android │ │ │ ├── en-US │ │ │ └── APP_EMULATOR-5554 (PIXEL_6_PRO_API_33)_0.png │ │ │ ├── nl-NL │ │ │ └── APP_EMULATOR-5554 (PIXEL_6_PRO_API_33)_0.png │ │ │ └── zh-CN │ │ │ └── APP_EMULATOR-5554 (PIXEL_6_PRO_API_33)_0.png │ ├── package.json │ ├── scripts │ │ ├── build-detox-ios.sh │ │ └── start-metro.sh │ ├── src │ │ ├── android-jsc-intl │ │ │ └── App.tsx │ │ └── react-native-adjust │ │ │ └── App.tsx │ └── tsconfig.json ├── apple-settings │ ├── app.config.ts │ ├── app.json │ ├── index.js │ ├── package.json │ ├── src │ │ ├── App.tsx │ │ └── SettingsViews.tsx │ └── tsconfig.json ├── ios-stickers │ ├── app.config.js │ ├── app.json │ ├── assets │ │ ├── imessage-icon.png │ │ └── stickers │ │ │ ├── annoyed.png │ │ │ ├── avocool.png │ │ │ ├── cant.png │ │ │ ├── coder-girl.png │ │ │ ├── cozzy copy.png │ │ │ ├── cozzy.png │ │ │ ├── crazy.png │ │ │ ├── cuddle.png │ │ │ ├── donno.png │ │ │ ├── dork.png │ │ │ ├── focus.png │ │ │ └── teapot.png │ ├── expo-template-bare-minimum-50.0.17.tgz │ ├── index.js │ ├── package.json │ └── src │ │ └── App.js ├── react-native-branch │ ├── app.config.js │ ├── app.json │ ├── index.js │ ├── package.json │ └── src │ │ └── App.js ├── react-native-dynamic-app-icon │ ├── app.config.js │ ├── app.json │ ├── assets │ │ └── icons │ │ │ ├── autumn.png │ │ │ ├── fall.png │ │ │ ├── solstice.png │ │ │ ├── spring.png │ │ │ ├── summer.png │ │ │ └── winter.png │ ├── index.js │ ├── package.json │ ├── src │ │ └── App.js │ └── tsconfig.json ├── react-native-pdf │ ├── app.config.js │ ├── app.json │ ├── index.js │ ├── package.json │ └── src │ │ └── App.js ├── react-native-siri-shortcut │ ├── app.config.js │ ├── app.json │ ├── index.js │ ├── package.json │ ├── src │ │ ├── App.ios.tsx │ │ └── App.tsx │ └── tsconfig.json └── react-native-webrtc │ ├── app.config.js │ ├── app.json │ ├── index.js │ ├── package.json │ ├── src │ └── App.js │ └── tsconfig.json ├── fixtures ├── AppDelegate.mm ├── AppDelegate.swift ├── Podfile ├── README.md ├── app-Bridging-Header.h ├── app-build.gradle ├── build.gradle └── getFixtures.ts ├── lerna.json ├── package.json ├── packages ├── android-jsc-intl │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── app.plugin.js │ ├── package.json │ ├── src │ │ └── withAndroidJscIntl.ts │ └── tsconfig.json ├── apple-settings │ ├── .eslintrc.js │ ├── README.md │ ├── __mocks__ │ │ ├── @expo │ │ │ └── image-utils.ts │ │ └── fs.ts │ ├── jest.config.js │ ├── jest │ │ └── setup.js │ ├── package.json │ ├── src │ │ ├── base-mods │ │ │ ├── strings.ts │ │ │ ├── withSettingsPlist.ts │ │ │ ├── withSettingsStrings.ts │ │ │ └── withXcparse.ts │ │ ├── index.tsx │ │ ├── models.ts │ │ ├── schema │ │ │ ├── SettingsPlist.json │ │ │ └── SettingsPlist.ts │ │ ├── static.ts │ │ └── withLinkedSettingsBundle.ts │ └── tsconfig.json ├── ios-stickers │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── __mocks__ │ │ ├── @expo │ │ │ └── image-utils.ts │ │ └── fs.ts │ ├── jest.config.js │ ├── jest │ │ └── setup.js │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ ├── fixtures │ │ │ │ └── icon.png │ │ │ ├── generateImessageIconsAsync.test.ts │ │ │ └── withStickerPack-test.ts │ │ ├── generateImessageIconsAsync.ts │ │ ├── options.json │ │ ├── withStickerAssets.ts │ │ ├── withStickerInfoPlist.ts │ │ ├── withStickerPack.ts │ │ ├── withStickerXcodeTarget.ts │ │ └── xcodeSticker.ts │ └── tsconfig.json ├── react-native-adjust │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── app.plugin.js │ ├── package.json │ ├── src │ │ └── withReactNativeAdjust.ts │ └── tsconfig.json ├── react-native-ble-plx │ └── README.md ├── react-native-blob-util │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── app.plugin.js │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ ├── __snapshots__ │ │ │ │ └── withReactNativeBlobUtil-test.ts.snap │ │ │ └── withReactNativeBlobUtil-test.ts │ │ └── withReactNativeBlobUtil.ts │ └── tsconfig.json ├── react-native-branch │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── android │ │ ├── .gitignore │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── expo │ │ │ └── modules │ │ │ └── adapters │ │ │ └── branch │ │ │ ├── BranchApplicationLifecycleListener.kt │ │ │ ├── BranchPackage.kt │ │ │ └── BranchReactActivityLifecycleListener.kt │ ├── app.plugin.js │ ├── expo-module.config.json │ ├── ios │ │ ├── ExpoAdapterBranch.podspec │ │ └── ExpoAdapterBranch │ │ │ └── BranchAppDelegate.swift │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ ├── fixtures │ │ │ │ └── react-native-AndroidManifest.xml │ │ │ ├── withBranchAndroid.test.ts │ │ │ └── withBranchIOS.test.ts │ │ ├── types.ts │ │ ├── withBranch.ts │ │ ├── withBranchAndroid.ts │ │ └── withBranchIOS.ts │ └── tsconfig.json ├── react-native-callkeep │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── app.plugin.js │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── ensureHeaderSearchPath.ts │ │ └── withCallkeep.ts │ └── tsconfig.json ├── react-native-dynamic-app-icon │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── react-native-pdf │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── app.plugin.js │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ ├── __snapshots__ │ │ │ │ └── withPdf.test.ts.snap │ │ │ └── withPdf.test.ts │ │ └── withPdf.ts │ └── tsconfig.json ├── react-native-quick-actions │ └── README.md ├── react-native-siri-shortcut │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── app.plugin.js │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ ├── __snapshots__ │ │ │ │ └── withReactNativeSiriShortcut.test.ts.snap │ │ │ └── withReactNativeSiriShortcut.test.ts │ │ └── withReactNativeSiriShortcut.ts │ └── tsconfig.json ├── react-native-webrtc │ ├── .eslintrc.js │ ├── CHANGELOG.md │ ├── README.md │ ├── app.plugin.js │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── withBitcodeDisabled.ts │ │ ├── withPermissions.ts │ │ └── withWebRTC.ts │ └── tsconfig.json └── tv │ └── README.md ├── scripts ├── generate-plugin.ts ├── gh-issues-config.ts ├── template │ ├── README.md │ ├── index.ts │ ├── package.json │ └── tsconfig.json └── update-dependabot-config.ts └── yarn.lock /.gitattributes: -------------------------------------------------------------------------------- 1 | packages/*/build/** -diff linguist-generated 2 | packages/*/plugin/build/** -diff linguist-generated 3 | packages/@*/*/build/** -diff linguist-generated 4 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | /* @EvanBacon -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: 🐛 Expo Config Plugin Bug Report 2 | description: Report a reproducible bug with one of the Expo Config Plugins. 3 | labels: bug 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: >- 8 | Thanks for taking the time to file a bug report! Please fill out this 9 | form as completely as possible. 10 | - type: markdown 11 | attributes: 12 | value: >- 13 | If you leave out sections there is a high likelihood your issue will be 14 | closed. If you have a question, not a bug report, please post it on our 15 | [forums](https://forums.expo.dev/) instead. 16 | - type: textarea 17 | attributes: 18 | label: Summary 19 | description: Describe the issue in 1 or 2 sentences 20 | placeholder: >- 21 | Clearly describe what the expected behavior is vs. what is actually 22 | happening. This should be as short as possible, while still 23 | communicating all the necessary information. If your summary is just 'X 24 | library/method isn't working', then you need to continue debugging 25 | yourself and provide more information. 26 | validations: 27 | required: true 28 | - type: dropdown 29 | attributes: 30 | label: Config Plugin 31 | options: 32 | - '@config-plugins/android-jsc-intl' 33 | - '@config-plugins/apple-settings' 34 | - '@config-plugins/detox' 35 | - '@config-plugins/ffmpeg-kit-react-native' 36 | - '@config-plugins/ios-stickers' 37 | - '@config-plugins/react-native-adjust' 38 | - '@config-plugins/react-native-blob-util' 39 | - '@config-plugins/react-native-branch' 40 | - '@config-plugins/react-native-callkeep' 41 | - '@config-plugins/react-native-dynamic-app-icon' 42 | - '@config-plugins/react-native-pdf' 43 | - '@config-plugins/react-native-siri-shortcut' 44 | - '@config-plugins/react-native-webrtc' 45 | validations: 46 | required: true 47 | - type: dropdown 48 | attributes: 49 | label: What platform(s) does this occur on? 50 | multiple: true 51 | options: 52 | - Android 53 | - iOS 54 | validations: 55 | required: true 56 | - type: input 57 | attributes: 58 | label: SDK Version 59 | description: What version of the Expo SDK are you using? 60 | - type: textarea 61 | attributes: 62 | label: Reproducible demo 63 | description: >- 64 | This should include as little code as possible, do not simply link your 65 | entire project. If a reproducible demo is not provided, it is very 66 | likely your issue will be closed. Read [here more 67 | guidance](https://stackoverflow.com/help/mcve). 68 | validations: 69 | required: true 70 | - type: markdown 71 | attributes: 72 | value: >- 73 | Please make sure contributors can run your code and follow the steps 74 | your provided in order to reproduce the bug. 75 | - type: markdown 76 | attributes: 77 | value: >- 78 | **Realize that it is up to you to debug your code and be as certain as 79 | possible that the bug is with Expo, not with your own app.** [Here's an 80 | excellent guide to debugging you can 81 | follow](https://gist.github.com/brentvatne/5ac00cba0c70b7a06b89a56787d6bc4a). 82 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | blank_issues_enabled: false 3 | contact_links: 4 | - name: 🤔 Question about an Expo Config Plugin 5 | about: >- 6 | If you have a question about an Expo Config Plugin, please ask it on the 7 | forums, discord, Twitter, or Stack Overflow. 8 | url: https://forums.expo.io/ 9 | - about: E2E tests and automation for mobile 10 | name: 📦 detox issues 11 | url: https://github.com/wix/Detox/issues 12 | - about: FFmpeg Kit for React Native 13 | name: 📦 ffmpeg-kit-react-native issues 14 | url: https://github.com/arthenica/ffmpeg-kit/issues 15 | - about: Adjust React Native SDK 16 | name: 📦 react-native-adjust issues 17 | url: https://github.com/adjust/react_native_sdk/issues 18 | - about: >- 19 | A module provides upload, download, and files access API. Supports file 20 | stream read/write for process large files. 21 | name: 📦 react-native-blob-util issues 22 | url: https://github.com/RonRadtke/react-native-blob-util/issues 23 | - about: iOS 10 CallKit and Android ConnectionService Framework For React Native 24 | name: 📦 react-native-callkeep issues 25 | url: https://github.com/react-native-webrtc/react-native-callkeep/issues 26 | - about: Programmatically change the app icon in React Native. 27 | name: 📦 react-native-dynamic-app-icon issues 28 | url: https://github.com/idearockers/react-native-dynamic-app-icon/issues 29 | - about: A react native PDF view component, support ios and android platform 30 | name: 📦 react-native-pdf issues 31 | url: https://github.com/wonday/react-native-pdf/issues 32 | - about: A React Native library that enables you to use iOS 12+ Siri Shortcuts. 33 | name: 📦 react-native-siri-shortcut issues 34 | url: https://github.com/Gustash/react-native-siri-shortcut/issues 35 | - about: WebRTC for React Native 36 | name: 📦 react-native-webrtc issues 37 | url: https://github.com/react-native-webrtc/react-native-webrtc/issues 38 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/enhancement.yml: -------------------------------------------------------------------------------- 1 | name: "⭐️ Config Plugin Request" 2 | description: "Suggest an idea for a new Expo Config Plugin." 3 | labels: enhancement 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: "This repo is used for publishing out-of-tree plugins that should eventually be upstreamed in a particular package. If the plugin is a utility or used to improve some particular workflow i.e. updates version numbers, than it's probably better suited for a personal repo or utility package." 8 | - type: input 9 | attributes: 10 | label: Library 11 | description: What package does this Config Plugin configure. 12 | placeholder: URL to a React Native package. 13 | validations: 14 | required: true 15 | - type: textarea 16 | attributes: 17 | label: Summary 18 | description: Add some info on why this integration is important. 19 | - type: textarea 20 | attributes: 21 | label: Any existing examples? 22 | placeholder: Have you already created a local plugin for the requested library? 23 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE: -------------------------------------------------------------------------------- 1 | 7 | 8 | # Why 9 | 10 | 13 | 14 | # How 15 | 16 | 19 | 20 | # Test Plan 21 | 22 | 25 | -------------------------------------------------------------------------------- /.github/workflows/lint-md.yml: -------------------------------------------------------------------------------- 1 | name: Check Markdown links 2 | on: 3 | workflow_dispatch: {} 4 | push: 5 | branches: [main] 6 | paths: 7 | - .github/workflows/lint-md.yml 8 | - "**.md" 9 | pull_request: 10 | paths: 11 | - .github/workflows/lint-md.yml 12 | - "**.md" 13 | 14 | jobs: 15 | lint-md: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v2 19 | - run: yarn install --frozen-lockfile --check-files 20 | - run: npx remark --use validate-links . .github 21 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test Packages 2 | on: 3 | push: 4 | branches: [main] 5 | pull_request: 6 | types: [opened, synchronize] 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | node: ["18"] 14 | name: Build with Node ${{ matrix.node }} 15 | steps: 16 | - uses: actions/checkout@v2 17 | with: 18 | fetch-depth: 1 19 | - name: Setup node 20 | uses: actions/setup-node@v1 21 | with: 22 | node-version: ${{ matrix.node }} 23 | - run: yarn install --frozen-lockfile --check-files 24 | - run: yarn lerna run prepare --stream 25 | - uses: actions/cache@v4 26 | with: 27 | path: "*" 28 | key: v2-${{ github.sha }}-${{ matrix.node }} 29 | test: 30 | runs-on: ubuntu-latest 31 | needs: build 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | node: ["18"] 36 | package: [ 37 | # Manually add packages here 38 | ios-stickers, 39 | react-native-blob-util, 40 | react-native-branch, 41 | react-native-siri-shortcut, 42 | react-native-pdf, 43 | ] 44 | name: Test ${{ matrix.package }} on Node ${{ matrix.node }} 45 | steps: 46 | - uses: actions/cache@v4 47 | with: 48 | path: "*" 49 | key: v2-${{ github.sha }}-${{ matrix.node }} 50 | - name: Set up Node 51 | uses: actions/setup-node@v1 52 | with: 53 | node-version: ${{ matrix.node }} 54 | - name: Lint ${{ matrix.package }} 55 | run: yarn lint --max-warnings 0 56 | working-directory: packages/${{ matrix.package }} 57 | - name: Test ${{ matrix.package }} 58 | run: yarn test 59 | working-directory: packages/${{ matrix.package }} 60 | env: 61 | CI: true 62 | EXPO_DEBUG: true 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Expo 2 | .expo 3 | __generated__ 4 | web-build 5 | 6 | # macOS 7 | .DS_Store 8 | 9 | # Node 10 | node_modules 11 | npm-debug.log 12 | yarn-error.log 13 | 14 | # Ruby 15 | .direnv 16 | 17 | # Emacs 18 | *~ 19 | 20 | # Vim 21 | .*.swp 22 | .*.swo 23 | .*.swn 24 | .*.swm 25 | 26 | # Sublime Text 27 | *.sublime-project 28 | *.sublime-workspace 29 | 30 | # Xcode 31 | *.pbxuser 32 | !default.pbxuser 33 | *.xccheckout 34 | *.xcscmblueprint 35 | xcuserdata 36 | 37 | # Android Studio 38 | *.iml 39 | .gradle 40 | .idea/libraries 41 | .idea/workspace.xml 42 | .idea/gradle.xml 43 | .idea/misc.xml 44 | .idea/modules.xml 45 | .idea/vcs.xml 46 | 47 | # Eclipse 48 | .project 49 | .settings 50 | 51 | # VSCode 52 | .history/ 53 | 54 | # Ignore build folders 55 | 56 | packages/*/build/** 57 | packages/*/plugin/build/** 58 | packages/@*/*/build/** 59 | 60 | 61 | # App native folders 62 | 63 | apps/*/ios/* 64 | apps/*/android/* 65 | apps/*/web-build/* 66 | apps/*/dist/* -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Expo Config Plugins 2 | 3 | ## Submitting a pull request 4 | 5 | To submit a pull request: 6 | 7 | 1. Fork the [repository](https://github.com/expo/config-plugins) and create a feature branch. (Existing contributors can create feature branches without forking. Prefix the branch name with `@your-github-username/`.) 8 | 2. Run `yarn` in the root directory to generate the build files. 9 | 3. Use [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) including in the PR title. 10 | 4. Fill out the entire PR template. Ensure your code is tested locally and has continuous tests in CI. 11 | 5. Make sure all tests pass on GitHub Actions. 12 | 6. Wait for a review and adjust the code if necessary. 13 | 14 | ## Creating a plugin 15 | 16 | - Plugins can be generated by running `yarn gen`. 17 | - Add plugins to the example in [`apps/app`](/apps/app/package.json) to test them. 18 | - The example app should always stay in a state of regeneration. 19 | 20 | Be sure to run the following scripts in the **root directory** to update automation tools: 21 | 22 | - Update dependabot: `yarn update-dependabot-config` 23 | - Update the issue template: `yarn update-issue-template` 24 | 25 | ## Publishing a release 26 | 27 | All publishing should be handled automatically whenever code is merged to `main`. 28 | -------------------------------------------------------------------------------- /apps/app/.gitignore: -------------------------------------------------------------------------------- 1 | /scripts/start.command 2 | /artifacts -------------------------------------------------------------------------------- /apps/app/App.tsx: -------------------------------------------------------------------------------- 1 | export { default } from "./src/android-jsc-intl/App"; 2 | // export { default } from "./src/react-native-adjust/App"; 3 | -------------------------------------------------------------------------------- /apps/app/app.config.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ config }) => { 2 | if (!config.extra) config.extra = {}; 3 | // Expose CI env variables to the app 4 | config.extra.CI = process.env.CI; 5 | return config; 6 | }; 7 | -------------------------------------------------------------------------------- /apps/app/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "app", 4 | "slug": "app", 5 | "version": "1.0.0", 6 | "orientation": "portrait", 7 | "icon": "https://github.com/expo.png", 8 | "splash": { 9 | "image": "./assets/splash.png", 10 | "resizeMode": "contain", 11 | "backgroundColor": "#ffffff" 12 | }, 13 | "updates": { 14 | "fallbackToCacheTimeout": 0 15 | }, 16 | "assetBundlePatterns": ["**/*"], 17 | "ios": { 18 | "supportsTablet": true, 19 | "bundleIdentifier": "dev.bacon.app" 20 | }, 21 | "android": { 22 | "adaptiveIcon": { 23 | "foregroundImage": "./assets/adaptive-icon.png", 24 | "backgroundColor": "#FFFFFF" 25 | }, 26 | "package": "com.bacon.app" 27 | }, 28 | "web": { 29 | "favicon": "./assets/favicon.png" 30 | }, 31 | "plugins": [ 32 | "@config-plugins/react-native-adjust", 33 | "@config-plugins/react-native-callkeep", 34 | "@config-plugins/android-jsc-intl", 35 | "expo-localization" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /apps/app/assets/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/expo/config-plugins/566f54e785147d88cb4c98490c3e536ee7ef3001/apps/app/assets/adaptive-icon.png -------------------------------------------------------------------------------- /apps/app/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/expo/config-plugins/566f54e785147d88cb4c98490c3e536ee7ef3001/apps/app/assets/favicon.png -------------------------------------------------------------------------------- /apps/app/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/expo/config-plugins/566f54e785147d88cb4c98490c3e536ee7ef3001/apps/app/assets/icon.png -------------------------------------------------------------------------------- /apps/app/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/expo/config-plugins/566f54e785147d88cb4c98490c3e536ee7ef3001/apps/app/assets/splash.png -------------------------------------------------------------------------------- /apps/app/meta/screenshots/android/en-US/APP_EMULATOR-5554 (PIXEL_6_PRO_API_33)_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/expo/config-plugins/566f54e785147d88cb4c98490c3e536ee7ef3001/apps/app/meta/screenshots/android/en-US/APP_EMULATOR-5554 (PIXEL_6_PRO_API_33)_0.png -------------------------------------------------------------------------------- /apps/app/meta/screenshots/android/nl-NL/APP_EMULATOR-5554 (PIXEL_6_PRO_API_33)_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/expo/config-plugins/566f54e785147d88cb4c98490c3e536ee7ef3001/apps/app/meta/screenshots/android/nl-NL/APP_EMULATOR-5554 (PIXEL_6_PRO_API_33)_0.png -------------------------------------------------------------------------------- /apps/app/meta/screenshots/android/zh-CN/APP_EMULATOR-5554 (PIXEL_6_PRO_API_33)_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/expo/config-plugins/566f54e785147d88cb4c98490c3e536ee7ef3001/apps/app/meta/screenshots/android/zh-CN/APP_EMULATOR-5554 (PIXEL_6_PRO_API_33)_0.png -------------------------------------------------------------------------------- /apps/app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@expo/app", 3 | "main": "./index.js", 4 | "version": "1.0.0", 5 | "private": true, 6 | "scripts": { 7 | "start": "expo start --dev-client", 8 | "ios": "expo run:ios", 9 | "android": "expo run:android" 10 | }, 11 | "dependencies": { 12 | "@config-plugins/android-jsc-intl": "*", 13 | "@config-plugins/react-native-adjust": "*", 14 | "@config-plugins/react-native-callkeep": "*", 15 | "expo": "~53", 16 | "expo-localization": "~16.1.5", 17 | "expo-splash-screen": "~0.30.7", 18 | "fbjs": "^0.8.18", 19 | "i18n-js": "^3.8.0", 20 | "luxon": "^1.27.0", 21 | "react": "19.0.0", 22 | "react-native": "0.79.2", 23 | "react-native-adjust": "^5.1.0", 24 | "react-native-callkeep": "^4.3.16", 25 | "react-native-safe-area-context": "5.3.0" 26 | }, 27 | "devDependencies": { 28 | "@babel/plugin-syntax-jsx": "^7.16.0", 29 | "@types/jest": "^29.4.0", 30 | "@types/luxon": "^1.27.1", 31 | "babel-jest": "^29.5.0", 32 | "jest": "~29.7.0", 33 | "jest-circus": "^29.5.0", 34 | "ts-jest": "^29.0.5", 35 | "typescript": "~5.8.3" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /apps/app/scripts/build-detox-ios.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This script wraps the xcodebuild command and exits with non-zero if the build fails. 4 | # 5 | # This ensures that CI fails on the correct step instead of attempting to run Detox tests without a 6 | # build. 7 | 8 | set -eu 9 | 10 | iosName=$1 11 | # Debug or Release 12 | configuration=${3:-"Debug"} 13 | # YES or NO 14 | UseModernBuildSystem=${3:-"NO"} 15 | 16 | xcodebuild \ 17 | -workspace ios/$iosName.xcworkspace \ 18 | -scheme $iosName \ 19 | -configuration "$configuration" \ 20 | -sdk iphonesimulator \ 21 | -derivedDataPath "ios/build" \ 22 | -UseModernBuildSystem="$UseModernBuildSystem" 2>&1 | npx excpretty ./ 23 | 24 | if [ "${PIPESTATUS[0]}" -ne "0" ]; then 25 | echo 'Build Failed' 26 | set +e 27 | exit 1 28 | fi 29 | 30 | echo 'Build Succeeded' 31 | -------------------------------------------------------------------------------- /apps/app/scripts/start-metro.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | port=${1:-8081} 4 | 5 | PACKAGER_STATUS_URL="http://localhost:${port}/status" 6 | # Check if Metro is running 7 | STATUS=$(curl --silent $PACKAGER_STATUS_URL) 8 | 9 | if [ "${STATUS}" = "packager-status:running" ]; then 10 | echo " ✅ Verified Metro Bundler is running." 11 | else 12 | echo " ⚠️ Starting Metro Bundler..." 13 | # yarn run clear-metro 14 | # yarn start 15 | 16 | commandFile=$(dirname "$0")/start.command 17 | cat > ${commandFile} << EOF 18 | cd "\$(dirname "\$0")/.." 19 | # Run 'npx expo start --help' to get more parameters 20 | yarn start --port ${port} 21 | EOF 22 | # execute the file in a new command line window 23 | chmod 0755 ${commandFile} 24 | case "$OSTYPE" in 25 | darwin*) 26 | open ${commandFile} 27 | ;; 28 | *) 29 | # Spawns a new terminal window and detaches it 30 | # Assuming the non-standard variable $TERMINAL is set 31 | if [ -z "$TERMINAL" ]; then 32 | echo "Could not open a new terminal window. Please make sure to export TERMINAL='your-terminal'" 33 | else 34 | nohup "$TERMINAL" -e "${commandFile}" /dev/null 2>&1 & 35 | fi 36 | ;; 37 | esac 38 | 39 | fi -------------------------------------------------------------------------------- /apps/app/src/android-jsc-intl/App.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Text, View } from "react-native"; 3 | import { DateTime } from "luxon"; 4 | 5 | const currentDate = DateTime.fromObject({ 6 | locale: "en-US", 7 | zone: "America/New_York", 8 | }); 9 | 10 | export default function App() { 11 | return ( 12 | 20 | 21 | Intl support for Android, without Hermes 🤖 22 | 23 | 24 | {currentDate.toISO()} 25 | 26 | 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /apps/app/src/react-native-adjust/App.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { SafeAreaView, Text, StyleSheet } from "react-native"; 3 | import { Adjust, AdjustConfig } from "react-native-adjust"; 4 | 5 | export default function App() { 6 | React.useEffect(() => { 7 | const adjustConfig = new AdjustConfig( 8 | "APP_TOKEN", 9 | AdjustConfig.EnvironmentSandbox 10 | ); 11 | Adjust.enable(); 12 | }, []); 13 | 14 | return ( 15 | 16 | Adjust SDK 17 | 18 | ); 19 | } 20 | 21 | const styles = StyleSheet.create({ 22 | container: { 23 | flex: 1, 24 | justifyContent: "center", 25 | alignItems: "center", 26 | }, 27 | }); 28 | -------------------------------------------------------------------------------- /apps/app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": {}, 3 | "extends": "expo/tsconfig.base" 4 | } 5 | -------------------------------------------------------------------------------- /apps/apple-settings/app.config.ts: -------------------------------------------------------------------------------- 1 | import withAppleSettings, { 2 | ChildPane, 3 | Group, 4 | RadioGroup, 5 | Slider, 6 | Switch, 7 | TextField, 8 | Title, 9 | } from "@config-plugins/apple-settings"; 10 | import { MultiValue } from "@config-plugins/apple-settings/build/models"; 11 | import { ConfigContext, ExpoConfig } from "expo/config"; 12 | import path from "node:path"; 13 | 14 | const folderName = path.basename(__dirname); 15 | const cleanName = folderName.replace(/[_\s-]/g, ""); 16 | const appId = "dev.bacon." + cleanName; 17 | 18 | function withWhiteLabel(config: Partial) { 19 | if (!config.extra) config.extra = {}; 20 | // Expose CI env variables to the app 21 | config.extra.CI = process.env.CI; 22 | 23 | if (!config.ios) config.ios = {}; 24 | config.ios.bundleIdentifier = appId; 25 | if (!config.android) config.android = {}; 26 | config.android.package = appId; 27 | 28 | return config; 29 | } 30 | 31 | module.exports = ({ config }: ConfigContext): Partial => { 32 | config = withWhiteLabel(config); 33 | 34 | config = withAppleSettings(config as ExpoConfig, { 35 | // The name of the .plist file to generate. Root is the default and must be provided. 36 | Root: { 37 | // The locales object is optional. If provided, it will be used to generate the localized .strings files. 38 | locales: { 39 | // The Apple locale code. This will be used to generate the .strings file. 40 | en: { 41 | // Name of the localized key. 42 | Name: "Text Field", 43 | }, 44 | }, 45 | // The page object is required. It will be used to generate the .plist file. 46 | // The contents will be converted directly to plist. 47 | page: { 48 | // The `PreferenceSpecifiers` defines the UI elements to generate. 49 | PreferenceSpecifiers: [ 50 | Title({ 51 | title: "Title", 52 | value: "Default Title", 53 | key: "title_preference", 54 | }), 55 | // Helper models can be used to generate the UI elements using 56 | // an API that's similar to React Native. 57 | TextField({ 58 | title: "Name", 59 | key: "name_preference", 60 | value: "", 61 | keyboardType: "Alphabet", 62 | autoCapitalize: "None", 63 | autoCorrect: "No", 64 | }), 65 | Switch({ 66 | title: "Enabled", 67 | key: "enabled_preference", 68 | value: true, 69 | }), 70 | Slider({ 71 | key: "slider_preference", 72 | value: 0.5, 73 | }), 74 | // Broken https://forums.developer.apple.com/forums/thread/764519 75 | // RadioGroup({ 76 | // value: "option1", 77 | // key: "radio_preference", 78 | // items: [ 79 | // { 80 | // title: "Option 1", 81 | // value: "option1", 82 | // }, 83 | 84 | // { 85 | // title: "Option 2", 86 | // value: "option2", 87 | // }, 88 | // ], 89 | // }), 90 | // MultiValue({ 91 | // title: "Multi Value", 92 | // key: "multi_value_preference", 93 | // value: "alpha", 94 | // items: [ 95 | // { 96 | // title: "Alpha", 97 | // value: "alpha", 98 | // short: "α", 99 | // }, 100 | // { 101 | // title: "Beta", 102 | // value: "beta", 103 | // short: "β", 104 | // }, 105 | // { 106 | // title: "Delta", 107 | // value: "delta", 108 | // short: "Δ", 109 | // }, 110 | // { 111 | // title: "Omega", 112 | // value: "omega", 113 | // short: "Ω", 114 | // }, 115 | // ], 116 | // }), 117 | ], 118 | }, 119 | }, 120 | }); 121 | 122 | return config; 123 | }; 124 | -------------------------------------------------------------------------------- /apps/apple-settings/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "apple-settings", 4 | "icon": "https://github.com/expo.png", 5 | "platforms": ["ios"], 6 | "plugins": [["expo-build-properties", { "ios": { "ccacheEnabled": true } }]] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /apps/apple-settings/index.js: -------------------------------------------------------------------------------- 1 | import { registerRootComponent } from "expo"; 2 | 3 | import App from "./src/App"; 4 | 5 | registerRootComponent(App); 6 | -------------------------------------------------------------------------------- /apps/apple-settings/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@config-plugins-app/apple-settings", 3 | "main": "./index.js", 4 | "version": "1.0.0", 5 | "scripts": { 6 | "start": "expo start --dev-client", 7 | "ios": "expo run:ios", 8 | "android": "expo run:android" 9 | }, 10 | "dependencies": { 11 | "@config-plugins/apple-settings": "*", 12 | "@react-native-community/slider": "4.5.6", 13 | "@react-native-picker/picker": "2.11.0", 14 | "expo": "~53", 15 | "expo-splash-screen": "~0.30.7", 16 | "react": "19.0.0", 17 | "react-native": "0.79.2" 18 | }, 19 | "private": true 20 | } 21 | -------------------------------------------------------------------------------- /apps/apple-settings/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Button, Linking, StyleSheet, View } from "react-native"; 3 | 4 | import { 5 | SettingsRadioGroup, 6 | SettingsSlider, 7 | SettingsSwitch, 8 | SettingsTextInput, 9 | SettingsTitle, 10 | } from "./SettingsViews"; 11 | 12 | const App = () => { 13 | return ( 14 | 15 | {/* */} 16 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |