1## Dependencies {#dependencies} 2 3Artifacts may depend on other artifacts within AndroidX as well as sanctioned 4third-party libraries. Additionally, artifacts may have toolchain dependencies 5that are not explicitly specified in their `dependencies` build configuration or 6don't appear in their Maven publications (`pom` or `module` files). 7 8### Versioned artifacts {#dependencies-versioned} 9 10One of the most difficult aspects of independently-versioned releases is 11maintaining compatibility with public artifacts. In a monorepo such as Google's 12repository or Android Git at `main` revision, it's easy for an artifact to 13accidentally gain a dependency on a feature that may not be released on the same 14schedule. 15 16To address this problem, library owners in AndroidX can choose from several 17types of dependencies: 18 19- Project `project(":core:core")` uses the tip-of-tree sources for the 20 `androidx.core:core` library and requires that they be loaded in the 21 workspace and released at the same time. 22- Playground `projectOrArtifact(":core:core")` is used for the 23 [Playground](/docs/playground.md) workflow and will use 24 tip-of-tree sources, if present in the workspace, or `SNAPSHOT` prebuilt 25 artifacts from [androidx.dev](http://androidx.dev) otherwise. 26- Pinned `"androidx.core:core:1.4.0"` uses the prebuilt AAR and requires that 27 it be checked in to the `prebuilts/androidx/internal` local Maven repository 28 or, when using the Playground workflow, the remote Google Maven repository. 29 30Libraries should prefer pinned dependencies with the lowest possible versions 31that include the APIs or behaviors required by the library, and should only use 32project or Playground specs in cases where tip-of-tree APIs or behaviors are 33required. 34 35**Do not** upgrade the version of a library's dependency to artificially boost 36adoption of that version. 37 38#### Pre-release dependencies {#dependencies-pre-release} 39 40Pre-release suffixes **must** propagate up the dependency tree. For example, if 41your artifact has a dependency on an artifact versioned `1.1.0-alpha01` then 42your artifact must also carry the `alpha` suffix. 43 44NOTE This does not apply to test dependencies: suffixes of test dependencies do 45*not* carry over to your artifact. 46 47#### Pinned versions {#dependencies-prebuilt} 48 49To avoid issues with dependency versioning, pin your dependencies to the oldest 50stable version of an artifact that includes the necessary APIs. This will ensure 51that the artifact's release schedule is not accidentally tied to that of another 52artifact and will allow developers to use older libraries if desired. 53 54``` 55dependencies { 56 api("androidx.collection:collection:1.0.0") 57 ... 58} 59``` 60 61Artifacts are built and tested against both pinned and tip-of-tree versions of 62their dependencies to ensure behavioral compatibility. 63 64#### Tip-of-tree versions {#dependencies-project} 65 66Below is an example of a project dependency, which uses tip-of-tree sources for 67the dependency rather than a prebuilt `JAR` or `AAR`. It ties the artifact's 68release schedule to that of the dependency artifact because the dependency will 69need to be released at the same time. 70 71``` 72dependencies { 73 api(project(":collection")) 74 ... 75} 76``` 77 78### Non-public APIs {#dependencies-non-public-apis} 79 80Artifacts may depend on non-public or restricted APIs exposed within their own 81artifact or another artifact in the same `groupId`; however, cross-artifact 82usages are subject to binary compatibility guarantees. See 83[`@RestrictTo` APIs](/docs/api_guidelines#restricted-api) for 84more details. 85 86Dependency versioning policies are enforced at build time in the `createArchive` 87task, which ensures that pre-release version suffixes are propagated 88appropriately. Cross-artifact API usage policies are enforced by the `checkApi` 89and `checkApiRelease` tasks. 90 91### Third-party libraries {#dependencies-3p} 92 93Artifacts may depend on libraries developed outside of AndroidX; however, they 94must conform to the following guidelines: 95 96* Prebuilt **must** be checked into Android Git 97 * `prebuilts/maven_repo` is recommended if this dependency is only 98 intended for use with AndroidX artifacts, otherwise please use 99 `external` 100* Prebuilt directory **must** contains an `OWNERS` file identifying one or 101 more individual owners (e.g. NOT a group alias) 102* Library **must** be approved by legal 103 104Please see Jetpack's 105[open-source policy page](/docs/open_source.md) for more 106details on using third-party libraries. 107 108### Platform extension (sidecar JAR) dependencies {#dependencies-sidecar} 109 110Platform extension or "sidecar JAR" libraries ship as part of the Android system 111image and are made available to developers through the `<uses-library>` manifest 112tag. 113 114Examples include Camera OEM extensions (`androidx.camera.extensions.impl`) and 115Window OEM extensions (`androidx.window.extensions`). 116 117Extension libraries may be defined in AndroidX library projects (see 118`androidx.window.extensions`) or externally, ex. in AOSP alongside the platform. 119In either case, we recommend that libraries use extensions as pinned, rather 120than project-type, dependencies to facilitate versioning across repositories. 121 122*Do not* ship extension interfaces to Google Maven. Teams may choose to ship 123stub JARs publicly, but that is not covered by AndroidX workflows. 124 125Project dependencies on extension libraries **must** use `compileOnly`: 126 127`build.gradle`: 128 129``` 130dependencies { 131 // Extension interfaces defined in Jetpack 132 compileOnly(project(":window:extensions:extensions")) 133 134 // Extension interfaces defined in a stub JAR 135 compileOnly( 136 fileTree( 137 dir: "../wear_stubs", 138 include: ["com.google.android.wearable-stubs.jar"] 139 ) 140 ) 141} 142``` 143 144Documentation dependencies **must** use the `stubs` configuration: 145 146`docs-public/build.gradle`: 147 148``` 149dependencies { 150 stubs("androidx.window:window-extensions:1.0.0-alpha01") 151 stubs( 152 fileTree( 153 dir: "../wear/wear_stubs/", 154 include: ["com.google.android.wearable-stubs.jar"] 155 ) 156 ) 157} 158``` 159 160See [Packaging and naming](/docs/api_guidelines#module-naming) 161for details about defining extension interfaces in Jetpack projects. 162 163### Types of dependencies {#dependencies-types} 164 165AndroidX allows dependencies to be specified as `api` or `implementation` with a 166"pinned" Maven spec (ex. `androidx.core:core:1.0.0`) or a "tip-of-tree" project 167spec (ex. `project(":core:core")`). 168 169Projects used in Playground, the experimental GitHub workflow, should use a 170"recent" project or artifact spec (ex. `projectOrArtifact(":core:core")`) which 171will default to tip-of-tree when used outside of the Playground workflow or a 172pinned `SNAPSHOT` artifact otherwise. 173 174Regardless of which dependency spec is used, all projects are built against 175tip-of-tree dependencies in CI to prevent regressions and enforce Jetpack's 176compatible-at-head policy. 177 178#### `api` versus `implementation` {#dependencies-api-vs-impl} 179 180`api`-type dependencies will appear in clients' auto-complete as though they had 181added the dependency directly to their project, and Studio will run any lint 182checks bundled with `api`-type dependencies. 183 184Dependencies whose APIs are exposed in a library's API surface **must** be 185included as `api`-type. For example, if your library's API surface includes 186`AccessibilityNodeInfoCompat` then you will use an `api`-type dependency on the 187`androidx.core:core` library. 188 189NOTE Libraries that provide client-facing lint checks, including 190`annotation-experimental`, **must** be included as `api`-type to ensure that 191lint checks are run in the clients' dependent projects. 192 193`implementation`-type dependencies will be included in the classpath, but will 194not be made available at design time (ex. in auto-complete) unless the client 195explicitly adds them. 196 197#### Constraints {#dependencies-constraints} 198 199Dependency constraints ensure that when certain libraries are used together, 200they meet certain requirements. Defining a constraint on a library *does not* 201pull that library into the classpath. 202 203In Jetpack, we use constraints to ensure that atomically-grouped libraries all 204resolve to the same version 205([example](https://android-review.googlesource.com/c/platform/frameworks/support/+/1973425)) 206and, in rare cases, to avoid conflicts resulting from classes being moved 207between artifacts 208([example](https://android-review.googlesource.com/c/platform/frameworks/support/+/2086029)). 209 210`core/core-ktx/build.gradle`: 211 212``` 213dependencies { 214 // Atomic group 215 constraints { 216 implementation(project(":core:core")) 217 } 218} 219``` 220 221In *extremely* rare cases, libraries may need to define a constraint on a 222project that is not in its `studiow` project set, ex. a constraint between the 223Paging and Compose libraries. As a workaround, libraries may hard-code the Maven 224coordinate using a version variable 225([example](https://android-review.googlesource.com/c/platform/frameworks/support/+/2160202)) 226to indicate the tip-of-tree version. 227 228`paging/paging-common/build.gradle`: 229 230``` 231dependencies { 232 // Atomic group 233 constraints { 234 implementation("androidx.paging:paging-compose:${LibraryVersions.PAGING_COMPOSE}") 235 } 236} 237``` 238 239### Dependency considerations {#dependencies-health} 240 241Generally, Jetpack libraries should avoid dependencies that negatively impact 242developers without providing substantial benefit. Libraries should consider the 243implications of their dependencies, including: 244 245- Large dependencies where only a small portion is needed (e.g. APK bloat) 246- Dependencies that slow down build times through annotation processing or 247 compiler overhead 248- Dependencies which do not maintain binary compatibility and conflict with 249 semantic versioning guarantees 250- Dependencies that are intended for server environments and don't interact 251 well with the Android build toolchain (e.g. R8) or runtime (e.g. ART) 252 253#### Kotlin {#dependencies-kotlin} 254 255Kotlin is *strongly recommended* for new libraries and the Kotlin stdlib will 256already be present in the transitive dependencies of any library that depends on 257`androidx.annotations`. 258 259``` 260plugins { 261 id("AndroidXPlugin") 262 id("kotlin-android") 263} 264 265dependencies { 266 implementation(libs.kotlinStdlib) 267} 268``` 269 270Java-based libraries *may* migrate to Kotlin, but they must be careful to 271maintain binary compatibility during the migration. Metalava does not cover all 272possible aspects of migration, so some manual work will be required. 273 274#### Kotlin reflect {#dependencies-kotlin-reflect} 275 276Reflection in libraries is 277[only allowed for backwards compatibility support](/docs/api_guidelines#sdk-reflection) 278and those users should use Java reflection. `kotlin-reflect` is very costly at 279runtime and should never be used. 280 281#### Kotlin coroutines {#dependencies-coroutines} 282 283The Kotlin coroutines library adds around 100kB post-shrinking. New libraries 284that are written in Kotlin should prefer coroutines over `ListenableFuture`, but 285existing libraries must consider the size impact on their clients. See 286[Asynchronous work with return values](/docs/api_guidelines#async-return) 287for more details on using Kotlin coroutines in Jetpack libraries. 288 289``` 290dependencies { 291 implementation(libs.kotlinCoroutinesAndroid) 292} 293``` 294 295#### GSON {#dependencies-gson} 296 297GSON relies heavily on reflection and interacts poorly with app optimization 298tools like R8. Instead, consider using `org.json` which is included in the 299Android platform SDK. 300 301#### Guava {#dependencies-guava} 302 303The full Guava library is very large and should only be used in cases where 304there is a reasonable assumption that clients already depend on full Guava. 305 306For example, consider a library `androidx.foo:foo` implemented using Kotlin 307`suspend fun`s and an optional `androidx.foo:foo-guava` library that provides 308`ListenableFuture` interop wrappers with a direct dependency on 309`kotlinx.coroutines:kotlinx-coroutines-guava` and a transitive dependency on 310Guava. 311 312Libraries that only need `ListenableFuture` may instead depend on the standalone 313`com.google.guava:listenablefuture` artifact. See 314[Asynchronous work with return values](/docs/api_guidelines#async-return) 315for more details on using `ListenableFuture` in Jetpack libraries. 316 317#### Protobuf {#dependencies-protobuf} 318 319**Note**: It is preferred to use the [`wire`](https://github.com/square/wire) 320library for handling protocol buffers in Android libraries as it has a binary 321stable runtime. An example of its usage can be found 322[here](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:benchmark/benchmark-common/build.gradle?q=wireRuntime%20file:gradle&ss=androidx%2Fplatform%2Fframeworks%2Fsupport). 323 324[Protocol buffers](https://developers.google.com/protocol-buffers) provide a 325language- and platform-neutral mechanism for serializing structured data. The 326implementation enables developers to maintain protocol compatibility across 327library versions, meaning that two clients can communicate regardless of the 328library versions included in their APKs. 329 330The Protobuf library itself, however, does not guarantee ABI compatibility 331across minor versions and a specific version **must** be used with a library to 332avoid conflict with other dependencies used by the developer. To do this, you 333must first create a new project to repackage the protobuf runtime classes, and 334then have it as a dependency in the project you generate protos in. In the 335project that generates protos, you must also relocate any import statements 336containing `com.google.protobuf` to your target package name. The 337[AndroidXRepackagePlugin](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:buildSrc/private/src/main/kotlin/androidx/build/AndroidXRepackageImplPlugin.kt) 338abstracts this for you. An example of its use to repackage the protobuf runtime 339library can be found 340[here](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:wear/protolayout/protolayout-external-protobuf/build.gradle) 341and its associated use in the library that generates protos can be found 342[here](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:wear/protolayout/protolayout-proto/build.gradle). 343 344Additionally, the Java API surface generated by the Protobuf compiler is not 345guaranteed to be stable and **must not** be exposed to developers. Library 346owners should wrap the generated API surface with well-documented public APIs 347that follow an appropriate language-specific paradigm for constructing data 348classes, e.g. the Java `Builder` pattern. 349 350### Open-source compatibility {#dependencies-aosp} 351 352Jetpack's [open-source](/docs/open_source.md) guidelines 353require that libraries consider the open-source compatibility implications of 354their dependencies, including: 355 356- Closed-source or proprietary libraries or services that may not be available 357 on AOSP devices 358- Dependencies that may prevent developers from effectively isolating their 359 tests from third-party libraries or services 360 361Primary artifacts, e.g. `workmanager`, **must not** depend on closed-source 362components including libraries and hard-coded references to packages, 363permissions, or IPC mechanisms that may only be fulfilled by closed-source 364components. 365 366Optional artifacts, e.g. `workmanager-gcm`, *may* depend on closed-source 367components or configure a primary artifact to be backed by a closed-source 368component via service discovery or initialization. 369 370Some examples of safely depending on closed-source components include: 371 372- WorkManager's GCM Network Manager integration, which uses 373 [manifest metadata](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:work/work-gcm/src/main/AndroidManifest.xml) 374 for service discovery and provides an optional artifact exposing the 375 service. 376- Downloadable Fonts integration with Play Services, which plugs in via a 377 [`ContentProvider`](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:core/core/src/androidTest/java/androidx/core/provider/MockFontProvider.java) 378 as a service discovery mechanism with developer-specified 379 [signature verification](https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts#adding-certificates) 380 for additional security. 381 382Note that in all cases, the developer is not *required* to use GCM or Play 383Services and may instead use another compatible service implementing the same 384publicly-defined protocols. 385 386### Toolchain dependencies 387 388Toolchain dependencies are typically specified by the AndroidX build system and 389are often limited, if any, configuration on behalf of library owners. 390 391#### Kotlin language 392 393Several projects within AndroidX depend on aspects of the Kotlin compiler that 394do not guarantee binary compatibility, which means (1) Kotlin updates within 395AndroidX may be more complicated and (2) Kotlin updates may be more complicated 396for external clients. 397 398For this reason, we try to separate (1) and (2) by pinning the Kotlin language 399and API versions until the new compiler has been in use in AndroidX for at least 400three months. 401 402Library owners *may* in limited cases update their Kotlin language version early 403by specifying the `kotlinVersion` DSL property: 404 405``` 406androidx { 407 kotlinVersion KOTLIN_1_9 408} 409``` 410 411Note that this propagates the version requirement to all dependencies and is not 412appropriate for low-level libraries. 413 414#### Java language (host-side) {#java-host} 415 416The Java language level determines the minimum version of the Java runtime 417required for lint checks and other host-side libraries like compilers. 418 419To avoid causing issues for clients, we try to separate Java compiler or runtime 420updates from language level by pinning the Java language level to the second 421most-recent stable LTS version. In extreme cases, however, we may be required to 422move to a more recent version because of a dependency like AGP or Gradle. 423 424Library owners *may*, in cases where clients are unable to update their Java 425version, temporarily pin their Java language version to a lower value by 426specifying the compatibility DSL properties: 427 428``` 429javaExtension.apply { 430 // TODO(b/12345678) Remove this once clients are able to update. 431 sourceCompatibility = VERSION_17 432 targetCompatibility = VERSION_17 433} 434``` 435 436When doing so, library owners **must** file a bug and establish a timeline to 437un-pin and rejoin the rest of AndroidX. 438 439#### Java language (device-side) {#java-device} 440 441Currently, the highest Java language level supported for Android libraries is 442Java 1.8 (`VERSION_1_8`). AndroidX **does not** currently support library API 443desugaring, so the use of Java 8 APIs requires `minSdk 26` or higher. 444 445#### Android SDK {#compile-sdk} 446 447Similar to our library dependency versioning policy, libraries should depend on 448the lowest `compileSdk` version that provides the APIs needed by the library. 449 450We try to avoid unnecessary SDK upgrades because raising a library's 451`compileSdk` implicitly raises its `minCompileSdk`, which means that clients are 452required to raise their own `compileSdk`. This often requires updating Android 453Gradle Plugin, which can turn into a long process of upgrading many other 454dependencies. 455