Jetpack Compose BOM: Set Up Dependencies the Right Way

Quick answer: Add the Compose BOM as a Gradle
platformdependency, then declare the Compose libraries you use without individual versions. The BOM keeps those library versions compatible; it does not add the libraries for you or manage the Compose compiler.
The Compose Bill of Materials (BOM) is the simplest reliable way to manage Jetpack Compose dependencies. Instead of choosing a version for every Compose artifact, you choose one BOM version. Gradle then resolves a tested-together set of Compose library versions.
This guide configures a modern Android app using Kotlin DSL and a Gradle version catalog. It also shows the equivalent direct Gradle setup, previews, UI-test dependencies, and the mistakes that cause most setup problems.
Before you start
For a new app, Android Studio’s Empty Activity template creates a Compose-ready project. Compose uses Kotlin, and the Android documentation recommends a minimum API level of 21 or higher for a new Compose project. If you are adding Compose to an existing View-based app, you can use the same configuration in the app module and migrate screen by screen. See the Compose quick start for the current template requirements.
This article uses the current stable BOM published at the time of writing: 2026.08.00. BOM releases change regularly, so check the official Compose setup page before copying a version into a production project.
What the Compose BOM does—and does not do
Think of a BOM as a compatibility table. It maps one BOM version to matching versions of Compose UI, Foundation, Runtime, Material 3, tooling, and other Compose artifacts.
It helps because Compose libraries can be released independently. The BOM lets you update the whole compatible set by changing one version.
It does not:
- add every Compose library to your app;
- choose whether you need Material 3, Foundation, Navigation, or another feature;
- manage non-Compose dependencies such as
activity-composeor Lifecycle; or - configure the Compose compiler.
You still declare each library you use. You simply omit the version from dependencies that the BOM manages.
Recommended setup: version catalog + Kotlin DSL
Most new Android projects use gradle/libs.versions.toml. Put the BOM version and Compose compiler plugin there first.
[versions]
kotlin = "2.3.21"
composeBom = "2026.08.00"
[libraries]
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
[plugins]
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }The compiler plugin version must match your Kotlin version. With Kotlin 2.0 and later, the Compose compiler is managed with the Kotlin compiler through org.jetbrains.kotlin.plugin.compose; it is deliberately not part of the BOM.
Make the plugin available from the root build.gradle.kts:
plugins {
alias(libs.plugins.compose.compiler) apply false
}Then apply it in every Android module that contains Compose code. In a typical app, that is app/build.gradle.kts:
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.compose.compiler)
}
android {
buildFeatures {
compose = true
}
}Add the BOM and the libraries you actually need
In the same app module, import the BOM using Gradle’s platform() function. Import it for production code and instrumented tests so both configurations resolve the same Compose versions.
dependencies {
val composeBom = platform(libs.androidx.compose.bom)
implementation(composeBom)
androidTestImplementation(composeBom)
// Choose the UI layer your app needs.
implementation(libs.androidx.compose.material3)
// Android Studio @Preview support.
implementation(libs.androidx.compose.ui.tooling.preview)
debugImplementation(libs.androidx.compose.ui.tooling)
// Compose UI tests.
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
debugImplementation(libs.androidx.compose.ui.test.manifest)
}Material3 is a good default for most application interfaces. If you are building a lower-level design system instead, you might add androidx.compose.foundation:foundation or androidx.compose.ui:ui instead. The important detail is that the artifacts have no versions: the BOM supplies them.
Keep ui-tooling in debugImplementation. Your release app needs neither the interactive inspector nor its extra tooling code. Keep ui-test-manifest in debugImplementation as well; it supplies a test activity used by instrumented Compose UI tests.
Direct Gradle setup without a version catalog
You do not need a version catalog to use the BOM. This is the smallest Kotlin DSL version of the dependency block:
dependencies {
val composeBom = platform("androidx.compose:compose-bom:2026.08.00")
implementation(composeBom)
androidTestImplementation(composeBom)
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.ui:ui-tooling-preview")
debugImplementation("androidx.compose.ui:ui-tooling")
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-test-manifest")
}For Kotlin 2.x, also apply id("org.jetbrains.kotlin.plugin.compose") at the same Kotlin version used by your project. Android’s Compose compiler plugin guide has the non-catalog Gradle form if you need it.
Add integrations separately
Some libraries work with Compose but are not covered by the Compose BOM. Give those dependencies their own explicit versions, usually through your version catalog. Common examples are:
dependencies {
implementation("androidx.activity:activity-compose:1.13.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.10.0")
}Use the current versions recommended by Android Developers when you set up a real project. The same rule applies to Navigation, Hilt, Coil, Room, and Paging: they may provide Compose integrations, but they are not automatically added or versioned by the Compose BOM.
When you are learning the UI toolkit itself, start with the basics in What Is Jetpack Compose?. Then build a small screen with LazyColumn to confirm that your project, preview, and state updates all work together.
How to update the BOM safely
Updating Compose should normally be one small change:
- Read the BOM-to-library version mapping and the relevant release notes.
- Change
composeBomto the desired stable BOM version. - Sync Gradle, run unit and UI tests, and open representative screens in a debug build.
- Check your project’s
compileSdkand Android Gradle Plugin requirements. Newer Compose releases can require newer versions of both.
Avoid upgrading the BOM only to chase a single alpha API. Android offers compose-bom-alpha and compose-bom-beta for testing upcoming releases, but those tracks are not the normal production default.
Can you override one dependency from the BOM?
Yes. Keep the BOM import, then give that one artifact an explicit version:
dependencies {
implementation(platform("androidx.compose:compose-bom:2026.08.00"))
implementation("androidx.compose.animation:animation:1.12.0-beta01")
}Do this intentionally and test carefully. An alpha or beta artifact can pull in alpha dependencies of its own. If you do not have a specific reason to override a library, let the stable BOM choose the tested version instead.
Common Compose BOM mistakes
Giving every Compose dependency its own version
This defeats the main benefit of the BOM and can create an untested combination. Keep the version only on the BOM entry unless you are deliberately overriding one library.
Adding only the BOM
The BOM contains version constraints, not UI code. implementation(platform(...)) alone does not give you MaterialTheme, Text, or LazyColumn; declare the artifacts that provide those APIs.
Forgetting the test BOM
If a test configuration uses versionless Compose test artifacts, add the BOM to that configuration too. For instrumented UI tests, that is normally androidTestImplementation(composeBom).
Treating the BOM as the compiler configuration
The BOM and compiler solve different problems. With Kotlin 2.x, apply the Compose compiler Gradle plugin at the Kotlin version used by the project. Do not try to fix a compiler-plugin mismatch by changing only the BOM.
Using enforcedPlatform by default
platform() is the standard choice. enforcedPlatform() forces the BOM constraints onto downstream consumers and can make dependency resolution harder in reusable Android libraries. Use it only when you understand why strict forcing is needed.
FAQ
Do I have to use the Compose BOM?
No. You can set library versions manually, but the BOM is Android’s recommended path because it keeps independently versioned Compose artifacts aligned.
Does the BOM work with a version catalog?
Yes. Put a version only on the BOM alias, leave the individual Compose library aliases versionless, and wrap the BOM alias in platform() in your module dependency block.
Does the BOM include Material 3?
It manages Material 3’s compatible version, but it does not add Material 3 to your app. Add androidx.compose.material3:material3 if you want to use it.
Why does my preview work but my UI test fail?
Make sure the BOM is present in androidTestImplementation, ui-test-junit4 is in androidTestImplementation, and ui-test-manifest is in debugImplementation.
Next steps
Your project is ready once Gradle syncs, a simple @Composable renders inside setContent {}, and its preview appears in Android Studio. Next, learn how composable functions describe UI, then use Material Icons in Jetpack Compose to add familiar visual affordances without leaving the Compose toolchain.