[ Web Proxy ]
URL:
Viewing: https://developer.android.com/topic/performance/app-optimization/library-optimization [Back]  [Original]

Optimization for library authors  |  App quality  |  Android Developers Skip to main content
Essentials Design & Plan Develop Google Play Blog
Search:
Android Studio
Android Developers [Android Developers]

Optimization for library authors Stay organized with collections Save and categorize content based on your preferences.

As a library author, you must ensure that app developers can easily incorporate your library into their app while maintaining a high-quality end-user experience. This means your library must be compatible with Android optimization (R8) without requiring additional setup from the developeror document that the library might be inappropriate for usage on Android. It is crucial that libraries intended for use on Android must not prevent important app optimizations and adhere to additional optimization requirements.

This documentation is targeted at developers of published libraries, but might also be useful for developers of internal library modules in a large, modularized app.

If you're an app developer and want to learn about optimizing your Android app, see Enable app optimization. To learn about which libraries are appropriate to use, see Choose libraries wisely.

Understand keep rule types

There are two distinct types of keep rules that you can have in libraries:

Optimization requirements and guidelines

The R8 configuration in libraries has a global impact on the consuming app's final binary size and performance. Apart from the general keep rule best practices, library authors must adhere to specific requirements, and consider additional guidelines.

Adhere to optimization requirements

Inefficiency in libraries is a major contributor to app bloat, wasted memory, slow startups, and ANRs (Application Not Responding errors). Libraries must avoid violating the following requirements to avoid significantly reducing app quality, and user experience.

Additional recommendations

Apart from the optimization requirements, the following are additional recommendations.

When reflection is okay

If you must use reflection, you should only reflect into either of the following:

Using reflection in this way limits the runtime cost, and enables writing targeted consumer keep rules.

This specific and targeted form of reflection is a pattern you can see across both the Android framework (for example, during system resource loading) and AndroidX libraries (for example when constructing WorkManager ListenableWorkers, or RoomDatabases). By contrast, the open ended reflection of Gson isn't appropriate for usage in Android apps.

Common misconceptions

A few common misconceptions might lead you to configure R8 incorrectly. These include the following:

Configure rule packaging

To ensure your consumer keep rules are applied correctly, you must package them appropriately depending on your library format.

AAR libraries

To add consumer rules for an AAR library, use the consumerProguardFiles option in the Android library module's build script. For more information, see our guidance on creating library modules.

Kotlin

android {
    defaultConfig {
        consumerProguardFiles("consumer-proguard-rules.pro")
    }
    ...
}

Groovy

android {
    defaultConfig {
        consumerProguardFiles 'consumer-proguard-rules.pro'
    }
    ...
}

JAR libraries

To bundle rules with your Kotlin or Java library that ships as a JAR, put your rules file in the final JAR's META-INF/proguard/ directory, with any filename. For example if your code in <libraryroot>/src/main/kotlin, put a consumer rules file at <libraryroot>/src/main/resources/META-INF/proguard/consumer-proguard-rules.pro and the rules will be bundled in the correct location in your output JAR.

Verify that the final JAR bundles rules correctly by checking that the rules are in the META-INF/proguard directory.

Optimize AAR library build (advanced)

Note: A common misconception in Android development is that optimizing your AAR (Android Archive) or JAR (Java Archive) makes it acceptable to prevent optimization by keeping your library package during the app-level build. However, whole-program optimization (at the app level) is significantly more effective than optimization done at the library level. It's only during an app build, when a library is included as part of an app, that R8 can know how all the methods of the library are used, and which parameters are passed.

Generally, you shouldn't need to optimize a library build directly because the possible optimizations at library build time are very limited. As a library developer, you need to reason about multiple stages of optimization and keep behavior, both at library and app build time, before you optimize that library.

If you still want to optimize your library at build time this is supported by the Android Gradle Plugin.

Kotlin

android {
    buildTypes {
        release {
            isMinifyEnabled = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
        configureEach {
            consumerProguardFiles("consumer-rules.pro")
        }
    }
}

Groovy

android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles
                getDefaultProguardFile('proguard-android-optimize.txt'),
                'proguard-rules.pro'
        }
        configureEach {
            consumerProguardFiles "consumer-rules.pro"
        }
    }
}

Note that the behavior of proguardFiles is very different from consumerProguardFiles:

For example, if your library uses reflection to construct internal classes, you might need to define the keep rules both in proguardFiles and consumerProguardFiles.

If you use -repackageclasses in your library's build, repackage classes to a sub-package inside your library's package. For example, use -repackageclasses 'com.example.mylibrary.internal' instead of -repackageclasses 'internal'.

Optimize Compose UI performance

If your library includes Compose UI components, optimize for both binary shrinking with R8 (as previously described) and recomposition efficiency:

Support different R8 versions (advanced)

You can tailor rules to target specific versions of R8. This enables your library to work optimally in projects that use newer R8 versions, while allowing existing rules to continue to be used in projects with older R8 versions.

To specify targeted R8 rules, you need to include them in the META-INF/com.android.tools directory inside classes.jar of an AAR or in the META-INF/com.android.tools directory of a JAR.

In an AAR library:
    proguard.txt (legacy location, the file name must be "proguard.txt")
    classes.jar
     META-INF
         com.android.tools (location of targeted R8 rules)
             r8-from-<X>-upto-<Y>/<R8-rule-files>
             ... (more directories with the same name format)

In a JAR library:
    META-INF
     proguard/<ProGuard-rule-files> (legacy location)
     com.android.tools (location of targeted R8 rules)
         r8-from-<X>-upto-<Y>/<R8-rule-files>
         ... (more directories with the same name format)

In the META-INF/com.android.tools directory, there can be multiple subdirectories with names in the form of r8-from-<X>-upto-<Y> to indicate which R8 versions the rules are written for. Each subdirectory can have one or more files containing the R8 rules, with any file names and extensions.

Note that the -from-<X> and -upto-<Y> parts are optional, the <Y> version is exclusive, and the version ranges are usually continuous but can also overlap.

For example, r8, r8-upto-8.0.0, r8-from-8.0.0-upto-8.2.0, and r8-from-8.2.0 are directory names representing a set of targeted R8 rules. The rules under the r8 directory can be used by any R8 versions. The rules under the r8-from-8.0.0-upto-8.2.0 directory can be used by R8 from version 8.0.0 up to but not including version 8.2.0.

The Android Gradle plugin uses that information to select all the rules that can be used by the current R8 version. If a library does not specify targeted R8 rules, the Android Gradle plugin will select the rules from the legacy locations (proguard.txt for an AAR or META-INF/proguard/<ProGuard-rule-files> for a JAR).

Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.

Last updated 2026-08-05 UTC.

[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2026-08-05 UTC."],[],[]]

Web Proxy Viewer  |  New URL  |  Original Page