Skip to content

Use single skiko-awt-runtime dependency on Desktop#2806

Open
kropp wants to merge 2 commits intojb-mainfrom
kropp/skiko-awt-runtime
Open

Use single skiko-awt-runtime dependency on Desktop#2806
kropp wants to merge 2 commits intojb-mainfrom
kropp/skiko-awt-runtime

Conversation

@kropp
Copy link
Member

@kropp kropp commented Feb 27, 2026

Describe proposed changes and the issue being fixed

Fixes CMP-9175 Introduce a single desktop dependency for all platforms

Testing

On desktop target, replacing the compose.desktop.currentOs with org.jetbrains.compose.desktop:desktop:1.11.0-alpha04 should work without any other changes on all OS

Release Notes

Migration Notes - Desktop

  • org.jetbrains.compose.desktop:desktop now depends on universal org.jetbrains.skiko:skiko-awt-runtime artifact, which is resolved to a platform specific artifact using Gradle attributes

@kropp kropp requested review from MatkovIvan and igordmn February 27, 2026 15:57
@kropp
Copy link
Member Author

kropp commented Feb 27, 2026

After writing Release Notes, I'm now thinking whether we should introduce desktop-awt artifact, for a possible future case of introducing another window/event management abstraction

implementation(project(":collection:collection"))
implementation(libs.skikoAwtRuntime)
implementation(project(":collection:collection"))
implementation(project(":compose:desktop:desktop"))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we rename this module to compose:ui-awt?

Copy link
Member Author

Choose a reason for hiding this comment

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

Could you please elaborate which exactly module you are proposing to rename?

Copy link
Collaborator

Choose a reason for hiding this comment

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

  • rename :compose:desktop:desktop to compose:ui-awt (because it belong more to ui, and similar to ui-uikit)
  • remove any dependencies from ui-awt except skiko
  • add ui -> ui-awt dependency to hide this module from users (see my other comment)

Copy link
Member Author

Choose a reason for hiding this comment

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

Does that mean that every library would have it as dependency, I've assumed we don't want this.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I've assumed we don't want this.

Probably we want, because the org.jetbrains.skiko:skiko on the desktop target always assumes that the runtime dependency is present, can't work without them, and can't use something different. The org.jetbrains.skiko:skiko-awt-runtime dependency itself still doesn't point to a specific OS.

Copy link
Collaborator

@igordmn igordmn Mar 2, 2026

Choose a reason for hiding this comment

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

Because of that, maybe we even don't need extra dependencies in Compose, and just make org.jetbrains.skiko:skiko -> org.jetbrains.skiko:skiko-awt-runtime in the desktop target in Skiko?

implementation(project(":collection:collection"))
implementation(libs.skikoAwtRuntime)
implementation(project(":collection:collection"))
implementation(project(":compose:desktop:desktop"))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we don't require users to depend on this explicitly, and add transitive dependency ui -> ui-awt in desktopMain?

So, when users use the CMP plugin and compose.ui, they receive the right dependency.

// during resolution, without affecting what gets published
project.configurations.configureEach { configuration ->
if (configuration.isCanBeResolved) {
configuration.resolutionStrategy.dependencySubstitution {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we use dependencyConstraints as in the CMP plugin to be consistent in the logic?

Copy link
Member Author

Choose a reason for hiding this comment

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

Unfortunately, not.
Dependency constraints are propagated to published artifacts when configuration is consumable, and it is.
This means that all users will get linux/x86 requirement, if we are building on such a machine.
That's the best solution I've come up so far.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this mean that we also need to use dependencySubstitutution in the plugin, otherwise libraries built with "Compose Multiplatform plugin" have this constraint?

Copy link
Member Author

Choose a reason for hiding this comment

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

These constraints are only applied to skiko-awt-runtime module, and it is only added as dependency in applications, it is not included in libraries' dependencies. This works so far. And there is a property to disable this behavior completely.
If we rework dependency as suggested in another comment, add skiko-awt-runtime will be added to all libraries, than it might be an issue.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I thought about it a little, and I see that if want to implement hiding this dependency from users (I see that it is beneficial), we can:

  • use dependencySubstitutution in the Gradle plugin
  • don't publish any additional modules on Compose side
  • and it seems there is no point in skiko-awt-runtime, and we can apply dependency substitution on the skiko artifact itself? If this is true, we can remove this artifact from Skiko publication?

Copy link
Collaborator

Choose a reason for hiding this comment

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

use dependencySubstitutution in the Gradle plugin

It looks like from user perspective it works the same? I.e. it allows running applications, and doesn't add anything to the library publications?

Copy link
Member Author

Choose a reason for hiding this comment

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

If we rely on dependencySubstitution, we introduce hard dependency on Compose Gradle plugin.
This will limit us in the future in supporting other build systems.
Current proposed approach with skiko-awt-runtime is less limiting, as the required attributes can be provided manually. Well, after writing this, I realize that there is still a limitation and it is only marginally better.

// during resolution, without affecting what gets published
project.configurations.configureEach { configuration ->
if (configuration.isCanBeResolved) {
configuration.resolutionStrategy.dependencySubstitution {
Copy link
Member

Choose a reason for hiding this comment

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

resolutionStrategy is local logic that affects only this project. If it's intended, please make it more explicit + link/explanation in comments how it's resolved for published artifacts

Copy link
Member

Choose a reason for hiding this comment

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

Direct :compose:material:material dependency is still here, so CMP-5990 won't be resolved

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.

3 participants