Mastering Dependency Management & Build Systems in Kotlin Multiplatform

Why Dependency Management Matters

Poorly managed dependencies lead to:

  • Version Conflicts: Mismatched libraries causing runtime crashes.
  • Slow Builds: Unoptimized configurations wasting development time.
  • Scalability Issues: Difficulty adding new features or platforms.

KMP Advantages:

  • Unified Codebase: Share 70%+ code across platforms.
  • Centralized Control: Manage dependencies in one place.

1. Dependency Management Best Practices

1.1 Centralize Library Versions

Step 1: Declare versions in gradle.properties:

# gradle.properties  
kotlinVersion = 1.9.20  
ktorVersion = 2.3.6  

Step 2: Reference in build.gradle.kts:

dependencies {  
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinVersion")  
    implementation("io.ktor:ktor-client-core:$ktorVersion")  
}  

Benefits:

  • Avoid duplication
  • Simplify updates

1.2 Platform-Specific Dependencies

ModuleDependencyPurpose
commonMainkotlinx-datetimeCross-platform date handling
androidMainandroidx.lifecycle:lifecycle-viewmodelAndroid-specific UI logic
iosMainktor-client-darwiniOS networking

Implementation:

// build.gradle.kts  
kotlin {  
    sourceSets {  
        val commonMain by getting {  
            dependencies {  
                implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.5.0")  
            }  
        }  
        val androidMain by getting {  
            dependencies {  
                implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0")  
            }  
        }  
    }  
}  

2. Configuring Multiplatform Builds

2.1 Target Platform Setup

kotlin {  
    androidTarget()  // Android  
    iosX64()         // Intel Mac iOS Simulator  
    iosArm64()       // M1/M2 iOS Devices  
    jvm("desktop") { // Desktop (Windows/macOS/Linux)  
        compilations.all {  
            kotlinOptions.jvmTarget = "17"  
        }  
    }  
    js(IR) {         // Web  
        browser()  
    }  
}  

2.2 Platform-Specific Code with expect/actual

Shared Code (commonMain)

expect fun getDeviceId(): String  

Android Implementation

actual fun getDeviceId(): String =  
    Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)  

iOS Implementation

actual fun getDeviceId(): String =  
    UIDevice.current.identifierForVendor?.uuidString ?: ""  

3. Build Variants & Environment Configs

3.1 Android Product Flavors

Define in build.gradle.kts:

android {  
    flavorDimensions += "environment"  
    productFlavors {  
        create("dev") {  
            dimension = "environment"  
            buildConfigField("String", "API_URL", "\"https://dev.api.com\"")  
        }  
        create("prod") {  
            dimension = "environment"  
            buildConfigField("String", "API_URL", "\"https://api.com\"")  
        }  
    }  
}  

Access in Code:

val apiUrl = BuildConfig.API_URL  

3.2 iOS Configuration via Xcode Schemes

  1. Create Dev/Prod schemes in Xcode.
  2. Add API_URL to Info.plist:
<key>API_URL</key>  
<string>$(API_BASE_URL)</string>  
  1. Set environment variables per scheme.

4. Build Speed Optimization

4.1 Gradle Configuration

gradle.properties:

# Parallel execution & caching  
org.gradle.parallel=true  
org.gradle.caching=true  
kotlin.incremental=true  

Enable Build Cache:

./gradlew build --build-cache  

4.2 Dependency Caching

Repository Setup:

dependencyResolutionManagement {  
    repositories {  
        mavenCentral()  
        google()  
    }  
}  

Estimated Impact:

OptimizationBuild Time Reduction
Parallel Execution30-40%
Incremental Compilation50-60%

5. CI/CD Automation

5.1 GitHub Actions Workflow

name: KMP Build Pipeline  
on: [push]  

jobs:  
  build:  
    runs-on: ubuntu-latest  
    steps:  
      - uses: actions/checkout@v4  
      - uses: actions/setup-java@v3  
        with:  
          java-version: 17  
      - run: ./gradlew build  

  ios:  
    runs-on: macos-latest  
    needs: build  
    steps:  
      - uses: actions/checkout@v4  
      - run: ./gradlew :shared:linkDebugFrameworkIosArm64  

6. Troubleshooting Common Issues

6.1 Dependency Conflicts

Force a Specific Version:

dependencies {  
    implementation("io.ktor:ktor-client-core") {  
        version { strictly("2.3.6") }  
    }  
}  

Analyze Dependencies:

./gradlew :shared:dependencies > deps.txt  

6.2 Cache Corruption

Clean Gradle Cache:

./gradlew cleanBuildCache  
rm -rf ~/.gradle/caches  

Key Takeaways

  1. Centralize Versions: Use gradle.properties for consistency.
  2. Modularize Code: Split into commonMain, androidMain, iosMain.
  3. Optimize Builds: Enable caching and parallel execution.
  4. Automate CI/CD: Use GitHub Actions for cross-platform builds.
  5. Handle Conflicts: Use strictly() and dependency reports.

By implementing these strategies, you’ll reduce build times by 40-60% and ensure seamless cross-platform development. For advanced techniques, explore the official Kotlin Multiplatform docs. 🚀

Internal Links

External Links

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