Skip to content

Commit 18e291f

Browse files
committed
update: new structure, separating the mandatory from the recommended
1 parent 41fe36d commit 18e291f

File tree

1 file changed

+93
-45
lines changed

1 file changed

+93
-45
lines changed

topics/development/multiplatform-project-agp-9-migration.md

Lines changed: 93 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,107 @@
1-
[//]: # (title: Migrating a Kotlin Multiplatform project to support AGP 9.0)
1+
[//]: # (title: Updating a Kotlin Multiplatform project to support AGP 9)
2+
<show-structure for="chapter,procedure" depth="3"/>
23

3-
Projects where multiplatform modules configured Android targets using the `com.android.application` plugin
4-
need to be restructured to upgrade to Android Gradle plugin 9.0.
5-
AGP 9 deprecates several APIs which are used by Kotlin Multiplatform,
6-
but provides a new [Android Gradle Library plugin](https://developer.android.com/kotlin/multiplatform/plugin)
7-
to be used instead.
4+
Kotlin Multiplatform projects targeting Android need to migrate to using the new
5+
[Android Gradle Library plugin](https://developer.android.com/kotlin/multiplatform/plugin)
6+
to be able to use Android Gradle plugin version 9.0 and newer.
87

9-
The following guide shows how to swap the plugins and restructure the project at the same time.
8+
> AGP 9 is supported in IntelliJ IDEA starting with version 2025.3 TODO
9+
> and Android Studio starting with Otter 2025.3 TODO
10+
>
11+
{style="note"}
12+
13+
## Mandatory changes
14+
15+
### Migrate to built-in Kotlin
16+
17+
AGP 9.0 brings built-in Kotlin support that is enabled by default,
18+
so you don't need to enable the Kotlin Android Gradle plugin (`org.jetbrains.kotlin.android`) explicitly anymore.
19+
20+
If you're using [kapt](https://kotlinlang.org/docs/kapt.html) or custom `kotlinOptions`,
21+
you may need to perform additional migration steps.
22+
23+
Follow the [migration guide](https://developer.android.com/build/migrate-to-built-in-kotlin)
24+
to make sure you don't miss anything.
25+
26+
### Migrate to the Android Gradle Library plugin
27+
28+
Previously, to configure an Android target in a multiplatform module you needed to use
29+
the KMP plugin (`org.jetbrains.kotlin.multiplatform`)
30+
together with either
31+
the Android application (`com.android.application`) or the Android library (`com.android.library`) plugin.
32+
33+
With AGP 9.0, these plugins stop being compatible with KMP,
34+
and you need to migrate to the new Android Gradle Library plugin built specifically for KMP.
1035

1136
> To make your project work with AGP 9.0 in the short term, you can manually enable the deprecated APIs.
1237
> To do that, in the `gradle.properties` file of your project add this property:
1338
> `android.enableLegacyVariantApi=true`.
1439
>
15-
> The legacy APIs are going to be removed completely in AGP 10, make sure you finish the migration before that!
40+
> The legacy APIs are going to be removed completely in AGP 10. Make sure you finish the migration before that!
1641
>
1742
{style="note"}
1843

19-
## Migration guide
44+
For library migration steps, see the [guide in Android documentation](https://developer.android.com/kotlin/multiplatform/plugin#migrate).
45+
46+
To migrate an app project, you need to have the Android entry point and the shared code in properly configured separate modules.
47+
There is a [general tutorial for migrating a sample app](#step-by-step-migration-of-a-sample-app),
48+
but the mandatory parts are:
49+
* [Create and configure a shared module]()
50+
* [Create and configure an Android app module]()
51+
52+
## Recommended changes
53+
54+
Along with updating your Gradle configuration, we recommend to review the structure of your KMP project.
55+
The general approach is to extract shared code in its own module, and create a separate module for each platform-specific
56+
entry point.
2057

21-
In this guide, we show how to restructure a combined multiplatform module into discrete modules clearly delineating
22-
shared logic, shared UI, and individual entry points.
58+
In terms of [Android modularization approach](https://developer.android.com/topic/modularization),
59+
we recommend creating separate **app modules** for platform-specific entry points
60+
(so, a separate module for Android, web, and JVM)
61+
and **feature modules** for shared code.
2362

24-
The example project is a Compose Multiplatform app that is the result of the [](compose-multiplatform-new-project.md)
63+
<!-- TODO link to the blog post explaining the changes -->
64+
65+
## Step by step migration of a sample app
66+
67+
The example project that you will prepare for the migration is a Compose Multiplatform app that is the result of the
68+
[](compose-multiplatform-new-project.md)
2569
tutorial.
26-
You can check out the initial state of the project in
27-
the [update_october_2025 branch](https://github.com/kotlin-hands-on/get-started-with-cm/tree/update_october_2025)
28-
of the sample project.
29-
30-
<!-- TODO this branch doesn't work, need something else here — I just followed the tutorial with the current plugin version
31-
and migrated the result
32-
in the meantime, the best approach is to follow the tutorial :)-->
33-
34-
The example consists of a single Gradle module (`composeApp`) that contains all the shared code and all of the KMP entry
35-
points.
36-
You will extract shared code and entry points into separate modules to reach two goals:
37-
38-
* Create a more flexible and scalable project structure that allows managing shared logic, shared UI, and different
39-
entry points
40-
separately.
41-
* Isolate the Android module (that uses the `androidApplication` Gradle plugin) from KMP modules (that use the
42-
`androidLibrary`
43-
Gradle plugin).
44-
45-
For general modularization advice,
46-
see [Android modularization intro](https://developer.android.com/topic/modularization).
47-
In these terms, you are going to create several **app modules**, for each platform, and shared **feature modules**, for
48-
UI and business logic.
49-
50-
> If your project is simple enough, it might suffice to combine all shared code (shared logic and UI) in a single
51-
module.
52-
> We'll separate them to illustrate the modularisation pattern.
53-
>
54-
{style="note"}
70+
The example consists of a single Gradle module (`composeApp`) that contains all the shared code and KMP entry
71+
points,
72+
and the `iosApp` project with the iOS-specific code and configuration.
73+
74+
To prepare for the AGP 9 migration and to create a generally more flexible and scalable project structure,
75+
you will:
76+
77+
* Create feature modules for shared UI and business logic code.
78+
* Create app modules with entry points for each platform.
79+
80+
If you are looking to only implement changes mandatory for the AGP 9 migration,
81+
you required steps are:
82+
83+
* [Create and configure a shared module](#create-shared-modules)
84+
* [Create and configure an Android app module](#android-app)
85+
86+
<!-- When the new structure is implemented in the wizard, this is going to change:
87+
following the tutorial will bring you to the new structure already.
88+
So we need to save a sample of "how things used to be" and link to it when the wizard update hits.-->
89+
90+
### Create shared modules
91+
92+
The rule of thumb for shared modules is:
93+
94+
* If you implement Compose Multiplatform UI for each of your apps, you only need a single `shared` module that
95+
includes all multiplatform dependencies.
96+
* If at least one of your apps has fully native UI and only should depend on common code for business logic,
97+
create a `sharedLogic` and a `sharedUI` module to separate them.
98+
99+
The UI in the sample project is fully implemented using Compose Multiplatform,
100+
but to illustrate the more general case we'll show the more complicated structure with `sharedUI` and `sharedLogic` modules.
101+
If you only want a single shared module, skip the shared logic step, jump ahead to the [`sharedUI`](#create-a-shared-ui-module)
102+
section and use it as a blueprint.
55103

56-
### Create a shared logic module
104+
#### Create a shared logic module
57105

58106
Before actually creating a module, you need to decide on what is business logic, which code is both UI- and
59107
platform-independent.
@@ -194,9 +242,9 @@ To do that, recreate the source set structure with the folders that contain `Pla
194242
The entry points
195243
10. Sync Gradle check that there are no expect-actual errors. -->
196244

197-
### Create a shared UI module
245+
#### Create a shared UI module
198246

199-
Isolate shared code implementing common UI elements in the `sharedUi` module:
247+
Extract shared code implementing common UI elements in the `sharedUi` module:
200248

201249
1. Create the `sharedUi` directory at the root of the project.
202250
2. Inside that directory, create an empty `build.gradle.kts` file and the `src` directory.
@@ -440,7 +488,7 @@ Create and configure a new entry point module for the Android app:
440488
9. Start the run configuration to make sure that the app runs as expected.
441489
10. If everything works correctly:
442490
* Remove the `composeApp/src/androidMain` directory.
443-
* In the `composeApp/build.gradle.kts` file, remove the desktop-related code:
491+
* In the `composeApp/build.gradle.kts` file, remove the Android-related code:
444492
* the `android {}` block,
445493
* the `androidMain.dependencies {}`,
446494
* the `androidTarget {}` block inside the `kotlin {}` block.

0 commit comments

Comments
 (0)