Building shared UI components with Kotlin Compose Multiplatform (KMP) allows teams to maintain a single codebase for Android, iOS, and web interfaces. However, this approach introduces unique challenges for AI code completion tools, which often struggle with the platform-specific nuances and shared code patterns specific to KMP projects.
This guide examines practical strategies for getting the most out of AI code completion when working with Kotlin Compose Multiplatform shared UI components.
Understanding KMP Shared UI Architecture
Kotlin Compose Multiplatform enables you to write UI code once and deploy it across platforms. The shared code typically lives in a common module, while platform-specific implementations reside in separate source sets.
// shared/src/commonMain/kotlin/ui/Button.kt
@Composable
fun SharedButton(
text: String,
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
Button(
onClick = onClick,
modifier = modifier
) {
Text(text)
}
}
AI tools need to understand this structure to provide relevant suggestions. Without proper context, they may suggest Android-only or iOS-only APIs that won’t compile in the shared module.
Configuring AI Tools for KMP Projects
Most AI code completion tools work best when they understand your project’s architecture. Provide clear context about your KMP setup:
- Specify that code lives in
commonMain,androidMain, andiosMainsource sets - Define expected imports for shared Compose code
- Indicate which APIs are available across platforms
When using tools like GitHub Copilot, Cursor, or Claude Code, include a brief project context file that explains your KMP structure. This helps the AI avoid suggesting platform-specific imports or APIs that would break your shared code.
Common Pitfalls and How to Avoid Them
Platform-Specific API Suggestions
AI tools frequently suggest Material 3 components that exist only on Android. For shared UI, you need either custom implementations or the limited set of Compose APIs available across platforms.
// Instead of this (Android-only):
@Composable
fun MyComponent() {
TopAppBar(
title = { Text("Title") }
)
}
// Use this pattern for shared code:
@Composable
fun SharedTopBar(
title: String,
modifier: Modifier = Modifier
) {
Box(
modifier = modifier
.fillMaxWidth()
.background(MaterialTheme.colors.primary)
.padding(16.dp)
) {
Text(
text = title,
color = MaterialTheme.colors.onPrimary
)
}
}
The AI may initially suggest Android-only components. You can mitigate this by explicitly specifying that your code targets the common source set and requires cross-platform compatible APIs.
Expect/Actual Pattern Confusion
KMP uses the expect/actual pattern for platform-specific implementations. AI tools sometimes struggle with this distinction, potentially suggesting implementations where declarations are needed.
// Expected declaration in commonMain
@Composable
expect fun PlatformText(text: String)
// Actual implementation in androidMain
@Composable
actual fun PlatformText(text: String) {
Text(text = text)
}
// Actual implementation in iosMain
@Composable
actual fun PlatformText(text: String) {
Text(text)
}
When working with expect/actual declarations, guide your AI tool to understand which file belongs to which source set to prevent incorrect suggestions.
Optimizing AI Prompts for KMP UI Development
Clear, specific prompts yield better results. Instead of generic requests, specify the context:
- Instead of: “Create a button component”
- Try: “Create a shared Compose button component that works in commonMain, using only cross-platform APIs”
For more complex components, provide the expected structure:
// Prompt: Create a shared card component with the following structure:
// - Takes title and content parameters
// - Uses only cross-platform Modifier methods
// - Supports optional onClick handler
// - Returns a Composable function
This approach helps the AI generate code that actually compiles in your shared module rather than requiring extensive rework.
Advanced KMP UI Patterns with AI Assistance
When working with more complex UI patterns, providing detailed specifications helps AI tools generate production-ready code. Consider a feature-request screen component that appears across all platforms:
// shared/src/commonMain/kotlin/ui/FeatureRequestCard.kt
@Composable
fun FeatureRequestCard(
title: String,
description: String,
votes: Int,
onVoteClick: () -> Unit,
modifier: Modifier = Modifier
) {
Box(
modifier = modifier
.fillMaxWidth()
.padding(12.dp)
.background(MaterialTheme.colors.surface, RoundedCornerShape(8.dp))
.border(1.dp, MaterialTheme.colors.outline, RoundedCornerShape(8.dp))
.padding(16.dp)
) {
Column(modifier = Modifier.fillMaxWidth()) {
Text(
text = title,
style = MaterialTheme.typography.h6,
modifier = Modifier.fillMaxWidth(),
overflow = TextOverflow.Ellipsis,
maxLines = 2
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = description,
style = MaterialTheme.typography.body2,
modifier = Modifier.fillMaxWidth(),
overflow = TextOverflow.Ellipsis,
maxLines = 3,
color = MaterialTheme.colors.onSurface.copy(alpha = 0.7f)
)
Spacer(modifier = Modifier.height(12.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Button(
onClick = onVoteClick,
modifier = Modifier.wrapContentWidth(),
colors = ButtonDefaults.buttonColors(
backgroundColor = MaterialTheme.colors.primary.copy(alpha = 0.1f),
contentColor = MaterialTheme.colors.primary
)
) {
Icon(
painter = painterResource("ic_thumbs_up.xml"),
contentDescription = "Vote",
modifier = Modifier.size(16.dp)
)
Spacer(modifier = Modifier.width(4.dp))
Text("$votes votes")
}
}
}
}
}
Guide your AI tool by specifying cross-platform constraints explicitly: mention that custom icons should use vector drawable resources available on both Android and iOS, specify that animations should use standard Compose values, and note which Material Design components are safe for shared code.
Handling AI Suggestions for Conditional Rendering
KMP projects often need platform-specific rendering logic within shared UI. AI tools should understand when to use expect/actual pattern versus composing shared components:
// shared/src/commonMain/kotlin/ui/PlatformSpecificHeader.kt
@Composable
fun PlatformSpecificHeader(
title: String,
modifier: Modifier = Modifier
) {
// This works in shared code without expect/actual
Column(
modifier = modifier
.fillMaxWidth()
.background(MaterialTheme.colors.primary)
.padding(16.dp)
) {
Text(
text = title,
style = MaterialTheme.typography.h5,
color = MaterialTheme.colors.onPrimary
)
Spacer(modifier = Modifier.height(4.dp))
// For platform-specific UI details, create a separate composable
PlatformStatusIndicator()
}
}
// Use expect/actual for true platform-specific rendering
@Composable
expect fun PlatformStatusIndicator()
When prompting AI tools, explain that shared code should defer platform-specific decisions to expect/actual implementations rather than using if (Platform.isAndroid) patterns that require conditional imports.
Context Management for Complex KMP Projects
Large KMP projects with multiple modules benefit from explicit context files. When working with AI tools, reference these documented boundaries:
Create a KMP_ARCHITECTURE.md file at your project root:
# KMP Architecture Guide
## Module Structure
- `shared/` — Common code and shared UI (commonMain)
- `shared/src/androidMain/` — Android-specific implementations
- `shared/src/iosMain/` — iOS-specific implementations
## UI Patterns
- Shared composables live in `commonMain/kotlin/ui/`
- Use `Modifier` extensions for layout concerns
- Custom components should accept `Modifier` as final optional parameter
## Forbidden Patterns in Shared Code
- Android-specific imports (android.*)
- iOS-specific imports (Foundation)
- kotlinx.serialization without proper versions
- Reflection (use inline serializers instead)
## Safe Cross-Platform APIs
- All basic Compose functions (Box, Column, Row, etc.)
- Text, Image, Button (basic Material components)
- Modifier builders and extensions
- Standard Kotlin stdlib
Reference this guide when prompting your AI tool, which helps it understand your project’s constraints without re-learning them each conversation.
Testing AI-Generated Shared Components
Always verify AI-generated code works across all target platforms. A component that compiles successfully on Android might fail on iOS due to subtle API differences:
- Test compilation for each platform source set
- Run the app on Android, iOS (or simulator), and web targets
- Check for runtime differences in layout or behavior
Best Practices for KMP AI Assistance
Maintain a project-specific reference that AI tools can access, documenting:
- Which Compose APIs are safe for shared code
- Your expect/actual naming conventions
- Common component patterns used throughout your project
- Platform-specific workarounds for shared limitations
This reference becomes part of your project context, enabling AI tools to provide more accurate suggestions over time.
Conclusion
AI code completion for Kotlin Compose Multiplatform shared UI components requires additional configuration and awareness compared to single-platform development. By understanding your KMP architecture, providing explicit context to AI tools, and verifying suggestions across platforms, you can effectively use AI assistance while maintaining working cross-platform UI code.
The key is treating AI tools as collaborative partners that need clear guidance about your multiplatform constraints. With proper setup, these tools can significantly accelerate your KMP development workflow while reducing boilerplate code in your shared modules.
Built by theluckystrike — More at zovo.one