The Gradle build system in Android Studio lets you include external binaries or other library modules to your build as dependencies. The dependencies can be located on your machine or in a remote repository, and any transitive dependencies they declare are automatically included as well. This page describes how to use dependencies with your Android project, including details about behaviors and configurations that are specific to the Android Gradle plugin (AGP). For a deeper conceptual guide to Gradle dependencies, see the Gradle guide for dependency management, but remember that your Android project must use only the dependency configurations defined on this page.
Add a library or plugin dependency
The best way to add and manage build dependencies is to use version catalogs, the method new projects use by default. This section covers the most common types of configurations used for Android projects; refer to the Gradle documentation for more options. For an example of an app that uses version catalogs, see Now in Android. If you already have build dependencies set up without version catalogs and have a multi-module project, we recommend migrating.
For guidance on adding and managing native dependencies (not common), see Native dependencies.
In the following example, we add a remote binary
dependency (the Jetpack Macrobenchmark
library), local library module
dependency (myLibrary
), and a plugin
dependency (the Android Gradle plugin) to our project. Here are the general
steps to add these dependencies to your project:
Add an alias for the version of the dependency that you want in the
[versions]
section of the version catalog file, calledlibs.versions.toml
(under thegradle
directory in Project view or Gradle Scripts in Android view):[versions] agp = "8.3.0" androidx-macro-benchmark = "1.2.2" my-library = "1.4" [libraries] ... [plugins] ...
Aliases can include dashes or underscores. These aliases generate nested values you can reference in build scripts. The references start with the name of the catalog, the
libs
part oflibs.versions.toml
. When using a single version catalog, we recommend keeping the default value of "libs."Add an alias for the dependency in the
[libraries]
(for remote binaries or local library modules) or[plugins]
(for plugins) sections of thelibs.versions.toml
file.[versions] ... [libraries] androidx-benchmark-macro = { group = "androidx.benchmark", name = "benchmark-macro-junit4", version.ref = "androidx-macro-benchmark" } my-library = { group = "com.myapplication", name = "mylibrary", version.ref = "my-library" } [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" }
Some libraries are available in a published Bill of Materials (BOM) that groups families of libraries and their versions. You can include a BOM in your version catalog and build files, and let it manage those versions for you. See Using the Bill of Materials for details.
Add a reference to dependency alias to the build script of the module(s) that require the dependency. Convert the alias' underscores and dashes to dots when you reference it from a build script. Our module-level build script would look like this:
Kotlin
plugins { alias(libs.plugins.androidApplication) } dependencies { implementation(libs.androidx.benchmark.macro) implementation(libs.my.library) }
Groovy
plugins { alias 'libs.plugins.androidApplication' } dependencies { implementation libs.androidx.benchmark.macro implementation libs.my.library }
Plugin references include
plugins
after the catalog name, and version references includeversions
after the catalog name (version references are uncommon; see Dependencies with same version numbers for examples of version references.) Library references don't include alibraries
qualifier, so you can't useversions
orplugins
at the start of a library alias.
Configure dependencies
Inside the dependencies
block, you can declare a library dependency using one
of several different dependency configurations (such as implementation
shown
earlier). Each dependency configuration provides Gradle with different
instructions about how to use the dependency. The following table describes each
of the configurations you can use for a dependency in your Android project.
Configuration | Behavior |
---|---|
implementation |
Gradle adds the dependency to the compile classpath and
packages the dependency to the build output. When your
module configures an implementation dependency, it's
letting Gradle know that you don't want the module to leak the
dependency to other modules at compile time. That is, the dependency
isn't made available to other modules that depend on the current
module.
Using this dependency configuration instead of
|
api |
Gradle adds the dependency to the compile classpath and build
output. When a module includes an api dependency, it's
letting Gradle know that the module wants to transitively export
that dependency to other modules, so that it's available to them at
both runtime and compile time.
Use this configuration with caution and only with dependencies that
you need to transitively export to other upstream consumers. If an
|
compileOnly |
Gradle adds the dependency to the compile classpath only
(that is, it's not added to the build output). This is useful when
you're creating an Android module and you need the dependency during
compilation, but it's optional to have it present at runtime. For
example, if you depend on a library that only includes compile-time annotations—typically used to generate code but often not included in the build output—you could mark that library compileOnly .
If you use this configuration, then your library module must include a runtime condition to check whether the dependency is available, and then gracefully change its behavior so it can still function if it's not provided. This helps reduce the size of the final app by not adding transient dependencies that aren't critical.
Note: You can't use the |
runtimeOnly |
Gradle adds the dependency to the build output only, for use
during runtime. That is, it isn't added to the compile classpath.
This is rarely used on Android, but commonly used in server
applications to provide logging implementations. For example, a
library could use a logging API that doesn't include an
implementation. Consumers of that library could add it as an
implementation dependency and include a
runtimeOnly dependency for the actual logging
implementation to use.
|
ksp |
These configurations supply libraries that process annotations and other symbols in your code before it is compiled. They typically validate your code or generate additional code, reducing the code you need to write. To add such a dependency, you must add it to the annotation processor classpath using the The Android Gradle plugin assumes a dependency is an annotation processor if its JAR file contains the following file:
If the plugin detects an annotation processor that's on the compile classpath, it produces a build error.
When deciding which configuration to use, consider the following:
For more information about using annotation processors, see Add annotation processors. |
lintChecks |
Use this configuration to include a library containing lint checks you want Gradle to execute when building your Android app project. Note that AARs that contain a |
lintPublish |
Use this configuration in Android library projects to include lint
checks you want Gradle to compile into a lint.jar file
and package in your AAR. This causes projects that consume your
AAR to also apply those lint checks. If you were previously using
the lintChecks dependency configuration to include lint
checks in the published AAR, you need to migrate those dependencies
to instead use the lintPublish configuration.
Kotlindependencies { // Executes lint checks from the ":checks" project at build time. lintChecks(project(":checks")) // Compiles lint checks from the ":checks-to-publish" into a // lint.jar file and publishes it to your Android library. lintPublish(project(":checks-to-publish")) } Groovydependencies { // Executes lint checks from the ':checks' project at build time. lintChecks project(':checks') // Compiles lint checks from the ':checks-to-publish' into a // lint.jar file and publishes it to your Android library. lintPublish project(':checks-to-publish') } |
Configure dependencies for a specific build variant
All of the preceding configurations apply dependencies to all build variants. If you instead want to declare a dependency for only a specific build variant source set or for a testing source set, you must capitalize the configuration name and prefix it with the name of the build variant or testing source set.
For example, to add a remote binary dependency only to your "free" product
flavor using the implementation
configuration, use this:
Kotlin
dependencies { freeImplementation("com.google.firebase:firebase-ads:21.5.1") }
Groovy
dependencies { freeImplementation 'com.google.firebase:firebase-ads:21.5.1' }
However, if you want to add a dependency for a variant that combines a product flavor and a build type, then you must initialize the configuration name:
Kotlin
// Initializes a placeholder for the freeDebugImplementation dependency configuration. val freeDebugImplementation by configurations.creating dependencies { freeDebugImplementation(project(":free-support")) }
Groovy
configurations { // Initializes a placeholder for the freeDebugImplementation dependency configuration. freeDebugImplementation {} } dependencies { freeDebugImplementation project(":free-support") }
To add implementation
dependencies for your local tests and instrumented tests
, it looks like this:
Kotlin
dependencies { // Adds a remote binary dependency only for local tests. testImplementation("junit:junit:4.12") // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1") }
Groovy
dependencies { // Adds a remote binary dependency only for local tests. testImplementation 'junit:junit:4.12' // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' }
However, certain configurations don't make sense in this situation. For example,
because other modules can't depend on androidTest
, you get the following
warning if you use the androidTestApi
configuration:
WARNING: Configuration 'androidTestApi' is obsolete and has been replaced with 'androidTestImplementation'.
Dependency order
The order in which you list your dependencies indicates the priority for each: the first library is higher priority than the second, the second is higher priority than the third, and so on. This order is important in the event that resources are merged or manifest elements are merged into your app from the libraries.
For example, if your project declares the following:
- Dependency on
LIB_A
andLIB_B
(in that order) - And
LIB_A
depends onLIB_C
andLIB_D
(in that order) - And
LIB_B
also depends onLIB_C
Then, the flat dependency order will be as follows:
LIB_A
LIB_D
LIB_B
LIB_C
This ensures that both LIB_A
and LIB_B
can override
LIB_C
; and LIB_D
is still higher priority than
LIB_B
because LIB_A
(which depends on it)
has higher priority than LIB_B
.
For more information about how manifests from different project sources/dependencies are merged, see Merge multiple manifest files.
Dependency information for Play Console
When building your app, AGP includes metadata that describes the library dependencies that are compiled into your app. When uploading your app, the Play Console inspects this metadata to provide alerts for known issues with SDKs and dependencies your app uses, and, in some cases, provide actionable feedback to resolve those issues.
The data is compressed, encrypted by a Google Play signing key, and stored in
the signing block of your release app. We recommend keeping this dependencies
file for a safe and positive user experience. You can opt out by including the
following
dependenciesInfo
block in your module's build.gradle.kts
file.
android {
dependenciesInfo {
// Disables dependency metadata when building APKs.
includeInApk = false
// Disables dependency metadata when building Android App Bundles.
includeInBundle = false
}
}
For more information on our policies and potential issues with dependencies, see our support page on using third-party SDKs in your app.
SDK insights
Android Studio shows lint warnings in the version catalog file and the Project Structure Dialog for public SDKs in the Google Play SDK Index when the following issues apply:
- The SDKs are marked as outdated by their authors.
- The SDKs violate Play policies.
The warnings are signals that you should update those dependencies, because using outdated versions could prevent you from publishing to the Google Play Console in the future.
Add build dependencies without version catalogs
We recommend using version catalogs to add and manage dependencies, but simple projects might not need them. Here's an example of a build file that doesn't use version catalogs:
Kotlin
plugins { id("com.android.application") } android { ... } dependencies { // Dependency on a remote binary implementation("com.example.android:app-magic:12.3") // Dependency on a local library module implementation(project(":mylibrary")) }
Groovy
plugins { id 'com.android.application' } android { ... } dependencies { // Dependency on a remote binary implementation 'com.example.android:app-magic:12.3' // Dependency on a local library module implementation project(':mylibrary') }
This build file declares a dependency on version 12.3 of the "app-magic" library, inside the "com.example.android" namespace group. The remote binary dependency declaration is shorthand for the following:
Kotlin
implementation(group = "com.example.android", name = "app-magic", version = "12.3")
Groovy
implementation group: 'com.example.android', name: 'app-magic', version: '12.3'
The build file also declares a dependency on an Android library module named
"mylibrary"; this name must match the library name defined with an include:
in
your settings.gradle.kts
file. When you build your app, the build system
compiles the library module and packages the resulting compiled contents in the
app.
The build file also declares a dependency on the Android Gradle plugin
(com.application.android
). If you have multiple modules that use the same
plugin, you can only have a single version of the plugin on the build classpath
across all modules. Instead of specifying the version in each of the module
build scripts, you should include the plugin dependency in the root build script
with the version, and indicate to not apply it. Adding apply false
tells
Gradle to note the version of the plugin but not to use it in the root build.
Typically the root build script is empty except for this plugins
block.
Kotlin
plugins { id("org.jetbrains.kotlin.android") version "1.9.0" apply false }
Groovy
plugins { id ‘com.android.application’ version ‘8.3.0-rc02’ apply false }
If you have a single-module project you can specify the version explicitly in the module-level build script and leave the project-level build script empty:
Kotlin
plugins { id("com.android.application") version "8.3.0" }
Groovy
plugins { id 'com.android.application' version '8.3.0-rc02' }