Share this
Compose Multiplatform 1.8.0: What’s new and what you need to know
by Seven Peaks on May 21, 2025 9:23:23 AM
Introduction
Compose Multiplatform has been making serious strides in unifying UI development across Android, desktop, and iOS using a shared Kotlin codebase. As a Mobile Engineer working across platforms, the ability to build high-quality, responsive UIs with a single codebase is a game-changer, both in terms of productivity and code maintainability.
With the release of Compose Multiplatform 1.8.0, JetBrains brings a wave of enhancements that are not just evolutionary but transformational. This version is not just an update - it’s a signal that Kotlin’s promise of sharing UI logic between Android, iOS, desktop, and web is now production-grade.
In this article, I’ll walk you through:
- The key changes introduced in version 1.8.0
- Critical breaking changes that could affect your projects
- Practical migration tips to make your upgrade seamless
Let’s dive in.
Key changes in Compose Multiplatform 1.8.0
iOS is now Stable and Production-ready
After over a year of active development, Compose for iOS is now officially stable. This means you can ship apps to the App Store using Compose UI on iOS with confidence in API stability and ongoing support.
iOS support includes:
- Optimized layout measuring and rendering.
- Better text baseline alignment.
- More reliable Modifier behavior
- Smoother scrolling and gesture responsiveness.
Under the hood, Apple-specific rendering quirks and performance issues have been resolved. For example, views are better integrated with UIKit via ComposeUIViewController, and scrolling now behaves more naturally on iOS.
This milestone unblocks true multiplatform UIs with a single Kotlin codebase and enables shared design systems without relying on SwiftUI or UIKit directly.
SavedState replaces Bundle for Navigation Arguments
A subtle but impactful change: Compose’s navigation framework now uses SavedState instead of Android's Bundle for route arguments. This API shift makes argument parsing:
- Safer (nullability is clearer)
- Platform-agnostic (not tied to Android)
- Consistent across KMP targets
You’ll now use:
val userId = arguments.read { getStringOrNull("userid") } |
instead of:
val userId = arguments?.getString("userid") |
The SavedState API aligns well with state persistence goals in multiplatform apps and positions Compose for navigation parity on desktop, iOS, and beyond.
Our experience:
Even though the change looks quite minor and can be applied through the entire codebase quickly, we decided to also migrate to type-safe navigation at the same time (as when we started our current projects with KMP/CMP, type-safe navigation was not available). But it was worth the time.
So, how did we make this happen?
- Removed String-based routes:
data object BuildingDetails : BuildingsScreen( route = "building_details", deepLinks = listOf( NavDeepLink("$DEEPLINK/building_details") ) ) |
- Prepared Type-safe routes after rid of String-based ones:
sealed class BuildingsScreen { @Serializable object ROUTE : BuildingsScreen() @Serializable class BuildingDetails( val buildingId: String ) : BuildingsScreen() ... } |
- Updated the methods related to navigating to screens:
navController.navigate( // Before route = BuildingsScreen.BuildingDetails.route // After route = BuildingsScreen.BuildingDetails ) |
- And the final step - handling data during navigation:
val buildingId = it.toRoute<BuildingsScreen.BuildingDetails>().buildingId BuildingDetailsScreen( buildingId = buildingId ) |
In the long run, these changes will improve the readability of your code and reduce the time required for maintenance.
Line-height alignment across platforms
The LineHeightStyle.Alignment API is now supported on all platforms. Developers can now configure text line alignment consistently across Android, iOS, and other platforms.
Apply LineHeightStyle.Alignment in your text components to achieve desired alignment:
Text( text = "Sample Text", style = TextStyle( lineHeight = 20.sp, lineHeightStyle = LineHeightStyle( alignment = LineHeightStyle.Alignment.Center ) ) ) |
runOnIdle now runs on the UI thread
A key change in Compose test APIs: runOnIdle now executes on the main UI thread. Previously, this function could run on a background thread, which sometimes masked thread-safety issues in stateful UIs.
This shift brings test behavior in line with real-world runtime expectations and prevents hidden race conditions in test setups.
Main thread enforcement in tests
Many Compose test APIs now enforce main thread execution. If you try to use them off the main thread, an exception will be thrown.
For example:
- onNodeWithTag()
- performClick()
- assertTextEquals()
These APIs now require wrapping in:
runOnIdle { ... } |
or
runOnUiThread { ... } |
Tweaking current test suites might be needed to make tests more reliable, especially if they've been a bit too forgiving in the past.
Introduction of the new Clipboard interface
What changed?
A new Clipboard interface replaces the deprecated ClipboardManager.
Why does it matter?
The new interface supports suspend functions and is compatible with all targets, including web, enhancing asynchronous clipboard operations.
What do developers need to adjust?
Transition to using the new Clipboard interface for clipboard operations in your applications.
Deprecation of ComposeUIViewControllerDelegate on iOS
The ComposeUIViewControllerDelegate API has been deprecated.
Why does it matter?
Developers should now override UIViewController class methods via the parent view controller, adhering to Apple's recommended practices.
What do developers need to adjust?
Refactor your iOS code to override methods in the parent UIViewController instead of using the deprecated delegate.
Removal of platformLayers option on iOS
What changed?
The experimental platformLayers option has been removed.
Why does it matter?
The alternative layering mode introduced in version 1.6.0 is now the default behavior on iOS, rendering the option obsolete.
What do developers need to adjust?
No action is required unless your project explicitly relied on the platformLayers option.
Layout & Platform improvements
Several improvements refine the behavior of Compose UIs across platforms:
- TextField baseline alignment is now consistent across platforms.
- Insets support is improved in Compose for iOS and Desktop.
- Better text input responsiveness in Compose Web.
- Fixed layout bugs related to Modifier.alignByBaseline() on iOS.
- Compose Web now handles awaitPointerEventScope in more browsers.
- Compose Multiplatform now uses Skia 1.3.0, leading to better rendering performance and stability.
These changes improve visual consistency and responsiveness, especially when reusing design elements across screen sizes and platforms.
Breaking changes you should know
The Kotlin K2 Compiler is now required
Compose 1.8.0 fully adopts Kotlin’s next-gen K2 compiler across Native and Web targets. This change significantly improves compile-time performance, enhances type inference, and unlocks future Kotlin features.
What you need to know:
- Kotlin 2.1.0+ is mandatory. All native (including iOS) and web Compose targets must use it.
- K1-based builds are no longer supported for these targets.
- You must recompile all your Compose libraries using K2 to avoid ABI mismatches.
For Android-only projects, this may not cause immediate friction. But in multiplatform modules, you’ll need to update kotlinCompilerPluginClasspath, Kotlin Gradle Plugin version, and possibly refactor incompatible code.
Our experience:
In general, if you use only the common Google and Jetbrains SDKs, there will not be problems with migration. We use Gradle Versions Catalogs, which I personally found useful to keep all dependencies in one place and easy to manage in cases like this. And as our team continuously maintains dependency versions over time, after upgrading the version of Kotlin to 2.1.20 we’ve got no issues at all, the app built as usual with the new version.
There are steps we’ve taken at the same time to keep migration smooth:
- Update Android Gradle Plugin to version 8.8.2
- Update Room to the last available version (2.7.1 at the moment of update), as well as Sqlite driver, and migrate from Kapt to KSP.
- Removed the entire composeOptions section from app gradle configuration and added org.jetbrains.kotlin.plugin.compose to gradle plugins.
- Updated Koin DI to version 4.0.2
Material Icons must be declared explicitly
To reduce transitive bloat and align with the K2 plugin’s new architecture, the material-icons-core library is no longer bundled automatically.
If your project uses any Material icons, you must now declare them explicitly:
implementation("org.jetbrains.compose.material:material-icons-core:<version>") |
This change encourages better dependency hygiene, especially important for iOS and web targets where binary size and asset loading can be sensitive.
Our experience:
We actively use the Material Icons library, but extended dependency. It did not require additional steps as the dependency was already mentioned in our feature module gradle build configs.
This is how our setup looks:
libs.versions.toml
[versions] compose-plugin = "1.8.0" ... [plugins] jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" } ... |
build.gradle
plugins { ... alias(libs.plugins.jetbrainsCompose) ... } ... commonMain.dependencies { implementation(compose.materialIconsExtended) } |
runOnIdle now executes on UI thread
If your tests relied on the implicit waitForIdle() call, add it explicitly after runOnIdle():
runOnIdle { // your test code } waitForIdle() |
Migration tips
Upgrade Kotlin Version: Ensure your project uses Kotlin 2.1.20 or newer to maintain compatibility.
Explicit Dependencies: Add material-icons-core explicitly if your project relies on it.
Update Navigation Logic: Refactor navigation code to utilize SavedState for state management.
Revise Tests: Review and adjust tests affected by changes in runOnIdle behavior and time advancement handling.
Adopt New Clipboard Interface: Transition to the new Clipboard interface for cross-platform clipboard operations.
Leverage Variable Fonts: Utilize variable fonts to enhance UI flexibility and performance.
If you already use one of the last alpha versions of the Compose Multiplatform library in your project, migration to the stable one will not take longer than updating your Gradle Versions Catalogs and rebuilding the project. Otherwise, it can require a significant time investment into refactoring the code.
Conclusion
Compose Multiplatform 1.8.0 marks a major milestone with stable iOS support, performance improvements, and refined APIs. While the migration should be smooth for most projects, pay close attention to breaking changes in touch handling and threading.
By our experience with Kotlin Multiplatform and Compose Multiplatform, we can save up to 50% of the development time when making Android + iOS applications, as most of the functionality is production ready and works out of the box.
By following the best practices outlined here, you can ensure a seamless upgrade and take full advantage of Compose Multiplatform’s growing capabilities.
![]() |
Dmitrii Afonin (Dmitrii), Head of Mobile Dmitrii is a head of mobile with 15+ years of experience in Android development and backend systems. He has led projects end-to-end, with expertise in architecture design, Java/Kotlin, and Agile workflows. Passionate about solving technical challenges and continuous learning. |
Share this
- FinTech (13)
- Career (12)
- Expert Spotlight (11)
- Thought Leadership (11)
- Product Growth (9)
- Software Development (9)
- Cloud (8)
- Data and Analytics (7)
- Product Design (7)
- AI (5)
- Data (5)
- Design Thinking (5)
- InsurTech (5)
- QA (5)
- Agile (4)
- CSR (4)
- Company (4)
- Digital Transformation (4)
- Financial Inclusion (4)
- JavaScript (4)
- Seven Peaks Insights (4)
- Trend (4)
- UX Design (4)
- UX Research (4)
- .NET (3)
- Android Developer (3)
- Android Development (3)
- Azure (3)
- Banking (3)
- DevOps (3)
- Digital Product (3)
- IoT (3)
- Product-Centric Mindset (3)
- Service Design (3)
- CDP (2)
- Cloud Development (2)
- Customer Data Platform (2)
- E-wallet (2)
- Expat (2)
- Hybrid App (2)
- Kotlin (2)
- Product Owner (2)
- Software Tester (2)
- SwiftUI (2)
- UI (2)
- UX (2)
- UX Writing (2)
- Visual Design (2)
- iOS Development (2)
- .NET 8 (1)
- 2023 (1)
- 4IR (1)
- 5G (1)
- API (1)
- Agritech (1)
- AndroidX Biometric (1)
- App Development (1)
- Azure OpenAI Service (1)
- Backend (1)
- Brand Loyalty (1)
- CI/CD (1)
- Conversions (1)
- Cross-Platform Application (1)
- Dashboard (1)
- Digital (1)
- Digital Healthcare (1)
- Digital ID (1)
- Digital Landscape (1)
- Engineer (1)
- Expert Interview (1)
- Fiddler (1)
- Figma (1)
- Financial Times (1)
- GraphQL (1)
- Hilt (1)
- IT outsourcing (1)
- KYC (1)
- MVP (1)
- MVVM (1)
- Metaverse (1)
- Morphosis (1)
- Native App (1)
- New C# (1)
- Newsletter (1)
- Node.js (1)
- Payment (1)
- Platform Engineer (1)
- Platform Engineering Jobs (1)
- Platform Engineering Services (1)
- Project Manager (1)
- Rabbit MQ (1)
- React (1)
- ReactJS (1)
- Stripe (1)
- Super App (1)
- Turnkey (1)
- UIkit (1)
- UX Strategy (1)
- Web 3.0 (1)
- Web-Debugging Tool (1)
- April 2025 (5)
- March 2025 (4)
- February 2025 (1)
- January 2025 (3)
- December 2024 (4)
- November 2024 (2)
- September 2024 (4)
- August 2024 (3)
- July 2024 (6)
- April 2024 (1)
- March 2024 (7)
- February 2024 (14)
- January 2024 (13)
- December 2023 (9)
- November 2023 (9)
- October 2023 (2)
- September 2023 (6)
- August 2023 (6)
- June 2023 (4)
- May 2023 (4)
- April 2023 (1)
- March 2023 (1)
- November 2022 (1)
- August 2022 (4)
- July 2022 (1)
- June 2022 (6)
- April 2022 (6)
- March 2022 (4)
- February 2022 (8)
- January 2022 (4)
- December 2021 (1)
- November 2021 (2)
- October 2021 (2)
- September 2021 (1)
- August 2021 (3)
- July 2021 (1)
- June 2021 (2)
- May 2021 (1)
- March 2021 (4)
- February 2021 (5)
- December 2020 (4)
- November 2020 (1)
- June 2020 (1)
- April 2020 (1)