rnrepo

repository·main·Indexed 19 days ago

https://github.com/software-mansion/rnrepo

A build system for React Native libraries that improves native build times by pre-building and distributing community library artifacts via a hosted Maven repository. It targets projects using The New Architecture and provides tools for iOS via a CocoaPods plugin and Android via a Gradle plugin to substitute source dependencies with pre-compiled binaries.

Tokens
12.4K
Snippets
49
Records
74
Agent score
64%

What's inside rnrepo

  1. How the build tracking lifecycle works

    main

    The database acts as the source of truth between the Scheduler and the Publisher:

    • Scheduler: Uses isBuildAlreadyScheduled to check if a build exists. If not (or if retry=true), it uses createBuildRecord to schedule a new one.
    • Publisher: Once a build finishes, it uses updateBuildStatus to set the status to completed or failed.

    Builds are automatically skipped if a record already exists with retry=false.

  2. How @rnrepo/expo-config-plugin works

    main

    The plugin automates the modification of your Android Gradle configuration to enable RNRepo prebuilds. It performs three main actions:

    1. Add RNRepo Plugin Classpath: Adds the prebuilds plugin to your project dependencies.
    2. Configure Maven Repository: Adds the RNRepo Maven repository to both buildscript and allprojects.
    3. Apply Plugin: Applies the prebuilds plugin to your app's build.gradle file.
  3. Understand RNRepo limitations and fallback behavior

    main

    RNRepo provides prebuilt artifacts for specific library and React Native version combinations. If a match is not found, the system automatically falls back to building from source.

    Key Limitations:

    • Local Modifications: If you use patch-package or custom build-time feature flags on React Native core or libraries, prebuilt artifacts may be incompatible. You must explicitly opt out of prebuilds for these libraries.
    • Supported Versions: Supports all React Native versions from 0.80.0 onwards, plus specific patch versions for 0.77.3, 0.78.3, and 0.79.7. Unsupported versions trigger a source build fallback.
    • C++ Dependencies: Libraries requiring other C++-level compile-time dependencies (e.g., those using Nitro modules) cannot be pre-compiled.
    • Codegen: Most Android libraries still require a local codegen step during the app build process.
    • Worklets on Android (Expo SDK 55+): In debug builds, react-native-worklets and its C++ dependents (like react-native-reanimated) fall back to source builds due to how expo-modules-core links to libworklets.so. Release builds are unaffected and use prebuilt artifacts.

    Tip: To debug why a package fell back to source, run your build with the --info flag and search for RNRepo in the logs.

  4. How RNRepo distributes and secures artifacts

    main

    RNRepo automates the compilation and distribution of React Native library binaries:

    1. Manifests: Uses libraries.json (vetted libraries/versions) and react-native-versions.json (matching RN versions).
    2. Automated Builds: GitHub Workflows compile Android (AAR/AAB) and iOS (xcframework) artifacts upon library or RN updates.
    3. Distribution: Artifacts are hosted at https://packages.rnrepo.org/releases and served via standard Maven metadata, allowing seamless consumption by Gradle and CocoaPods.
    4. Security Model:
      • Isolation: Builds run in locked-down GitHub-hosted environments.
      • Transparency: Every artifact links to its specific workflow run and logs for auditing.
      • Integrity: Artifacts are GPG-signed and checksums are served via packages.rnrepo.org.
  5. How the CocoaPods RNRepo Plugin works

    main

    The plugin automates the substitution of React Native source dependencies with pre-compiled xcframeworks from https://packages.rnrepo.org/ through three lifecycle stages:

    1. Pre-Install Hook: Scans dependencies, downloads both Debug and Release xcframeworks, and extracts them into node_modules/{package-name}/.rnrepo-cache/.
    2. Dependency Resolution: Modifies pod specifications to point vendored_frameworks to a .rnrepo-cache/Current/ symlink.
    3. Post-Install Hook: Injects build phase scripts into pod targets. These scripts create a Current symlink pointing to either Debug or Release based on the $CONFIGURATION environment variable at build time.

    Framework Storage Structure: Frameworks are stored within the package directory as follows:

    node_modules/
      └── {package-name}/
          └── .rnrepo-cache/
              ├── Debug/
              │   └── {package-name}.xcframework/
              ├── Release/
              │   └── {package-name}.xcframework/
              └── Current/  (symlink pointing to Debug or Release)
  6. Install RNRepo for Expo Prebuild (CNG)

    main

    If you use Expo Continuous Code Generation (CNG) where native directories are generated via expo prebuild, use the @rnrepo/expo-config-plugin to automate configuration.

    1. Install the plugin:

      npx expo install @rnrepo/expo-config-plugin

      Note: In hoisted node_modules, you may need to install @rnrepo/build-tools manually using npx expo install @rnrepo/build-tools.

    2. Add the plugin to your app.config.ts, app.json, or app.config.js:

      {
        "expo": {
          "plugins": ["@rnrepo/expo-config-plugin"]
        }
      }
    3. Expo Fingerprint: If using Expo Fingerprint (e.g., in EAS builds), add the RNRepo cache to your .fingerprintignore file to prevent it from being tracked:

      **/.rnrepo-cache/**/*
    npx expo install @rnrepo/expo-config-plugin
  7. Reload RNRepo dependencies and cache

    main

    To force the RNRepo plugin to re-download all dependencies, use the --refresh-dependencies flag with Gradle:

    ./gradlew :app:assembleDebug --refresh-dependencies

    If you need to manually clear the RNRepo cache, delete the following directories from your Gradle cache:

    • ~/.gradle/caches/modules-2/metadata-2.107/descriptors/org.rnrepo.public
    • ~/.gradle/caches/modules-2/files-2.1/org.rnrepo.public
    • ~/.gradle/caches/modules-2/metadata-2.107/descriptors/org.rnrepo.tools
    • ~/.gradle/caches/modules-2/files-2.1/org.rnrepo.tools
    ./gradlew :app:assembleDebug --refresh-dependencies
  8. Configure Android for RNRepo

    main

    To enable RNRepo on Android, you must configure both your root android/build.gradle and your app-level android/app/build.gradle files.

    1. In android/build.gradle, add the rnrepoDir definition to the buildscript.dependencies block and include the prebuilds-plugin.jar.
    2. In android/app/build.gradle, apply the org.rnrepo.tools.prebuilds-plugin plugin.
    // android/build.gradle
    buildscript {
       dependencies {
          ... 
         def rnrepoDir = new File(
           providers.exec {
             workingDir(rootDir)
             commandLine("node", "--print", "require.resolve('@rnrepo/build-tools/package.json')")
           }.standardOutput.asText.get().trim()
         ).getParentFile().absolutePath
         classpath fileTree(dir: "${rnrepoDir}/gradle-plugin/build/libs", include: ["prebuilds-plugin.jar"])
       }
    }
    
    apply plugin: "com.facebook.react.rootproject"
    
    // android/app/build.gradle
    apply plugin: "com.facebook.react"
    apply plugin: "org.rnrepo.tools.prebuilds-plugin"
  9. Set up Supabase CLI for RNRepo

    main

    To manage your database via the Supabase CLI within the packages/database directory, follow these steps:

    1. Install the CLI (globally or locally):

      npm install -g supabase
    2. Link your project using your project reference:

      cd packages/database
      supabase link --project-ref your-project-ref
    3. Push migrations:

      supabase db push
    npm install -g supabase
    cd packages/database
    supabase link --project-ref your-project-ref
    supabase db push