Skip to content

Conversation

@zamulla
Copy link
Collaborator

@zamulla zamulla commented Oct 14, 2025

No description provided.

@zamulla zamulla requested a review from a team as a code owner October 14, 2025 09:49
<toc-element toc-title="Basic project structure" topic="multiplatform-discover-project.md"/>
<toc-element toc-title="Advanced project structure" topic="multiplatform-advanced-project-structure.md"/>
<toc-element toc-title="Project configuration options" topic="multiplatform-project-configuration.md"/>
<toc-element toc-title="Project configuration options" topic="multiplatform-project-agp-9-migration.md"/>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong toc-title

You can remove old run configurations associated with the `composeApp` module.
2. In the `gradle/libs.versions.toml` file, update the AGP version to a 9.* version, for example:
```txt
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"CDE016: Unknown language is specified for a code block"
Let's try toml or text

// ...
}
```
4. In the `kotlin {}` block, specify the targets that the common module should support in this example:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous step is for the root build.gradle.kts file, specify the file with the kotlin {} block

Comment on lines +14 to +15
> To do that, in the `gradle.properties` file of your project add this property:
> `android.enableLegacyVariantApi=true`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> To do that, in the `gradle.properties` file of your project add this property:
> `android.enableLegacyVariantApi=true`.
> To do this, add the following property to the `gradle.properties` file:
> `android.enableLegacyVariantApi=true`.

Comment on lines +60 to +61
Before actually creating a module, you need to decide on what is business logic, which code is both UI- and
platform-independent.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Before actually creating a module, you need to decide on what is business logic, which code is both UI- and
platform-independent.
Before creating a module, you need to identify the code for business logic that is both UI- and platform-independent.

### Update the iOS integration
Since the iOS app entry point is not built as a separate Gradle module, you can embed the source code into any module.
In this example, `sharedUi` makes most sense:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In this example, `sharedUi` makes most sense:
In this example, `sharedUi` makes the most sense:

### Remove `composeApp` and update the Android Gradle plugin version
When all code is working from correct new modules:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
When all code is working from correct new modules:
Once all code works correctly from the new modules:

1. Remove the old module completely:
1. Remove the `composeApp` dependency from the `settings.gradle.kts` file (the line `include(":composeApp")`).
2. Remove the `composeApp` directory entirely.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
2. Remove the `composeApp` directory entirely.
2. Delete the `composeApp` directory entirely.

4. That your apps build and run with the new AGP.
Congratulations, you modernized and optimized the structure of your project!
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

Suggested change
Congratulations, you modernized and optimized the structure of your project!
Congratulations! You have modernized and optimized the structure of your project.

kotlin {
// ...
androidLibrary {
namespace = "com.jetbrains.greeting.demo.sharedLogic"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be sharedUi?

@ElviraMustafina
Copy link
Collaborator

The guide is long and intimidating, with repetitive steps for each platform. What do you think about adding a section with general steps for creating a module? This would help identify common patterns upfront and allow us to make repetitive steps collapsible.

@zamulla zamulla requested a review from evilya October 20, 2025 11:49
<toc-element toc-title="Basic project structure" topic="multiplatform-discover-project.md"/>
<toc-element toc-title="Advanced project structure" topic="multiplatform-advanced-project-structure.md"/>
<toc-element toc-title="Project configuration options" topic="multiplatform-project-configuration.md"/>
<toc-element toc-title="Project configuration options" topic="multiplatform-project-agp-9-migration.md"/>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I'm not sure if this guide will be discoverable under "Explore project structure"

```kotlin
fun currentTimeAt(location: String): String? {
@OptIn(ExperimentalTime::class)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we add opt-in on a project level?

Kotlin Multiplatform projects with Android targets which were created using the Android Gradle plugin version earlier
than 9.0
need to be restructured to upgrade to AGP 9.0.
Several APIs needed for KMP configuration are hidden in AGP 9.0 and eventually are going to be removed.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it publicly communicated/documented? It would be nice to provide a link to outline a rough timeline

than 9.0
need to be restructured to upgrade to AGP 9.0.
Several APIs needed for KMP configuration are hidden in AGP 9.0 and eventually are going to be removed.
To solve this in the long term, we recommend updating your project structure to isolate AGP usage to an Android module.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, it's not entirely correct. Library-AGP is still going to be used in a shared module, but Application-AGP will be isolated in an Android module. I'm not sure if there's established terminology for distinguishing between these two types of AGPs

The example project is a Compose Multiplatform app that is the result of the [](compose-multiplatform-new-project.md)
tutorial.
You can check out the initial state of the project in
the [update_october_2025 branch](https://github.com/kotlin-hands-on/get-started-with-cm/tree/update_october_2025)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a temporary branch that I was planning to delete 😅 should we create a new one with more meaningful name?

Comment on lines +43 to +45
* Isolate the Android module (that uses the `androidApplication` Gradle plugin) from KMP modules (that use the
`androidLibrary`
Gradle plugin).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we explicitly state somewhere at the beginning that the goal for this migration is to not use com.android.application and org.jetbrains.kotlin.multiplatform in the same module? Maybe even before describing workaround with android.enableLegacyVariantApi=true, so people would know if they even need to migrate

You have isolated the shared logic in a separate module and successfully used it cross-platform.
Next step, creating a shared UI module.

<!-- TODO Platform.kt may be a good example of migrating expect-actuals, but are they still there in the sample we're using?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, it's not used in the sample app. We either need to come up with a better example for expect/actual usage in this particular sample or just keep it more generic without mentioning Platform class and related methods

sourceSets {
commonMain.dependencies {
implementation(projects.sharedLogic)
implementation(compose.runtime)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're going to get rid of dependency aliases in CMP, so this block will change by the time of release. I'll let you know what it's going to look like

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants