Skip to content

Kotlin 2.3.0, Compose 1.10.0, and more#175

Merged
dokar3 merged 4 commits intomainfrom
kotlin-2.3.0
Jan 25, 2026
Merged

Kotlin 2.3.0, Compose 1.10.0, and more#175
dokar3 merged 4 commits intomainfrom
kotlin-2.3.0

Conversation

@dokar3
Copy link
Owner

@dokar3 dokar3 commented Jan 25, 2026

Summary by CodeRabbit

  • New Features

    • Expanded Kotlin Multiplatform targets (JS & WASM) and updated web sample to use a full-page viewport.
    • Added a vector checkmark asset used by the sample UI.
  • Bug Fixes

    • Improved label padding in ChipTextField for better alignment.
  • Chores

    • Bumped Compose/Kotlin/Gradle/Android SDK versions and updated dependency catalog.
    • Switched image loading to a Ktor-based fetcher.
    • Added a manual publish workflow and refreshed the README badge.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 25, 2026

📝 Walkthrough

Walkthrough

Adds a manual GitHub Actions "Publish library" workflow; upgrades Gradle, Kotlin, Compose and version catalog; migrates modules to Kotlin Multiplatform and version-catalog plugin aliases; adds platform text-style expect/actuals; switches Coil NetworkFetcher to Ktor-based fetcher; small UI/layout and sample resource updates.

Changes

Cohort / File(s) Summary
CI / Publishing
.github/workflows/publish-library.yaml
New manual workflow "Publish library": checkout → setup Zulu JDK 20 → Gradle build → ./gradlew publish to Maven Central using GitHub Secrets (Maven + GPG).
Version catalog & tooling
gradle/libs.versions.toml, gradle/wrapper/gradle-wrapper.properties, build.gradle.kts, gradle/gradle-daemon-jvm.properties, gradle.properties, settings.gradle
Upgrade versions (Kotlin, Compose MP, Coroutines, AGP, Ktor, Coil), add androidMinSdk, add plugins (kotlinMultiplatform, android-kotlin-multiplatform), Gradle wrapper -> 9.3.0, new daemon properties, JS/WASM experimental flags, SONATYPE_HOST change, Foojay toolchains plugin in settings.
Module build conversions
Core modules
chiptextfield/build.gradle, chiptextfield-core/build.gradle, chiptextfield-m3/build.gradle, chiptextfield-core/*
Replace explicit AGP/KMP plugin ids with version-catalog aliases, remove top-level android {} in favor of androidLibrary { ... }, add/enable wasmJs and js(IR) targets with explicit output names, migrate dependencies to libs.jetbrains.compose.*, remove androidTarget.publishLibraryVariants.
Sample builds & web app
sample/*/build.gradle*, sample/webApp/*, sample/desktop/build.gradle.kts, sample/shared/build.gradle.kts
Migrate samples to version-catalog plugin aliases and libs, replace hard-coded SDK numbers with libs.versions lookups, update JS/WASM compilerOptions.outputModuleName and webpack output filenames, simplify dependencies and sourceSets.
Image loader (Coil → Ktor)
sample/shared/src/{androidMain,jsMain,jvmMain}/kotlin/.../Platform.*
Replace Coil NetworkFetcher.Factory() with Ktor-based KtorNetworkFetcherFactory() in ImageLoader components across Android, JS, and JVM targets.
Platform text-style expect/actual
chiptextfield-core/src/commonMain/kotlin/com/dokar/chiptextfield/Platform.kt, chiptextfield-core/src/{androidMain,jsMain,jvmMain,wasmJsMain}/kotlin/.../Platform.*
Add internal expect val DefaultPlatformTextStyle: PlatformTextStyle in commonMain and corresponding actual implementations on android/js/jvm/wasmJs.
UI adjustments
chiptextfield/src/commonMain/kotlin/.../ChipTextField.kt, chiptextfield-m3/src/commonMain/kotlin/.../m3/ChipTextField.kt
Conditionally wrap innerTextField with a Box applying top padding (8.dp) when a label is present; imports updated for padding.
Resources & sample UI
sample/shared/src/commonMain/composeResources/drawable/ic_check.xml, sample/shared/src/commonMain/kotlin/.../m2/CheckableChips.kt
Add ic_check vector drawable and switch check icon rendering from vector Icons to painterResource(Res.drawable.ic_check).
Web / Wasm hosting & assets
sample/webApp/src/{jsMain,wasmJsMain}/resources/index.html, sample/webApp/src/wasmJsMain/resources/load.mjs, sample/webApp/src/{jsMain,wasmJsMain}/kotlin/.../Main.kt
Replace canvas-based hosting with div #ComposeTarget / commented ComposeViewport placeholders, update JS/WASM bundle names (webApp.js, webAppWasm.js), remove skiko WASM instantiate path and adjust HTML/CSS.
Small API/implementation additions
chiptextfield-core/src/{androidMain,jvmMain,jsMain,wasmJsMain}/kotlin/.../Platform.*
Add platform-specific actual DefaultPlatformTextStyle implementations (compose PlatformTextStyle) for each target.

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer
    participant GH as GitHub Actions
    participant Runner as macOS Runner
    participant JDK as Zulu JDK 20
    participant Gradle as Gradle (build)
    participant Maven as Maven Central
    participant GPG as GPG Signing Service

    Dev->>GH: workflow_dispatch (manual)
    GH->>Runner: start job (macOS-15)
    Runner->>JDK: setup-java (Zulu JDK 20) rgba(99,102,241,0.5)
    Runner->>Gradle: checkout repo & run Gradle build rgba(16,185,129,0.5)
    Gradle->>Gradle: execute `./gradlew publish --no-configuration-cache`
    Gradle->>GPG: sign artifacts (using secrets) rgba(234,88,12,0.5)
    Gradle->>Maven: publish artifacts to Maven Central (using secrets) rgba(59,130,246,0.5)
    Maven-->>Runner: publish result
    Runner-->>GH: job result
    GH-->>Dev: workflow completed
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 I hopped through Gradle, quick and light,
I changed the fetcher, set the build to right,
Multiplatform fields now stretch and sing,
Publish button waits — a tiny spring—
The rabbit dances, code takes flight! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Kotlin 2.3.0, Compose 1.10.0, and more' accurately summarizes the primary changes in the PR, which involve upgrading Kotlin to 2.3.0, Compose Multiplatform to 1.10.0, and multiple other dependency/configuration updates.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
sample/android/build.gradle (1)

1-4: Add the Kotlin Android plugin.

This module applies com.android.application but no Kotlin Android plugin. The module contains Kotlin sources (sample/android/src/main/java/com/dokar/chiptextfield/sample/MainActivity.kt) and requires the kotlin.android plugin for proper Kotlin support, even though other configuration may allow it to compile.

Proposed fix
 plugins {
     id 'com.android.application'
+    alias(libs.plugins.kotlin.android)
     alias(libs.plugins.compose.compiler)
 }
🤖 Fix all issues with AI agents
In `@gradle.properties`:
- Around line 24-25: Remove the unused experimental flag
org.jetbrains.compose.experimental.jscanvas.enabled=true from gradle.properties
while keeping org.jetbrains.compose.experimental.wasm.enabled=true; locate the
gradle.properties entries (org.jetbrains.compose.experimental.jscanvas.enabled
and org.jetbrains.compose.experimental.wasm.enabled), delete the jscanvas line,
and ensure only the wasm flag remains to support wasmJs targets.

In `@gradle/gradle-daemon-jvm.properties`:
- Around line 1-12: The Gradle daemon file sets toolchainVersion=21 but the CI
workflows still use older JDKs; update the CI to match by changing the
java-version value to "21" in the workflow steps that set the JDK (look for uses
of actions/setup-java or 'java-version' keys) inside
.github/workflows/android.yml and .github/workflows/publish-library.yaml, or
alternatively change toolchainVersion in gradle/gradle-daemon-jvm.properties to
the JDK version your workflows currently use (e.g., 17 or 20) so both sides
match.

In `@gradle/libs.versions.toml`:
- Around line 2-16: The versions file sets kotlin="2.3.0" and agp="9.0.0", an
unsupported pair; either update kotlin to a release that supports AGP 9.0.0 or
downgrade agp to "8.13.0" to match Kotlin 2.3.0; also ensure
compose-multiplatform ("compose-multiplatform") modules apply the
org.jetbrains.kotlin.plugin.compose Gradle plugin with the same Kotlin version
(kotlin) so the Compose compiler plugin version aligns with the Kotlin
toolchain.

In `@gradle/wrapper/gradle-wrapper.properties`:
- Line 4: You changed distributionUrl to Gradle 9.3.0 but Compose Multiplatform
1.10.0 isn't officially certified for Gradle 9.x; run a full end-to-end build
and test matrix (including Android builds with AGP 9.0.0 and Kotlin 2.3.0) to
verify no regressions, and if the build fails revert distributionUrl back to a
supported Gradle (e.g., 8.14) or upgrade Compose/Kotlin/AGP to versions that
explicitly support Gradle 9.x; key items to check: gradle-wrapper.properties
distributionUrl, Compose Multiplatform 1.10.0 usage, AGP/Kotlin compatibility in
build.gradle(kts) and CI scripts.

In `@sample/shared/build.gradle.kts`:
- Around line 11-15: Add a minSdk setting to the androidLibrary block so this
module matches the other modules; update the androidLibrary configuration (the
block containing namespace, compileSdk, and androidResources.enable) to include
minSdk = libs.versions.androidMinSdk.get().toInt() so the sample/shared module
uses the same version-catalog minSdk as chiptextfield, chiptextfield-m3, and
chiptextfield-core.

In `@sample/webApp/build.gradle.kts`:
- Around line 33-35: The dev-server is serving the entire repository via
static(project.rootDir.path); replace this broad root path with a narrower,
explicit module or source directory (e.g., the module's "src/main/resources" or
a dedicated "public" folder) or alternatively restrict the server binding to
localhost only; update the static(...) call to point to the chosen subdirectory
(instead of project.rootDir.path) or configure the dev-server's host binding to
"localhost" so the repo root is no longer exposed.
🧹 Nitpick comments (6)
chiptextfield/src/commonMain/kotlin/com/dokar/chiptextfield/ChipTextField.kt (1)

320-329: Replace the 8.dp padding workaround with Material's proper label-aware padding helpers.

The label alignment issue in Compose Material TextFieldDecorationBox is real, but the current workaround of wrapping innerTextField() with Modifier.padding(top = 8.dp) does not follow Material's recommended approach. Since Material 1.10.0+, use TextFieldDefaults.textFieldWithLabelPadding() and TextFieldDefaults.textFieldWithoutLabelPadding() instead, or apply padding outside the decoration box. This ensures baseline-correct label positioning and removes the "hacky" workaround.

chiptextfield-m3/src/commonMain/kotlin/com/dokar/chiptextfield/m3/ChipTextField.kt (1)

322-331: Clarify the workaround intent and version context.
The version "material3-1.9.0" in the comment matches the project's current jetbrains-compose-material3 dependency (1.9.0), but this is Jetbrains Compose Material3, not standard Android Material3, which uses different versioning (currently 1.5.0-alpha range).

Additionally, the comment describes this as a "hacky fix," but the padding workaround when a label is present appears to be a common design pattern in Material3's DecorationBox API rather than a bug awaiting an upstream fix. Consider updating the comment to clarify: (1) the specific issue or visual problem this padding addresses, and (2) whether this remains necessary or if it's an established pattern for this use case.

.github/workflows/publish-library.yaml (3)

15-19: Align CI Java version with the daemon toolchain (21).
Line 19 sets Java to 20, while the daemon toolchain is pinned to 21. Aligning avoids extra downloads and reduces mismatch risk.

♻️ Suggested alignment
-          java-version: 20
+          java-version: 21

23-30: Ensure publishing secrets align with Gradle property names.
Lines 26–30 map secrets to ORG_GRADLE_PROJECT_* properties. Please verify these names match the publishing plugin configuration and that the secrets are defined in the repo/environment.


13-21: Update gradle/gradle-build-action to gradle/actions/setup-gradle.

gradle/gradle-build-action@v3 has been superseded by gradle/actions/setup-gradle@v3. Although the former still works (transparently delegating to the latter), Gradle recommends migrating to gradle/actions/setup-gradle@v3 for consistency with current best practices. Additionally, consider SHA pinning (e.g., actions/checkout@v6.0.2) or using full commit SHAs to reduce supply-chain risk.

gradle/libs.versions.toml (1)

31-36: Consider aligning Compose Material3 with the Compose Multiplatform version.

Material3 is pinned to 1.9.0 while other Compose artifacts use 1.10.0. If that wasn’t intentional, aligning versions reduces the risk of ABI/runtime mismatches.

♻️ Suggested alignment
-jetbrains-compose-material3 = { module = "org.jetbrains.compose.material3:material3", version = "1.9.0" }
+jetbrains-compose-material3 = { module = "org.jetbrains.compose.material3:material3", version.ref = "compose-multiplatform" }

Comment on lines 24 to 25
org.jetbrains.compose.experimental.jscanvas.enabled=true
org.jetbrains.compose.experimental.wasm.enabled=true
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, locate and read gradle.properties to understand the Compose and Kotlin versions
find . -name "gradle.properties" -type f | head -5

Repository: dokar3/ChipTextField

Length of output: 193


🏁 Script executed:

# Read the main gradle.properties file to extract Compose and Kotlin versions
cat -n gradle.properties

Repository: dokar3/ChipTextField

Length of output: 2398


🏁 Script executed:

# Find build.gradle or build.gradle.kts files to identify plugin versions
find . -name "build.gradle*" -type f | head -10

Repository: dokar3/ChipTextField

Length of output: 307


🏁 Script executed:

# Read the root build.gradle.kts to find plugin versions
cat -n build.gradle.kts

Repository: dokar3/ChipTextField

Length of output: 731


🏁 Script executed:

# Find the libs.versions.toml file which contains plugin versions
find . -name "libs.versions.toml" -o -name "versions.toml" | xargs cat -n

Repository: dokar3/ChipTextField

Length of output: 3228


🌐 Web query:

Compose Multiplatform 1.10.0 experimental jscanvas wasm flags support

💡 Result:

Compose Multiplatform 1.10.0 (Web): WasmGC browser support / flags

Compose Multiplatform 1.10.0 “Web” runs on browsers with WasmGC support. [1]

If your browser doesn’t have WasmGC enabled by default, use these browser flags (Kotlin/Wasm requirements that CMP inherits):

  • Chrome 119+ / Chromium-based 119+ (Edge/Brave/Opera, etc.): works by default. For older Chromium-based browsers, start with:
    --js-flags=--experimental-wasm-gc [2]
  • Chrome (older): enable chrome://flags/#enable-webassembly-garbage-collection and relaunch. [2]
  • Firefox 120+: works by default; Firefox 119: enable javascript.options.wasm_gc in about:config. [2]
  • Safari/WebKit 18.2+: works by default; older Safari is not supported for Kotlin/WasmGC. [2]

“experimental jscanvas” flag in 1.10.0

If by “jscanvas” you mean the Kotlin/JS canvas-based Compose web path: the old Gradle property

org.jetbrains.compose.experimental.jscanvas.enabled=true

is no longer required when you have a Kotlin/JS target (this change landed earlier and remains true in newer versions, including 1.10.0). [3]


Sources

[1] Compose Multiplatform 1.10.0 supported platforms (Web = browsers with WasmGC): https://kotlinlang.org/docs/multiplatform/compose-compatibility-and-versioning.html
[2] Kotlin/Wasm browser versions & configuration (WasmGC flags): https://kotlinlang.org/docs/wasm-configuration.html
[3] Compose Multiplatform release note noting jscanvas flag no longer required with Kotlin/JS: https://newreleases.io/project/github/JetBrains/compose-multiplatform/release/v1.9.0-alpha03


🌐 Web query:

Compose Multiplatform 1.10.0 release notes changelog experimental flags jscanvas

💡 Result:

Compose Multiplatform 1.10.0 (released January 13, 2026) — release notes / changelog

Official release notes (GitHub “Releases”)

Highlights & notable items include: unified androidx.compose.ui.tooling.preview.Preview usable from commonMain, bundled/stable Compose Hot Reload (enabled by default with Kotlin 2.1.20+), Navigation 3 support plumbing, Kotlin 2.2 requirement for native & web, Skia update to m138, and various iOS/Desktop/Web fixes and features. [1]

“What’s new” (Kotlin docs)

A curated “what changed” page for 1.10.0, including migration notes (e.g., deprecated dependency aliases, PredictiveBackHandler() → Navigation Event / NavigationBackHandler() guidance) and a dependencies table for the release. [2]

Announcement blog post (JetBrains Kotlin Blog)

High-level overview: unified @Preview, Navigation 3 on non-Android targets, and stable/bundled Hot Reload. [3]


Experimental flags / feature toggles mentioned around 1.10.x

In 1.10.0 release notes

  • iOS interop overlay rendering: UIKitInteropProperties.placedAsOverlay (experimental API/flag; requires opt-in) to place UIKit interop views above the Compose canvas. [1]

In 1.10.0 pre-release notes (useful if you’re tracking “feature flags”)

  • New context menu implementation toggle: ComposeFoundationFlags.isNewContextMenuEnabled = true (was disabled by default in pre-release notes while maturing). [1]

jscanvas (Compose for Kotlin/JS canvas target) — experimental flag

If you enable the experimental jscanvas Compose target, Gradle may require setting this in gradle.properties:

org.jetbrains.compose.experimental.jscanvas.enabled=true

This is explicitly called out by the build error message for the experimental jscanvas target. [4]


Sources

[1] JetBrains/compose-multiplatform GitHub Releases – 1.10.0 notes: (github.com)
[2] Kotlin docs – “What’s new in Compose Multiplatform 1.10.0”: (kotlinlang.org)
[3] JetBrains Kotlin Blog – “Compose Multiplatform 1.10.0…”: (blog.jetbrains.com)
[4] Kotlin Slack archive – build error text referencing org.jetbrains.compose.experimental.jscanvas.enabled=true: (slack-chats.kotlinlang.org)

Citations:


🏁 Script executed:

# Check if project actually uses jscanvas or wasm targets in build files
rg "jscanvas|wasmJs|wasmWasi" --type kotlin --type gradle -i

Repository: dokar3/ChipTextField

Length of output: 724


🏁 Script executed:

# Check the actual build.gradle files that use wasmJs to understand configuration
cat -n sample/webApp/build.gradle.kts | head -50

Repository: dokar3/ChipTextField

Length of output: 1911


🏁 Script executed:

# Search for any jscanvas references in the entire codebase
rg "jscanvas" -i

Repository: dokar3/ChipTextField

Length of output: 138


Remove unused jscanvas experimental flag; wasm flag is necessary.

Compose Multiplatform 1.10.0 fully supports both experimental flags. The org.jetbrains.compose.experimental.wasm.enabled=true flag is necessary and correctly used for the wasmJs targets across the project. However, org.jetbrains.compose.experimental.jscanvas.enabled=true is unnecessary—it targets an old canvas-based Kotlin/JS backend, but this project uses the modern js(IR) target and wasmJs. Remove the unused jscanvas flag from line 24.

🤖 Prompt for AI Agents
In `@gradle.properties` around lines 24 - 25, Remove the unused experimental flag
org.jetbrains.compose.experimental.jscanvas.enabled=true from gradle.properties
while keeping org.jetbrains.compose.experimental.wasm.enabled=true; locate the
gradle.properties entries (org.jetbrains.compose.experimental.jscanvas.enabled
and org.jetbrains.compose.experimental.wasm.enabled), delete the jscanvas line,
and ensure only the wasm flag remains to support wasmJs targets.

Comment on lines 1 to 12
#This file is generated by updateDaemonJvm
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/73bcfb608d1fde9fb62e462f834a3299/redirect
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/846ee0d876d26a26f37aa1ce8de73224/redirect
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/9482ddec596298c84656d31d16652665/redirect
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/39701d92e1756bb2f141eb67cd4c660e/redirect
toolchainVersion=21
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for the daemon JVM file and examine CI configurations
echo "=== Checking gradle-daemon-jvm.properties file ==="
if [ -f "gradle/gradle-daemon-jvm.properties" ]; then
  cat -n gradle/gradle-daemon-jvm.properties
else
  echo "File not found at gradle/gradle-daemon-jvm.properties"
fi

echo -e "\n=== Finding GitHub Actions workflows ==="
find .github/workflows -type f \( -name "*.yml" -o -name "*.yaml" \) 2>/dev/null | head -20

echo -e "\n=== Searching for Java version configurations in workflows ==="
rg -n "java-version" .github/workflows/ 2>/dev/null || echo "No matches found"

echo -e "\n=== Searching for Gradle Java/toolchain configurations ==="
rg -n "org.gradle.java.home|toolchainVersion|java\.version" --type properties --type gradle 2>/dev/null || echo "No matches found"

echo -e "\n=== Listing gradle.properties files ==="
find . -maxdepth 2 -name "gradle.properties" -o -name "gradle*.properties" 2>/dev/null

Repository: dokar3/ChipTextField

Length of output: 1926


🏁 Script executed:

#!/bin/bash
echo "=== Checking main gradle.properties ==="
cat -n gradle.properties

echo -e "\n=== Checking module-level gradle.properties ==="
for f in ./chiptextfield-core/gradle.properties ./chiptextfield-m3/gradle.properties ./chiptextfield/gradle.properties; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    cat -n "$f"
  fi
done

Repository: dokar3/ChipTextField

Length of output: 2812


Update CI workflows to align with daemon JVM toolchain version 21.

This file pins toolchainVersion=21, but the CI workflows use JDK 17 (android.yml) and JDK 20 (publish-library.yaml). Update the java-version settings in .github/workflows/android.yml and .github/workflows/publish-library.yaml to 21 to match the daemon JVM requirement, or adjust the daemon version to align with your CI configuration.

🤖 Prompt for AI Agents
In `@gradle/gradle-daemon-jvm.properties` around lines 1 - 12, The Gradle daemon
file sets toolchainVersion=21 but the CI workflows still use older JDKs; update
the CI to match by changing the java-version value to "21" in the workflow steps
that set the JDK (look for uses of actions/setup-java or 'java-version' keys)
inside .github/workflows/android.yml and .github/workflows/publish-library.yaml,
or alternatively change toolchainVersion in gradle/gradle-daemon-jvm.properties
to the JDK version your workflows currently use (e.g., 17 or 20) so both sides
match.

Comment on lines +2 to +16
androidCompileSdk = "36"
androidTargetSdk = "36"
androidMinSdk = "23"
kotlin = "2.3.0"
coil = "3.3.0"
compose-multiplatform = "1.10.0"
coroutines = "1.10.2"
agp = "9.0.0"
maven-publish = "0.36.0"
ktor = "3.4.0"
androidx-core-ktx = "1.17.0"
androidx-lifecycle = "2.10.0"
androidx-activity = "1.12.2"
androidx-test-ext-junit = "1.3.0"
androidx-espresso = "3.7.0"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

AGP 9.0.0 requirements compatibility Kotlin version

💡 Result:

AGP 9.0.0 requirements (toolchain)

  • Gradle: 9.1.0 (minimum & default) [1]
  • JDK: 17 [1]
  • Android SDK Build Tools: 36.0.0 [1]
  • Max supported Android API level: 36 [1]

Kotlin / KGP compatibility (AGP 9.0.0)

  • AGP 9.0 has built-in Kotlin support enabled by default (you generally remove org.jetbrains.kotlin.android) [1].
  • AGP 9.0.0 has a runtime dependency on Kotlin Gradle Plugin (KGP) 2.2.10:
    • If your project uses a lower KGP, Gradle/AGP will upgrade it to 2.2.10 automatically [1].
    • You can use a higher KGP by explicitly declaring it [1].
    • You can downgrade below 2.2.10 only if you opt out of built-in Kotlin, and the minimum downgrade is KGP 2.0.0 [1].

Kotlin Multiplatform note (if relevant)

  • With AGP 9.0+, the Kotlin Multiplatform Gradle plugin is no longer compatible with com.android.application / com.android.library in the same module; migrate to the Android-KMP library plugin and separate the Android app module as needed [2].

Sources: Android Developers AGP 9.0.0 release notes [1]; Kotlin Multiplatform migration for AGP 9 [2].


🌐 Web query:

Kotlin 2.3.0 AGP 9.0.0 compatibility

💡 Result:

Kotlin 2.3.0 and Android Gradle Plugin (AGP) 9.0.0 are not an officially supported combo yet:

  • Kotlin 2.3.0 states the maximum supported AGP version is 8.13.0 (minimum 8.2.2). So AGP 9.0.0 is beyond Kotlin 2.3.0’s supported range. [1]
  • AGP 9.0.0 introduces built-in Kotlin (enabled by default) and has a runtime dependency on Kotlin Gradle Plugin (KGP) 2.2.10; you can also override to a higher KGP version if needed. [2]
  • With AGP 9.0.0, using the org.jetbrains.kotlin.android (“kotlin-android”) plugin is no longer necessary and is flagged by Kotlin 2.3.0 (guidance/diagnostics are provided to migrate). [1][3]

Practical takeaway: Expect it to work only “unsupported / best-effort”—if you must use AGP 9.0.0, use built-in Kotlin (don’t apply org.jetbrains.kotlin.android) and be prepared for potential incompatibilities until Kotlin updates its supported AGP range. [1][2]


🌐 Web query:

Compose Multiplatform 1.10.0 Kotlin 2.3.0 compatibility requirements

💡 Result:

Compose Multiplatform 1.10.0 is compatible with Kotlin 2.3.0, but you must align the Compose compiler plugin with the same Kotlin version.

Compatibility requirements (Compose Multiplatform 1.10.0 + Kotlin 2.3.0)

  • Kotlin: Use Kotlin 2.3.0 (Compose Multiplatform 1.10.0 requires Kotlin ≥ 2.1.0 due to the full switch to the K2 compiler). [1]
  • Compose compiler Gradle plugin: Apply org.jetbrains.kotlin.plugin.compose with the same version as Kotlin (2.3.0), and apply it to every module that uses Compose. [1][2]
  • Compose Multiplatform Gradle plugin: Use org.jetbrains.compose 1.10.0. [2]
  • Dependency constraint: Compose Multiplatform-based libraries you depend on should be compiled against Kotlin ≥ 2.1.0. [1]
  • Desktop JDK: JDK 11+ to run/build desktop; JDK 17+ to package native distributions (jpackage). [1]
  • Min platform versions (1.10.0): Android API 21+, iOS 13+, macOS 12 (x64)/13 (arm64), Windows 10+, Ubuntu 20.04+, Web requires WasmGC-capable browsers. [1]

Version catalog example (matches Kotlin 2.3.0 + Compose plugin 1.10.0) [2]

[versions]
kotlin = "2.3.0"
compose-plugin = "1.10.0"

[plugins]
jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" }
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }

Sources: Kotlin Multiplatform docs on Compose compatibility/versioning and Compose compiler plugin setup. [1][2]


🌐 Web query:

AndroidX library versions compatibility Kotlin 2.3.0

💡 Result:

For Kotlin 2.3.0 (released 2025-12-16), there isn’t a special “AndroidX vs Kotlin” compatibility matrix for most AndroidX libraries—the main Kotlin-version coupling in AndroidX is Jetpack Compose’s compiler setup.

What to ensure for Kotlin 2.3.0

1) Use a supported Android Gradle Plugin (AGP)

Kotlin 2.3.0 requires AGP ≥ 8.2.2 and supports up to AGP 8.13.0. [1]

2) If you use Jetpack Compose: use the Compose Compiler Gradle plugin that matches Kotlin

For Kotlin 2.0+, Compose is configured via the Compose Compiler Gradle plugin (org.jetbrains.kotlin.plugin.compose), and its version matches the Kotlin version. This removes the old “Compose compiler extension ↔ Kotlin” pinning problem. [2][3][4]

In practice with Kotlin 2.3.0, you typically want:

  • kotlin("android") (or AGP’s built-in Kotlin support where applicable)
  • id("org.jetbrains.kotlin.plugin.compose") version "2.3.0" for Compose modules [2][4]
  • Don’t rely on composeOptions { kotlinCompilerExtensionVersion = ... } for Kotlin 2.0+ setups (that map is mainly for pre-2.0 workflows). [2][3]

3) For non-Compose AndroidX libraries

Most AndroidX libraries are fine to use with Kotlin 2.3.0 as long as your AGP/Gradle/Kotlin plugin combination is supported (see #1). The usual issues people hit when upgrading Kotlin are almost always:

  • AGP too old for the Kotlin version [1]
  • Old Compose compiler configuration instead of the Kotlin-matched Compose plugin [2][4]

Sources: Kotlin 2.3.0 release notes (AGP compatibility) [1]; official Compose compiler + migration docs [2][4]; Android’s Compose↔Kotlin compatibility guidance for Kotlin 2.0+ [3].


AGP 9.0.0 and Kotlin 2.3.0 combination is not officially supported.

Kotlin 2.3.0 officially supports AGP 8.2.2 through 8.13.0, but this change bumps AGP to 9.0.0, which exceeds the supported range. Either upgrade Kotlin to a version that supports AGP 9.0.0, or downgrade AGP to the maximum supported version (8.13.0). The unsupported combination may work in practice with AGP's built-in Kotlin support, but it is not guaranteed and may encounter compatibility issues.

Separately, Compose Multiplatform 1.10.0 is compatible with Kotlin 2.3.0 (requires ≥2.1.0 for K2), and minSdk 23 is acceptable (above Compose MP's API 21 minimum). Ensure the Compose Compiler Gradle plugin (org.jetbrains.kotlin.plugin.compose) is applied with version 2.3.0 to modules using Compose.

🤖 Prompt for AI Agents
In `@gradle/libs.versions.toml` around lines 2 - 16, The versions file sets
kotlin="2.3.0" and agp="9.0.0", an unsupported pair; either update kotlin to a
release that supports AGP 9.0.0 or downgrade agp to "8.13.0" to match Kotlin
2.3.0; also ensure compose-multiplatform ("compose-multiplatform") modules apply
the org.jetbrains.kotlin.plugin.compose Gradle plugin with the same Kotlin
version (kotlin) so the Compose compiler plugin version aligns with the Kotlin
toolchain.

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Find build configuration files
fd -type f \( -name "build.gradle" -o -name "gradle.properties" -o -name "libs.versions.toml" -o -name "settings.gradle" \) | head -20

Repository: dokar3/ChipTextField

Length of output: 234


🏁 Script executed:

# Check for AGP, Kotlin, and Compose versions in gradle files
rg "(com\.android\.tools\.build:gradle|org\.jetbrains\.kotlin|androidx\.compose)" -A 1 -B 1 --max-count 20

Repository: dokar3/ChipTextField

Length of output: 50376


🏁 Script executed:

# Check gradle.properties specifically
find . -name "gradle.properties" -type f -exec cat {} \;

Repository: dokar3/ChipTextField

Length of output: 2211


🌐 Web query:

Gradle 9.3.0 Android Gradle Plugin compatibility matrix

💡 Result:

Gradle 9.3.0 ↔ Android Gradle Plugin (AGP) compatibility

Gradle 9.3.0 works with AGP 8.4+ (Gradle 9.x drops support for AGP < 8.4). [2]

AGP version Minimum required Gradle Compatible with Gradle 9.3.0?
9.1 9.2.1 Yes
9.0 9.1.0 Yes
8.13 8.13 Yes
8.12 8.13 Yes
8.11 8.13 Yes
8.10 8.11.1 Yes
8.9 8.11.1 Yes
8.8 8.10.2 Yes
8.7 8.9 Yes
8.6 8.7 Yes
8.5 8.7 Yes
8.4 8.6 Yes

Sources: AGP→Gradle minimums table and AGP 9.x compatibility sections. [1] [3] [4]

Not compatible with Gradle 9.3.0: AGP 8.3 and older (unsupported on Gradle 9.x). [2]

References

  1. Android Developers — AGP/Gradle compatibility table: [1]
  2. Gradle — “Upgrading to Gradle 9.0”: minimum supported AGP is 8.4.0: [2]
  3. Android Developers — AGP 9.0.0 compatibility (min Gradle 9.1.0): [3]
  4. Android Developers — AGP 9.1.0 compatibility (min Gradle 9.2.1): [4]

🌐 Web query:

Gradle 9.3.0 Kotlin plugin compatibility requirements

💡 Result:

For Gradle 9.3.0, the Kotlin-related compatibility requirements are:

  • Minimum Kotlin Gradle Plugin (KGP) version: 2.0.0 (older KGP versions aren’t supported on Gradle 9.x due to removed Gradle APIs). [2]
  • Kotlin embedded in Gradle 9.3.0 (for Kotlin DSL): Kotlin 2.2.21 (Kotlin language version 2.2). [1]
  • Kotlin versions Gradle 9.3.0 is tested with (general Kotlin integration): Kotlin 2.0.0 through 2.3.0-RC. [1]
  • If you’re using Android Gradle Plugin (AGP) 9.0: AGP 9.0 has a runtime dependency on KGP 2.2.10 (and will auto-upgrade to it if you specify a lower version). [3]

Sources: Gradle 9.3.0 compatibility matrix [1], Gradle 9.0 upgrade guide (KGP minimum) [2], AGP 9.0 release notes [3].


🏁 Script executed:

cat gradle/libs.versions.toml | head -50

Repository: dokar3/ChipTextField

Length of output: 2913


🏁 Script executed:

# Extract version definitions for agp, kotlin, and compose
rg "^\[versions\]" -A 50 gradle/libs.versions.toml | grep -E "(agp|kotlin|compose)" | head -20

Repository: dokar3/ChipTextField

Length of output: 1794


🏁 Script executed:

# Check for composeBomVersion in build.gradle files
rg "composeBomVersion" -B 2 -A 2

Repository: dokar3/ChipTextField

Length of output: 1205


🌐 Web query:

Compose Multiplatform 1.10.0 Gradle 9.3 compatibility

💡 Result:

Compose Multiplatform 1.10.0 has no published guarantee of compatibility with Gradle 9.3. The key blocker is the Kotlin toolchain it depends on:

  • Compose Multiplatform requires Kotlin (and the Compose compiler Gradle plugin aligned with Kotlin). [1]
  • As of the current Kotlin Multiplatform compatibility matrix, Kotlin 2.2.20/2.2.21 are officially compatible only with Gradle 7.6.3–8.14 (no Gradle 9.x listed). [2]
  • Gradle 9.x also raises the floor to Kotlin Gradle Plugin ≥ 2.0.0, but that doesn’t imply Gradle 9.3 support—just a minimum. [3]

Practical guidance: If you want an officially supported setup for Compose Multiplatform 1.10.0 today, use Gradle ≤ 8.14 with a compatible Kotlin version; using Gradle 9.3 is “try at your own risk” until JetBrains updates Kotlin/KMP’s compatibility range to include Gradle 9.x. [2]

Sources: [1] [2] [3]


Test Compose Multiplatform 1.10.0 with Gradle 9.3.0 before merging.
AGP 9.0.0 and Kotlin 2.3.0 are compatible with Gradle 9.3.0, but Compose Multiplatform 1.10.0 lacks official Gradle 9.x support (only certified for Gradle 7.6.3–8.14). Verify the build succeeds end-to-end.

🤖 Prompt for AI Agents
In `@gradle/wrapper/gradle-wrapper.properties` at line 4, You changed
distributionUrl to Gradle 9.3.0 but Compose Multiplatform 1.10.0 isn't
officially certified for Gradle 9.x; run a full end-to-end build and test matrix
(including Android builds with AGP 9.0.0 and Kotlin 2.3.0) to verify no
regressions, and if the build fails revert distributionUrl back to a supported
Gradle (e.g., 8.14) or upgrade Compose/Kotlin/AGP to versions that explicitly
support Gradle 9.x; key items to check: gradle-wrapper.properties
distributionUrl, Compose Multiplatform 1.10.0 usage, AGP/Kotlin compatibility in
build.gradle(kts) and CI scripts.

Comment on lines +11 to +15
androidLibrary {
namespace = "com.dokar.chiptextfield.sample.shared"
compileSdk = libs.versions.androidCompileSdk.get().toInt()
androidResources.enable = true
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, find the specific file mentioned
find . -name "build.gradle.kts" -type f | head -20

Repository: dokar3/ChipTextField

Length of output: 182


🏁 Script executed:

#!/bin/bash
# Check the specific file mentioned in the review
if [ -f "sample/shared/build.gradle.kts" ]; then
  echo "=== sample/shared/build.gradle.kts ===" 
  cat -n sample/shared/build.gradle.kts | head -30
else
  echo "File not found at sample/shared/build.gradle.kts"
fi

Repository: dokar3/ChipTextField

Length of output: 913


🏁 Script executed:

#!/bin/bash
# Search for all androidLibrary blocks and their minSdk settings
echo "=== All androidLibrary blocks with context ===" 
rg -n 'androidLibrary\s*\{' -A 5 --glob '*build.gradle*'

Repository: dokar3/ChipTextField

Length of output: 1737


🏁 Script executed:

#!/bin/bash
# Check all minSdk definitions
echo "=== All minSdk definitions ===" 
rg -n 'minSdk\s*=' --glob '*build.gradle*'

Repository: dokar3/ChipTextField

Length of output: 381


🏁 Script executed:

#!/bin/bash
# Check the version catalog for androidMinSdk
echo "=== Checking version catalog files ===" 
find . -name "*.versions.toml" -o -name "libs.versions.toml" -o -name "*catalog*.toml" | head -10

Repository: dokar3/ChipTextField

Length of output: 130


🏁 Script executed:

#!/bin/bash
# Check the version catalog for androidMinSdk definition
cat -n gradle/libs.versions.toml | grep -A 2 -B 2 androidMinSdk

Repository: dokar3/ChipTextField

Length of output: 200


🏁 Script executed:

#!/bin/bash
# Get broader view of version catalog to understand structure
cat -n gradle/libs.versions.toml | head -50

Repository: dokar3/ChipTextField

Length of output: 3228


Set minSdk in androidLibrary to match other modules.

The sample/shared module lacks minSdk while all other modules (chiptextfield, chiptextfield-m3, chiptextfield-core) explicitly set it via the version catalog. This creates an inconsistency in Android configuration across the project.

💡 Proposed fix
 androidLibrary {
     namespace = "com.dokar.chiptextfield.sample.shared"
     compileSdk = libs.versions.androidCompileSdk.get().toInt()
+    minSdk = libs.versions.androidMinSdk.get().toInt()
     androidResources.enable = true
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
androidLibrary {
namespace = "com.dokar.chiptextfield.sample.shared"
compileSdk = libs.versions.androidCompileSdk.get().toInt()
androidResources.enable = true
}
androidLibrary {
namespace = "com.dokar.chiptextfield.sample.shared"
compileSdk = libs.versions.androidCompileSdk.get().toInt()
minSdk = libs.versions.androidMinSdk.get().toInt()
androidResources.enable = true
}
🤖 Prompt for AI Agents
In `@sample/shared/build.gradle.kts` around lines 11 - 15, Add a minSdk setting to
the androidLibrary block so this module matches the other modules; update the
androidLibrary configuration (the block containing namespace, compileSdk, and
androidResources.enable) to include minSdk =
libs.versions.androidMinSdk.get().toInt() so the sample/shared module uses the
same version-catalog minSdk as chiptextfield, chiptextfield-m3, and
chiptextfield-core.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@chiptextfield-core/build.gradle`:
- Around line 29-31: The testTask has been permanently disabled (enabled =
false) which hides regressions; change the testTask configuration to
conditionally enable tests based on a Gradle property or env var instead (e.g.,
read a project property like "skipWasmTests" or "enableWasmTests") so by default
wasmJs tests run but can be turned off when the Skiko issue is present; update
the testTask block (symbol: testTask) to set enabled using that property (invert
logic as needed) and document the property in the build file or README so
CI/local runs can opt in/out.
♻️ Duplicate comments (2)
gradle/libs.versions.toml (1)

5-10: Verify Kotlin 2.3.0 ↔ AGP 9.0.0 compatibility

Please confirm this pairing is officially supported; if not, align AGP or Kotlin to a supported range. This was raised previously, so I’m not duplicating details here.

Kotlin 2.3.0 supported Android Gradle Plugin versions
Android Gradle Plugin 9.0.0 Kotlin compatibility
sample/shared/build.gradle.kts (1)

11-15: Add minSdk to the androidLibrary block for consistency.
This module still omits minSdk, which can diverge from the rest of the Android targets.

🔧 Suggested addition
 androidLibrary {
     namespace = "com.dokar.chiptextfield.sample.shared"
     compileSdk = libs.versions.androidCompileSdk.get().toInt()
+    minSdk = libs.versions.androidMinSdk.get().toInt()
     androidResources.enable = true
 }
🧹 Nitpick comments (1)
chiptextfield-m3/build.gradle (1)

21-33: Consider making wasm tests opt-in instead of hard-disabled.
This keeps CI green while allowing targeted runs when the skiko issue is resolved.

♻️ Example opt-in toggle
         testTask {
-            // Tests are broken now: Module not found: Error: Can't resolve './skiko.mjs'
-            enabled = false
+            // Tests are broken now: Module not found: Error: Can't resolve './skiko.mjs'
+            enabled = providers.gradleProperty("enableWasmTests")
+                .map { it.toBoolean() }
+                .getOrElse(false)
         }

Comment on lines +29 to +31
testTask {
// Tests are broken now: Module not found: Error: Can't resolve './skiko.mjs'
enabled = false
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Avoid permanently disabling wasmJs tests

Disabling the wasm test task hides regressions. Consider gating it behind a property so it can be re-enabled in CI/local runs once the Skiko issue is fixed.

💡 Proposed tweak
         testTask {
             // Tests are broken now: Module not found: Error: Can't resolve './skiko.mjs'
-            enabled = false
+            enabled = !project.hasProperty("skipWasmTests")
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
testTask {
// Tests are broken now: Module not found: Error: Can't resolve './skiko.mjs'
enabled = false
testTask {
// Tests are broken now: Module not found: Error: Can't resolve './skiko.mjs'
enabled = !project.hasProperty("skipWasmTests")
}
🤖 Prompt for AI Agents
In `@chiptextfield-core/build.gradle` around lines 29 - 31, The testTask has been
permanently disabled (enabled = false) which hides regressions; change the
testTask configuration to conditionally enable tests based on a Gradle property
or env var instead (e.g., read a project property like "skipWasmTests" or
"enableWasmTests") so by default wasmJs tests run but can be turned off when the
Skiko issue is present; update the testTask block (symbol: testTask) to set
enabled using that property (invert logic as needed) and document the property
in the build file or README so CI/local runs can opt in/out.

@dokar3 dokar3 merged commit 732b52a into main Jan 25, 2026
2 checks passed
@dokar3 dokar3 deleted the kotlin-2.3.0 branch January 25, 2026 13:19
@coderabbitai coderabbitai bot mentioned this pull request Feb 12, 2026
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.

1 participant