react-native-keys

repository·main·Indexed 18 days ago

https://github.com/numandev1/react-native-keys

A high-performance React Native package for managing environment variables across development, staging, and production. It distinguishes between 'public' keys, stored natively for non-sensitive identifiers, and 'secure' keys, which are encrypted to prevent extraction via decompilation. Supports Managed Expo, New Architecture (TurboModules and Fabric), and provides native access for iOS (Info.plist) and Android (BuildConfig/JNI).

Tokens
8.2K
Snippets
36
Records
41
Agent score
62%

What's inside react-native-keys

  1. How secure and public keys differ

    main

    The library distinguishes between two types of environment variables:

    • secure: These are protected with high-level encryption. Use this for sensitive third-party client-side API keys (e.g., Google Maps, Branch.io).
    • public: These are stored on the native side (Java/Objective-C) and are susceptible to decompilation. Use this for non-sensitive identifiers like Bundle Id, Package Id, or App Name required by AndroidManifest.xml.
  2. Migrate from react-native-config to react-native-keys

    main

    When migrating from react-native-config to react-native-keys, you must transition from .env files to JSON-based key files that distinguish between secure and public keys. You also need to update your Android Gradle configuration, iOS Pre-actions, and both Native and JavaScript access patterns.

    1. Data Format Migration

    Instead of a flat .env file, use a JSON structure. Keys intended for sensitive use should be placed in the secure object, while non-sensitive keys go in the public object.

    Example Transformation:

    Old (.env.development):

    BASE_URL=https://www.example.com
    APP_NAME=Example
    GOOGLE_API=ABCDEF
    BRANCH_API=ABCDEF
    PACKAGE_ID=com.example.rnkeys.dev

    New (keys.development.json):

    {
      "secure": { 
        "GOOGLE_API": "ABCD", 
        "BRANCH_API": "ABCDEF" 
      },
      "public": {
        "APP_NAME": "dev RNKEYS",
        "PACKAGE_ID": "com.example.rnkeys.dev"
      } 
    }

    2. Android Configuration

    Update build.gradle plugin application: In android/app/build.gradle, replace the react-native-config plugin with the react-native-keys plugin:

    // Remove this:
    // apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
    
    // Add this:
    apply from: project(':react-native-keys').projectDir.getPath() + "/RNKeys.gradle"

    Update key file mapping: In android/app/build.gradle, change project.ext.envConfigFiles to project.ext.keyFiles and point to your JSON files:

    project.ext.keyFiles = [
      debug: "keys.development.json",
      release: "keys.staging.json",
      release: "keys.json",
    ]

    Update Native Java Access: For secure keys, use the KeysModule.getSecureFor static method instead of accessing BuildConfig directly.

    // Old way:
    // BuildConfig.GOOGLE_MAPS_API_KEY
    
    // New way:
    import static com.reactnativekeysjsi.KeysModule.getSecureFor;
    
    getSecureFor("GOOGLE_MAPS_API_KEY")
    BuildConfig.PACKAGE_ID

    Update Gradle Configuration Access: If reading keys within your Gradle files (e.g., defaultConfig), use project.keys.get():

    // Old way:
    // applicationId project.env.get("APP_ID")
    
    // New way:
    defaultConfig {
      applicationId project.keys.get("APP_ID")
    }

    3. iOS Configuration

    Update Pre-actions Script: In Xcode, go to Edit scheme... -> Build -> Pre-actions, click +, and select New Run Script Action. Update the script to export the KEYSFILE and run the new keysIOS.js script:

    export KEYSFILE=keys.development.json
    "${SRCROOT}/../node_modules/react-native-keys/keysIOS.js"

    Update Native Objective-C Access: Import Keys.h and use secureFor: for sensitive keys and publicFor: for non-sensitive keys.

    // Old way:
    // #import "RNCConfig.h"
    // NSString *googleMapApiKey = [RNCConfig envFor:@
    

    // Example of the new JSON structure { "secure": { "GOOGLE_API": "ABCD", "BRANCH_API": "ABCDEF" }, "public": { "APP_NAME": "dev RNKEYS", "PACKAGE_ID": "com.example.rnkeys.dev" } }

  3. Manage Different Environments (Keys Files)

    main

    You can maintain different configurations in files like keys.staging.json or keys.production.json. By default, the library looks for keys.development.json.

    CLI Usage

    Pass the KEYSFILE environment variable when running commands:

    # Bash
    KEYSFILE=keys.staging.json react-native run-ios
    
    # Windows
    SET KEYSFILE=keys.staging.json && react-native run-ios
    
    # PowerShell
    env:KEYSFILE="keys.staging.json"; react-native run-ios

    Android Gradle

    cd android && KEYSFILE=keys.staging.json ./gradlew assembleRelease

    iOS Schemes

    The recommended approach for iOS is to create one Xcode Scheme per environment. In the scheme's Pre-actions script, you can set specific variables:

    # Choose env file for the build
    export KEYSFILE=keys.production.json
    
    # Or use specific variables for debug vs release
    export DEBUG_KEYSFILE=keys.debug.json
    export RELEASE_KEYSFILE=keys.staging.json
    
    "${SRCROOT}/../node_modules/react-native-keys/keysIOS.js"
    KEYSFILE=keys.staging.json react-native run-ios
  4. Migrate JavaScript key access to react-native-keys

    main

    When moving from react-native-config to react-native-keys in your JavaScript/TypeScript code, you must switch the import source and use the secureFor method for sensitive keys.

    Old Pattern:

    import Config from "react-native-config";
    const apiKey = Config.GOOGLE_MAPS_API_KEY;

    New Pattern:

    import Keys from 'react-native-keys';
    
    // For secure keys:
    const apiKey = Keys.secureFor('GOOGLE_MAPS_API_KEY');
    
    // For public keys:
    const packageName = Keys.PACKAGE_ID;
    import Keys from 'react-native-keys';
    
    Keys.secureFor('GOOGLE_MAPS_API_KEY');
    Keys.PACKAGE_ID;
  5. Install and Setup react-native-keys

    main

    To install the package, use yarn:

    yarn add react-native-keys

    For React Native versions 0.60 or greater, autolinking is available. For earlier versions, you must manually link the module using:

    react-native link react-native-keys

    If you are using CocoaPods on iOS, ensure you install the pods:

    (cd ios; pod install)
  6. Configure Android Native Setup

    main

    For Android, you must perform manual linking and configuration.

    1. Manual Linking:

      • android/settings.gradle:
        include ':react-native-keys'
        project(':react-native-keys').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-keys/android')
      • android/app/build.gradle:
        dependencies {
          implementation project(':react-native-keys')
        }
      • MainApplication.java: Import and add KeysPackage to the getPackages() list.
    2. Mandatory Step (Environment Mapping): In android/app/build.gradle, define a map associating build types (in lowercase) with their respective JSON key files. This must be done before the apply from call:

      project.ext.keyFiles = [
        debug: "keys.development.json",
        release: "keys.staging.json",
      ]
      
      apply from: project(':react-native-keys').projectDir.getPath() + "/RNKeys.gradle"
    project.ext.keyFiles = [
      debug: "keys.development.json",
      release: "keys.staging.json",
    ]
    
    apply from: project(':react-native-keys').projectDir.getPath() + "/RNKeys.gradle"