To create a BOM for a family of Android libraries, put the version management in a separate platform project. That project uses Gradle’s java-platform plugin to declare a dependency constraint for each library coordinate and version, then publishes the result with maven-publish from the javaPlatform component. The Android library projects keep publishing their own compiled artifacts. Consumers import the BOM with platform() and declare the libraries they want without repeating versions.
Why the BOM lives in its own project
A BOM (bill of materials) is dependency-management metadata. It records which version of each library belongs with which other version, and it does not contain the libraries’ compiled code. Gradle models this as a platform component with no sources, and that is why the platform belongs in a separate project. The Java Platform plugin cannot be combined with java or java-library in the same project, so the Android library modules and the platform module stay apart.
As an Amazon Associate I earn from qualifying purchases.
Step 1: Create the platform project
Add a new Gradle subproject or standalone build whose only job is to publish the BOM. In its build script, apply java-platform and maven-publish, set the group and version, and list one constraint per library. The following Kotlin DSL is a schematic pattern based on Gradle’s Java Platform plugin documentation. It is not a tested build script, and you will need to configure the repository URL and credentials for your own repository.
plugins {
`java-platform`
`maven-publish`
}
group = "com.example.android"
version = "1.2.0"
dependencies {
constraints {
api("com.example.android:core:1.2.0")
api("com.example.android:ui:1.2.0")
}
}
publishing {
publications {
create<MavenPublication>("bom") {
from(components["javaPlatform"])
}
}
}
Each api constraint is what becomes an entry in the generated BOM POM’s dependency-management section. The BOM version (here 1.2.0) identifies that release of the set, which is separate from the version of each library it constrains.
#1 Best Overall
Step 2: Publish the platform
Run the publish task that maven-publish generates for the bom publication. The exact task name depends on your repository setup, so check the tasks list in Gradle (./gradlew tasks --group publishing) before you run it. Once the publication is in the target repository, confirm that the generated POM lists the managed coordinates under dependency management.
Keep the library publications and the BOM publication as two separate steps. The Android library modules publish their AAR artifacts through the Android library publishing setup, and the platform project publishes only the version-management metadata.
Rank #2
Step 3: Import the BOM in consumer projects
A consuming module imports the BOM with platform() and then adds each library as an ordinary dependency, without a version:
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →dependencies {
implementation(platform("com.example.android:library-bom:1.2.0"))
implementation("com.example.android:core")
implementation("com.example.android:ui")
}
The BOM only manages versions. It does not add every managed library to the classpath, so a module that needs ui must still declare it. Jetpack Compose works the same way: the Compose BOM in the official Compose documentation is imported with a version, and the Compose libraries you want are declared separately. The Compose BOM page in the consulted documentation showed 2026.08.00 as a version example at the time of writing. That number is an illustration, not a recommended pin for a new project.
Choosing between platform() and enforcedPlatform()
Gradle offers two ways to import a BOM, and the choice matters most when your artifacts are consumed by other projects.
| Consideration | platform() |
enforcedPlatform() |
|---|---|---|
| Effect on the BOM’s constraints | Constraints are applied as version management, not converted to strict versions | Constraints are converted to strict versions (Gradle Platforms documentation) |
| Transitive propagation | Not forced onto transitive dependencies by the BOM import itself | Propagated transitively (Gradle Platforms documentation) |
| Override flexibility for consumers | Consumers can still override a managed version in their own build | Consumers are pinned to the BOM’s versions, so overrides are restricted |
| Recommended context | Libraries and components consumed by others, and most application builds | Applications that need strict version enforcement across the whole graph |
Gradle’s Platforms documentation gives this guidance: “enforcedPlatform should generally only be used in applications, not in libraries or other components consumed by others.” If your Android library artifacts will be consumed by other teams or published libraries, use platform() and keep the enforcement decision in the application that finally builds the app.
Keeping related library releases aligned
A BOM is most useful when a set of modules must work together. List the modules that belong to the set and give each one a coordinated constraint in the BOM. If the related modules do not already have a published BOM, Gradle’s version-alignment guidance recommends introducing a platform module whose constraints cover those components. For modules inside one multi-project build, Gradle also shows how project dependencies can be used as constraints, which keeps local development aligned before anything is published.
Your release scheme is a team decision. Some teams give every module the same version on each release, while others version each module independently and let the BOM record the combination. Either approach works with the BOM mechanism. Before you publish a BOM release, make sure every constrained coordinate and version exists in the target repository, because a BOM that points to missing artifacts will fail when consumers resolve it.
Best Value
Checklist before you publish
- The platform project applies
java-platformand does not applyjavaorjava-library. - Every constraint names a coordinate and a version that exists in the target repository.
- The publication is created from
components["javaPlatform"]. - The repository URL and credentials are configured for your own repository.
- Consumer documentation tells users to declare each library they need, because the BOM does not add them.
Version and source notes
The Java Platform plugin documentation consulted for this guide identified itself as Gradle 9.8.0. Gradle and Android tooling change over time, so confirm the syntax against the Gradle and Android Gradle Plugin versions your project uses before you copy the examples into a production build.
The examples in this guide are illustrative. They show the pattern the official documentation describes, and they have not been run against a specific repository or Android project.
Repository choice, credentials, and release automation depend on your hosting setup. The BOM mechanism itself does not decide those details.
For a standalone reference on Android library publishing with Maven Publish, see the Android documentation on publishing libraries. For the BOM mechanics, use the Gradle documentation for the Java Platform plugin and the Platforms guide, which are the sources the examples above follow.
Quick Recap
The Bottom Line
“”
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




