Support Library to AndroidX
For ten years, one library existed to backport new APIs to old Android versions. In 2018 it was renamed, reset and split into sixty independently versioned artifacts — and that reset is what made the modern ecosystem possible.
The is the reason an app written in 2014 could use RecyclerView on a device running
Android 2.3. is the reason an app written in 2026 can use Compose, Hilt and a navigation graph
without waiting for a platform release. The rename was not cosmetic; it changed how Android libraries
ship.
TL;DR#
- The Support Library (
android.support.*) backported new APIs to older Android versions, starting withsupport-v4in 2011. - AndroidX (
androidx.*) replaced it in 2018 with the same idea, but with independent versioning per artifact. - The migration was a package rename with a mechanical mapping, plus a flag in
gradle.propertiesduring the transition. - The important change was structural: one library became dozens of separately versioned artifacts, which is what allows any of them to ship a release without waiting for the others.
- The old namespace is frozen; it still exists on devices but receives no updates.1
Mental model#
Think of a city's public transport.
The Support Library was a single bus route that served every neighbourhood. It worked, but a change to one stop meant repainting the whole route. AndroidX is a network of routes, each with its own timetable, so a change to one line does not reschedule the others.
Where the analogy breaks#
The bus network still shares a map and a fare system. AndroidX artifacts share only a BOM (a bill of
materials listing compatible versions) and a general policy of compatibility. They are genuinely
independent — which is why androidx.core can be at a different version from androidx.compose.ui and
nobody is surprised.
The big picture#
Text description of this diagram
A force-directed graph of replacement edges recorded in the Jetpack dataset. Old APIs and libraries sit on the left and the AndroidX artifacts that supersede them on the right. support-v4 is replaced by androidx.core; android.support.v7.appcompat by androidx.appcompat; android.support.v7.recyclerview by androidx.recyclerview; android.support.constraint by androidx.constraintlayout; android.support.annotation by androidx.annotation; SharedPreferences by DataStore; android.hardware.Camera by CameraX; ExoPlayer by Media3; firebase-jobdispatcher and GcmNetworkManager by WorkManager; and android.view.View by Compose UI. Clicking a node shows what it superseded and what superseded it.
Deep dive#
Why the Support Library existed#
RecyclerView shipped in 2014 with Android 5.0's design language. It was useful to every app,
including those whose users were on Android 2.3. Shipping it in the platform would have limited it to
API 21+.
The Support Library packaged it as an app dependency instead, so it ran on any device where the app installed. That is the entire concept: ship the new code with the app, not with the OS.
// 2016-era build.gradle
dependencies {
implementation 'com.android.support:appcompat-v7:25.3.1'
implementation 'com.android.support:recyclerview-v7:25.3.1'
implementation 'com.android.support:design:25.3.1'
}The version numbers were identical across every artifact. That was the defining constraint: a fix
in recyclerview required a release of appcompat, design, support-v4 and everything else, because
they were tested and shipped as a unit.
The AndroidX reset#
In 2018, Google renamed the packages and split the release trains:
| Support Library | AndroidX | |
|---|---|---|
| namespace | android.support.* | androidx.* |
| versions | one shared version | independent per artifact |
| release | one train | one per artifact |
| minimum SDK | varied | generally 14+, now 21+ |
| future | frozen | active |
The mechanical part was handled by Android Studio's Refactor → Migrate to AndroidX, which rewrote
imports and dependency coordinates. The android.useAndroidX=true and
android.enableJetifier=true flags let a project with a mix of old and new dependencies build during
the transition.1
# gradle.properties, during migration only
android.useAndroidX=true
android.enableJetifier=trueenableJetifier rewrote third-party libraries' android.support references to androidx at build
time. It was essential for the transition and is a build-time cost that should be removed once every
dependency has migrated — it is now widely disabled.
What the split enabled#
Once artifacts version independently, several things become possible that were not before:
Faster fixes. A bug in RecyclerView ships in androidx.recyclerview without touching anything
else.
Faster adoption of new Kotlin versions. androidx.core:core-ktx can require a newer Kotlin without
forcing every other library to.
New libraries without a platform release. Compose, Hilt and the navigation libraries could not have existed under a single-version model; they would have had to wait for a platform train.
A BOM to manage the complexity. Because versions are independent, Google publishes a bill of materials that pins a compatible set:
dependencies {
implementation(platform("androidx.compose:compose-bom:$composeBomVersion"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.material3:material3")
// no versions specified; the BOM decides
}The BOM is the pragmatic answer to independent versioning: independence is good for release cadence and bad for "which combination works?".
What came with the rename#
The AndroidX era also brought a change in minimum SDK policy. The Support Library supported very old versions; AndroidX's floor has risen over time (21 for many libraries, higher for Compose-era ones). That is a trade Google made deliberately: supporting API 14 forever held back the libraries.
android {
defaultConfig {
minSdk = 26 // most AndroidX libraries are comfortable here
compileSdk = 37
targetSdk = 37
}
}The three SDK numbers do different jobs: minSdk is the lowest device that can install the app,
compileSdk is the API surface the code compiles against, and targetSdk is the compatibility contract
the app opts into.2
The migration lessons#
Three things the migration taught that still apply:
- Package names are API. Renaming
android.support.v4.app.Fragmenttoandroidx.fragment.app.Fragmentbroke every third-party library that referenced the old type. That is why the transition needed Jetifier. - A single version number is a scalability failure. It works for five artifacts and fails for sixty.
- A mechanical migration needs a mechanical tool. The rename was done by a refactoring tool, not by hand, which is why it happened over months rather than years.
What the reset meant for libraries that were not Google's#
Third-party libraries had to migrate too, and the migration exposed a structural problem: a library that
depended on android.support.v4 could not be used by an app that had moved to AndroidX. Jetifier solved
it by rewriting the library's bytecode at build time, which worked and was slow.
Some libraries took the opportunity to split their own artifacts. Others used the moment to drop old support. The pattern was consistent: the reset forced the whole ecosystem to re-declare its dependencies, and a lot of accidental coupling was removed in the process.
The lesson for anyone designing a library today: depend on the narrowest AndroidX artifact that
provides what you need. A library that depends on androidx.appcompat forces every consumer to
include AppCompat, which is a large dependency for a utility that needed one helper.
What did not change#
It is worth being clear about the limits of the reset. AndroidX did not:
- Change the platform's own class names (
android.app.Activityis stillandroid.app.Activity). - Remove the need for
minSdkchecks. - Make new platform APIs available on old devices.
What it did was give libraries a release mechanism independent of the OS. That is a build and distribution change, not an API change — and it is the change that made everything after 2018 possible.
Reading a version number#
AndroidX versions are not semantic in the way most libraries are. A version like 1.9.0 means: major,
minor, patch — and a major bump does not necessarily mean a breaking change, while a minor bump can
include one behind a flag. The stable/beta/alpha channel is the signal that matters, and it is in the
artifact name (-beta01, -alpha07).
The practical consequence: upgrading a Compose artifact across a minor version deserves a release note read, not just a build. The library's own changelog is the only reliable guide, because the version number does not carry the compatibility promise a semantic version would.
The migration in one afternoon#
For a small app, the migration is genuinely mechanical:
- Bump the Android Gradle Plugin.
- Run Android Studio's "Migrate to AndroidX" refactor.
- Set
android.useAndroidX=trueand, if any dependency still uses the old namespace,android.enableJetifier=true. - Build, fix the handful of APIs that changed rather than moved (
Fragment'sgetUserVisibleHint, someNotificationCompatsignatures). - Remove Jetifier once every dependency has migrated, and measure the build time difference.
The step people skip is 5, and it is the one with a measurable payoff: Jetifier rewrites bytecode for every dependency on every build.
Where the namespace shows up today#
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Text
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.navigation.compose.NavHost
import androidx.room.Room
import androidx.work.WorkManagerEvery import is a separate artifact with its own version, its own release notes, and its own minimum SDK. That is the world the 2018 reset created.
How it evolved#
| API | Version | What changed |
|---|---|---|
| 1 | 1.0 |
|
| 4 | 1.6 Donut |
|
| 5 | 2.0 Eclair |
|
| 8 | 2.2 Froyo |
|
| 9 | 2.3 Gingerbread |
|
| 11 | 3.0 Honeycomb |
|
| 13 | 3.2 Honeycomb |
|
| 14 | 4.0 Ice Cream Sandwich |
|
| 16 | 4.1 Jelly Bean |
|
| 17 | 4.2 Jelly Bean |
|
| 18 | 4.3 Jelly Bean |
|
| 19 | 4.4 KitKat |
|
| 20 | 4.4W KitKat (Wear) |
|
| 21 | 5.0 Lollipop |
|
| 22 | 5.1 Lollipop |
|
| 23 | 6.0 Marshmallow |
|
| 24 | 7.0 Nougat |
|
| 26 | 8.0 Oreo |
|
| 27 | 8.1 Oreo |
|
| 28 | 9 Pie |
|
| 29 | 10 |
|
| 30 | 11 |
|
| 31 | 12 |
|
| 32 | 12L |
|
| 33 | 13 Tiramisu |
|
| 34 | 14 Upside Down Cake |
|
| 35 | 15 Vanilla Ice Cream |
|
| 36 | 16 Baklava |
|
| 37 | 17 Cinnamon Bun |
|
The dates: support-v4 in 2011, the design library in 2015, AndroidX in 2018, Compose in 2021. The
pattern is that each era widened the gap between "what the OS provides" and "what an app can use".
Under the hood#
- Fragment.javathe platform fragment, separate from androidx.fragment
- View.javathe platform class AndroidX wraps and extends
- Build.javathe VERSION_CODES constants libraries check at runtime
Curiosity corner#
support-v4meant "support down to API 4". The name was a minimum SDK, not a version number.- Jetifier slowed builds measurably because it rewrote bytecode for every dependency. Its removal is one of the quiet wins of the AndroidX migration.
- The BOM is a pom with dependency management, not a library. It contributes no code to the APK.
Try it#
grep -rn "android.support" --include=.kt --include=.xml --include=*.gradle .
./gradlew :app:dependencies --configuration debugRuntimeClasspath | grep androidx
Check yourself#
Check yourself
What changed structurally when the Support Library became AndroidX?
Sources#
Sources
Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.
- docsMigrar para o AndroidX | Jetpackdeveloper.android.comaccessed 2026-10-27↩
- docsAndroidX রিলিজ | Jetpackdeveloper.android.comaccessed 2026-10-27↩
- docsJetpackdeveloper.android.comaccessed 2026-10-27↩
- docsExplore the Jetpack libraries by typedeveloper.android.comaccessed 2026-10-27↩
- docsAbout Android App Bundlesdeveloper.android.comaccessed 2026-10-27↩
- docsOptimize your build speeddeveloper.android.comaccessed 2026-10-27↩