Podcast Feature: “Shrink Your React Native App With ProGuard”

One thing we can get wrong (as developers) is we think about the tools we know. We don’t often think about the parts and pieces that make your native app faster”. This quote about ProGuard was the subject of episode 239 of React Native Radio, “Shrink Your App With ProGuard”. Our head ProGuard engineer, @james Hamilton, was invited onto their podcast to discuss a wide variety of ProGuard topics and answer some questions as well.

It begins with James and the hosts Jamon Holmgren and Mazen Chami simplifying what ProGuard is, what it does, and how it relates to tree-shaking. Other themes include: How ProGuard is used beyond Android, comparing ProGuard to R8, how Guardsquare grew from ProGuard, and whether you can rely on ProGuard for security protection (spoiler: you cannot!)…

Ever wonder what calling by reflection means or what code virtualization is? James explains about half way through the podcast. Then they dive into ProGuard Playground where Mazen encourages, “It’s something every developer should play with once they have their APK”. Finally the team tackles DexGuard, how it relates to ProGuard, and how the mutli-layered approach makes it a reliable security solution for hardening your app.

Using ProGuard in a React Native project

As mentioned in the podcast, R8 is now the default shrinker in the Android build chain which means that if you set enableProguardInReleaseBuilds (as appears in the usual React Native Gradle template) to true you will enable R8. R8 is compatible with ProGuard rules so you can still take advantage of tools like the ProGuard Playground to help you craft your rules.

You can enable ProGuard instead of R8 by doing the following:

  1. Add the ProGuard Gradle Plugin as a dependency in your top-level build.gradle buildscript section
 dependencies {
        classpath("com.android.tools.build:gradle:7.0.4")
        classpath("com.facebook.react:react-native-gradle-plugin")
        classpath("de.undercouch:gradle-download-task:4.1.2")
        // For the ProGuard Gradle Plugin
        classpath("com.guardsquare:proguard-gradle:7.1.0")
    }  
  1. Apply the ProGuard Gradle plugin in your app-level build.gradle file
apply plugin: "com.android.application"
apply plugin: "com.guardsquare.proguard"
  1. Set enableProguardInReleaseBuilds to false in your app-level build.gradle file or set minifyEnabled false in the variants block.
def enableProguardInReleaseBuilds = false
android {
    ...
    buildTypes {
        debug {
            signingConfig signingConfigs.debug
        }
        release {
            //minifyEnabled enableProguardInReleaseBuilds
            //proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
            minifyEnabled false
        }
    }
}
  1. Configuration the ProGuard Gradle plugin for specific variants by adding a proguard block to your app-level build.gradle file:
proguard {
   configurations {
      release {
         defaultConfiguration 'proguard-android-optimize.txt'
         configuration 'proguard-rules.pro'
      }
  }
}

For more information, see the ProGuard manual about setting up the ProGuard Gradle Plugin or ask a question here on the community.

Have any questions that weren’t addressed in the podcast? Let us know in the comments below.