A modern, production-ready Compose Multiplatform project template with clean architecture, dependency injection, code quality tools, and AGP 9 compatible configuration for Android and iOS.
This template solves a critical issue with the default Kotlin Multiplatform wizard and provides a * production-ready* foundation with enterprise-grade tooling:
The standard KMP wizard generates projects that combine kotlinMultiplatform and
androidApplication plugins in a single module, which triggers deprecation warnings that will break
with Android Gradle Plugin 9.0.0+.
β
Proper separation: Shared KMP code in dedicated modules
β
Modern plugin: Uses com.android.kotlin.multiplatform.library
β
Clean architecture: Clear boundaries between shared and platform code
β
Dependency Injection: kotlin-inject + kotlin-inject-anvil for compile-safe DI
β
Design System: Dedicated module for shared UI components and theming
β
Code Quality: Spotless + ktlint + Compose lints pre-configured
β
No warnings: Future-proof for AGP 9.0.0+
β
Production-ready: Battle-tested structure for real-world apps
your-app-name/
βββ shared/ # Core business logic & utilities
β βββ src/
β β βββ commonMain/ # Shared code (Platform, Greeting, DI)
β β βββ androidMain/ # Android-specific implementations
β β βββ iosMain/ # iOS-specific implementations
β βββ build.gradle.kts # Uses androidKotlinMultiplatformLibrary plugin
β
βββ designsystem/ # Shared UI Design System
β βββ src/
β β βββ commonMain/
β β β βββ kotlin/
β β β βββ designsystem/
β β β βββ Button.kt # Reusable UI components
β β β βββ theme/ # Theme, Colors, Typography
β β βββ androidMain/ # Android-specific theme impl
β β βββ iosMain/ # iOS-specific theme impl
β βββ build.gradle.kts # Shared design system module
β
βββ androidApp/ # Pure Android application module
β βββ src/
β β βββ main/
β β β βββ kotlin/
β β β β βββ MainActivity.kt
β β β β βββ YourNameApplication.kt # DI setup
β β β βββ AndroidManifest.xml
β β β βββ res/ # App icon, strings, etc.
β β βββ test/ # Unit tests
β β βββ androidTest/ # Instrumentation tests
β βββ build.gradle.kts # Pure Android app configuration
β
βββ iosApp/ # iOS application
β βββ iosApp/
β β βββ ContentView.swift
β β βββ iOSApp.swift
β βββ iosApp.xcodeproj
β
βββ gradle/
β βββ libs.versions.toml # Centralized dependency management
βββ build.gradle.kts # Root build with Spotless config
βββ settings.gradle.kts # Module configuration
βββ .editorconfig # Code style configuration
- Android Studio Koala (2024.1.1) or later
- JDK 17 or later
- Xcode 15.0+ (for iOS development)
- CocoaPods (for iOS dependencies, if needed)
- Click "Use this template" button at the top of this repository
- Create your new repository
- Clone it locally
- Follow the Renaming Instructions
git clone https://github.com/yourusername/cmp-clean-starter.git MyAwesomeApp
cd MyAwesomeApp
# Follow RENAMING.md guide# Format code with Spotless
./gradlew spotlessApply
# Build for all platforms
./gradlew build
# Run Android app
./gradlew :androidApp:installDebug
# Build iOS framework
./gradlew :shared:assembleSharedDebugXCFramework
# Then open iosApp/iosApp.xcodeproj in Xcode and runSee the detailed RENAMING.md guide for step-by-step instructions on customizing this template for your project. The guide covers:
- Updating package names across all modules
- Renaming theme and typography
- Updating Application class name
- iOS bundle identifier changes
shared/: Core business logic, platform abstractions, dependency injection setupdesignsystem/: Reusable UI components, theming system, typographyandroidApp/: Android application entry point with custom Application classiosApp/: iOS application with SwiftUI
- Compile-safe DI: No reflection, all checks at compile time
- kotlin-inject-anvil: Automatic component merging across modules
- Scoped components:
AndroidAppComponent,IosAppComponent, sharedAppComponent - Example setup included: See
YourNameApplication.ktand DI package structure
- Shared theming: Material3 theme with platform-specific implementations
- Custom components: Ability to provide platform specific components with expect/actual implementations
- Automatic code formatting on build
- Consistent style across team
- Pre-configured with sensible defaults (feel free to change this!)
- Run manually:
./gradlew spotlessApply
- Slack Compose Lint Checks: Android Lint-based rules for Compose
- Compose Rules: ktlint-based rules integrated with Spotless
- Catches common Compose mistakes at build time
- Enforces best practices automatically
androidKotlinMultiplatformLibrary: Official plugin from Google- No deprecation warnings: Ready for AGP 9.0.0+
- Optimized for KMP: Better IDE support and build performance
| Component | Version | Purpose |
|---|---|---|
| Kotlin | 2.3.0 | Programming language |
| Compose Multiplatform | 1.9.3 | UI framework |
| Android Gradle Plugin | 8.11.2 | Android build system |
| kotlin-inject | 0.9.0 | Compile-safe dependency injection |
| kotlin-inject-anvil | 0.1.6 | Component merging for multi-module DI |
| KSP | 2.3.4 | Kotlin Symbol Processing |
| Spotless | 8.1.0 | Code formatting |
| ktlint | (via Spotless) | Kotlin linter |
| Compose Lints | 1.4.2 | Slack's Compose lint checks |
| Compose Rules | 0.4.26 | ktlint Compose rules |
| Android Target SDK | 36 | Android API level |
| Android Min SDK | 24 | Android 7.0+ support |
- β Compose Multiplatform (Material3, Foundation, Resources)
- β kotlin-inject runtime & compiler
- β kotlin-inject-anvil for multi-module DI
- β Spotless with ktlint and Compose rules
- β Slack Compose Lint checks
- β Kotlin Test framework
- β Gradle version catalogs (type-safe dependencies)
- β KSP for compile-time code generation
- β Proper JVM target configuration (Java 11)
- β Multi-module dependency injection setup
- β Automated code formatting on build
- β Compose best practices enforcement
Dependencies are managed in gradle/libs.versions.toml:
[versions]
ktor = "3.0.0"
[libraries]
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
[plugins]
kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }Then use in module build.gradle.kts:
sourceSets {
commonMain.dependencies {
implementation(libs.ktor.client.core)
}
}1. Define an injectable class in shared:
@Inject
class GreetingService(private val platform: Platform) {
fun greet(): String = "Hello from ${platform.name}!"
}2. Add to component:
@ContributesTo(AppScope::class)
interface GreetingComponent {
val greetingService: GreetingService
}3. Use in Android:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val app = application as YourNameApplication
val greeting = app.component.greetingService.greet()
setContent {
YourAppTheme {
Text(greeting)
}
}
}
}Update theme colors in designsystem/src/commonMain/kotlin/designsystem/theme/Color.kt:
val md_theme_light_primary = Color(0xFF6750A4)
val md_theme_light_onPrimary = Color(0xFFFFFFFF)
// ... customize all colorsUpdate typography in Theme.kt:
val YourAppTypography = Typography(
displayLarge = TextStyle(
fontFamily = YourCustomFont,
fontWeight = FontWeight.Bold,
fontSize = 57.sp,
),
// ... customize all text styles
)# Format all code
./gradlew spotlessApply
# Check formatting without changes
./gradlew spotlessCheck
# Run all lints
./gradlew lint
# Run tests
./gradlew testTo add desktop support:
1. Update shared/build.gradle.kts:
jvm("desktop")2. Add desktop source set:
val desktopMain by getting {
dependencies {
implementation(compose.desktop.currentOs)
}
}3. Create desktop app module or add desktop-specific code
Solution: Check imports use the correct package:
import com.yourcompany.yourapp.shared.resources.ResSolution:
./gradlew clean
./gradlew :shared:assembleSharedDebugXCFrameworkThen rebuild in Xcode.
Solution:
./gradlew spotlessApplyThis will auto-fix most formatting issues.
Solution: Clean and rebuild:
./gradlew clean
./gradlew :shared:kspCommonMainKotlinMetadata
./gradlew buildSolution: Check that:
- KSP plugin is applied to the module
- kotlin-inject dependencies are in
commonMain @Injectand@ContributesToannotations are used correctly- Rebuild the project
- Kotlin Multiplatform Documentation
- Compose Multiplatform Documentation
- Android KMP Library Plugin Guide
- kotlin-inject Documentation
- kotlin-inject-anvil Documentation
- Spotless Documentation
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Desktop platform support
- Web (Wasm) platform support
- Navigation library integration
- Network layer example (Ktor/Apollo-Kotlin)
- Local database example (SQLDelight/Room)
- CI/CD configuration (GitHub Actions)
- Documentation improvements
This template is available under the MIT License. See LICENSE for details.
This template was created to address the deprecation warnings in the default Kotlin Multiplatform wizard and to provide a production-ready starting point with modern tooling. It follows official recommendations from:
- Android's KMP Plugin Documentation
- JetBrains' KMP Project Structure Guide
- kotlin-inject Best Practices
Special thanks to:
- JetBrains for Compose Multiplatform and Kotlin
- Google for Android tooling and active development of Compose
- Evan Tatarka for
kotlin-inject - Amazon for
kotlin-inject-anvil - Slack for Compose Lint Checks
- Anthropic for Claude, which assisted in the design and documentation of this template
- Issues: GitHub Issues
- **Discussions **: GitHub Discussions
- Stack Overflow: Tag questions with
kotlin-multiplatformandcompose-multiplatform
Star β this repository if you find it useful!
Made with β€οΈ for the Kotlin Multiplatform community