Theming in Compose Multiplatform: Build Consistent Cross-Platform UIs

Theming is the secret sauce for creating polished, professional apps. With Compose Multiplatform, you can define a unified design system that adapts to Android, iOS, desktop, and web—while still allowing platform-specific tweaks. This guide covers Material Design theming, dark mode, and adaptive styling strategies for KMP apps.


1. Building a Unified Theme with Material Design

Compose Multiplatform uses Material Design 3 by default, ensuring consistency across platforms.

Basic Theme Setup

@Composable  
fun MyAppTheme(content: @Composable () -> Unit) {  
    MaterialTheme(  
        colorScheme = lightColorScheme(), // Default M3 colors  
        typography = Typography(),  
        shapes = Shapes(),  
        content = content  
    )  
}  

// Usage  
@Composable  
fun App() {  
    MyAppTheme {  
        HomeScreen()  
    }  
}  

2. Customizing Colors, Typography, and Shapes

Color Schemes

Define light/dark palettes for brand consistency:

private val LightColors = lightColorScheme(  
    primary = Color(0xFF6200EA), // Purple  
    secondary = Color(0xFF03DAC6), // Teal  
    background = Color.White  
)  

private val DarkColors = darkColorScheme(  
    primary = Color(0xFFBB86FC), // Light purple  
    secondary = Color(0xFF03DAC6),  
    background = Color(0xFF121212) // Dark gray  
)  

Dark Mode Support

@Composable  
fun MyAppTheme(  
    darkTheme: Boolean = isSystemInDarkTheme(),  
    content: @Composable () -> Unit  
) {  
    val colors = if (darkTheme) DarkColors else LightColors  
    MaterialTheme(colorScheme = colors, /*...*/)  
}  

Pro Tip: Use isSystemInDarkTheme() for automatic dark/light switching.


3. Platform-Specific Styling

Adjust designs for iOS, Android, or desktop without breaking shared logic.

Detecting Platforms

import org.jetbrains.compose.ui.platform.Platform  

val isAndroid = Platform.OS == "Android"  
val isIOS = Platform.OS == "iOS"  

Platform-Adaptive Components

@Composable  
fun PlatformButton(label: String) {  
    val color = when (Platform.OS) {  
        "Android" -> Color.Blue  
        "iOS" -> Color.Gray  
        else -> MaterialTheme.colorScheme.primary  
    }  

    Button(colors = ButtonDefaults.buttonColors(color)) {  
        Text(label)  
    }  
}  

4. Advanced Theming Strategies

Typography System

val AppTypography = Typography(  
    headlineLarge = TextStyle(  
        fontSize = 30.sp,  
        fontWeight = FontWeight.Bold  
    ),  
    bodyMedium = TextStyle(fontSize = 16.sp)  
)  

// Usage  
Text("Title", style = MaterialTheme.typography.headlineLarge)  

Shape Customization

val AppShapes = Shapes(  
    small = RoundedCornerShape(4.dp), // Buttons  
    medium = RoundedCornerShape(8.dp), // Cards  
    large = RoundedCornerShape(16.dp) // Dialogs  
)  

5. Centralized Theme Management

Keep styles consistent with a theme manager:

object ThemeManager {  
    val colors: ColorScheme  
        get() = if (isSystemInDarkTheme()) DarkColors else LightColors  

    val typography: Typography = AppTypography  
    val shapes: Shapes = AppShapes  
}  

// Apply everywhere  
MaterialTheme(  
    colorScheme = ThemeManager.colors,  
    typography = ThemeManager.typography,  
    shapes = ThemeManager.shapes  
)  

Key Takeaways

  1. Use MaterialTheme for cross-platform design consistency.
  2. Support dark mode with isSystemInDarkTheme().
  3. Use Platform.OS checks for platform-specific tweaks.
  4. Centralize styles with a theme manager for easy maintenance.
  5. Link to Material Design 3 docs for authority.

Saiful Alam Rifan

Mobile Application Developer with over 12 years of experience crafting exceptional digital experiences. I specialize in delivering high-quality, user-friendly mobile applications across diverse domains including EdTech, Ride Sharing, Telemedicine, Blockchain Wallets, and Payment Gateway integration. My approach combines technical expertise with collaborative leadership, working seamlessly with analysts, QA teams, and engineers to create scalable, bug-free solutions that exceed expectations. Let's connect and transform your ideas into remarkable mobile experiences.

Recent Posts

Start Building KMP App with Material Design 3 Expressive – 2025

Introduction: Transform Your Cross-Platform Development with Material Design 3 Are you ready to revolutionize your… Read More

1 month ago

Google I/O 2025: A New Era for KMP and Android, Powered by AI

Alright, fellow developers, let's dive into Google I/O 2025. If you blinked, you might have… Read More

3 months ago

What’s New in Jetpack Compose 1.8: Autofill, Text, Visibility & More (2025)

Jetpack Compose 1.8 rolls out handy features like Autofill integration, slick Text enhancements including auto-sizing… Read More

5 months ago

Reified Keyword in Kotlin Explained: Unlock Type Safety

 Reified Keyword in Kotlin: Simplify Your Generic Functions Kotlin's reified keyword lets your generic functions know the… Read More

5 months ago

Android Studio Cloud: Develop Android Apps Anywhere (2025)

Android Studio Cloud: Ditch the Setup, Code Anywhere (Seriously!) Alright, fellow Android devs, gather 'round… Read More

5 months ago

Firebase Studio & Google’s AI Dev Tools Guide

Firebase Studio is a new cloud-based platform for building AI-powered apps, launched at Google Cloud… Read More

5 months ago