A production-grade Kotlin Multiplatform starter template that removes weeks of setup work.
NexKMP is a carefully architected KMP foundation designed for teams building serious applications. It provides a modular project structure, custom build-logic conventions, a full compiler plugin infrastructure, and integrated quality tooling — all ready to scale from day one.
Most KMP templates are minimal scaffolds. NexKMP is different.
- Modular from day one — Clean separation between application, library, feature, and tooling modules with dedicated convention plugins for each type.
- Custom compiler plugin infrastructure — Ships with a logging compiler plugin that demonstrates IR transformations, annotation processing, and proper test harness setup. Use it as-is or as a blueprint for your own plugins.
- Build-logic conventions — Eight specialized Gradle convention plugins that eliminate boilerplate and enforce consistency across all modules.
- Integrated quality gates — Detekt, Ktlint (with Compose rules), and Kover code coverage are wired in and run on every CI build.
- CI/CD ready — GitHub Actions workflows with build, lint, test, coverage verification, and secret scanning (Gitleaks) out of the box.
- Template configuration system — Configure
APP_ID,PKG_ROOT,APP_NAME, and feature toggles (ENABLE_KSP,ENABLE_KCP) in one place.
This is the foundation you'd build in week three of a real project — shipped on day one.
# Clone the repository
git clone https://github.com/FurkanOzenworkshere/NexKMP.git
cd NexKMP
# Configure your app identity
$EDITOR gradle.properties # Set APP_ID, PKG_ROOT, APP_NAME
# Build and run
./gradlew :composeApp:assembleDebug # Android
open iosApp/iosApp.xcodeproj # iOS (Xcode)
# Run all checks (lint + tests + coverage)
./gradlew clean build testAll koverVerifyFor full project renaming:
# Preview what will change
scripts/init_template.sh --dry-run
# Apply template transformations
scripts/init_template.shNexKMP/
├── composeApp/ # Main Compose Multiplatform application
│ └── src/
│ ├── commonMain/ # Shared Kotlin/Compose code
│ ├── androidMain/ # Android-specific implementations
│ └── iosMain/ # iOS-specific implementations
│
├── core/
│ └── logger/ # Cross-platform logging infrastructure
│
├── tooling/
│ └── logger/
│ ├── plugin-annotations/ # @LogCall, @LogConstructor, @LogProperty
│ ├── compiler-plugin/ # IR transformations for compile-time logging
│ └── gradle-plugin/ # Gradle integration for the compiler plugin
│
├── build-logic/
│ └── convention/ # Gradle convention plugins (8 plugins)
│
├── iosApp/ # iOS app entry point (SwiftUI)
│
└── .github/workflows/ # CI/CD pipelines
NexKMP uses convention plugins to standardize module configuration. Add a single plugin and get all required setup automatically.
| Plugin ID | Purpose | Includes |
|---|---|---|
nexkmp.plugin.application |
Main app module | Android app, iOS targets, Compose, ViewModel, Lifecycle, Quality, Testing |
nexkmp.plugin.library |
Shared library modules | KMP targets, Android library, Quality |
nexkmp.plugin.feature |
Feature modules with UI | KMP targets, Compose, ViewModel, Lifecycle, Quality |
nexkmp.plugin.testing |
Test infrastructure | JUnit 5, Robolectric, Turbine, Coroutines Test |
nexkmp.plugin.quality |
Static analysis | Detekt, Ktlint (with Compose rules), Kover |
nexkmp.plugin.compiler.plugin |
Compiler plugin modules | BuildConfig, test fixtures, Kotlin compiler APIs |
nexkmp.plugin.gradle.plugin |
Gradle plugin modules | Plugin publishing, validation |
nexkmp.plugin.annotations.plugin |
Annotation libraries | KMP library setup |
Library module (no UI):
// feature/data/build.gradle.kts
plugins {
id("nexkmp.plugin.library")
}Feature module (with Compose UI):
// feature/home/build.gradle.kts
plugins {
id("nexkmp.plugin.feature")
}Both automatically configure:
- Android/iOS targets
- Kotlin context parameters (
-Xcontext-parameters) - SDK versions from
libs.versions.toml - Coroutines dependency
- Quality tooling
NexKMP ships with a production-quality Kotlin compiler plugin for structured logging. This demonstrates:
- IR transformations — Function call wrapping, constructor interception, property access logging
- Annotation-driven code generation —
@LogCall,@LogConstructor,@LogProperty - Privacy-aware logging — Built-in redaction rules with partial/full masking
- Test harness — Complete test infrastructure using Kotlin's internal test framework
@LogCall(level = LogLevel.DEBUG)
fun processPayment(amount: Double, cardNumber: String): Boolean {
// Compiler plugin automatically wraps this with timing, args, result logging
return paymentGateway.process(amount, cardNumber)
}
@LogConstructor
class UserSession(val userId: String, val token: String)Generates structured, serializable LogEvent objects:
LogEvent.Call(
level = DEBUG,
timeMs = 1702569600000,
fqName = "com.example.processPayment",
durationMs = 42,
args = mapOf("amount" to LogValue.N(99.99), "cardNumber" to LogValue.S("***2345")),
result = LogValue.B(true),
error = null
)val rule = RedactRule(mode = Mode.PARTIAL, keep = 4)
// "4111111111111234" → "************1234"┌─────────────────────────────────────────────────────────────────┐
│ composeApp │
│ (Application entry point - Android/iOS Compose UI) │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ core/logger │
│ (Cross-platform logging API, LogEvent, LogSink, RedactRule) │
└─────────────────────────────────────────────────────────────────┘
▲
│
┌─────────────────────────────────────────────────────────────────┐
│ tooling/logger/* │
│ ┌──────────────────┐ ┌───────────────────┐ ┌─────────────┐ │
│ │ plugin-annotations│ │ compiler-plugin │ │gradle-plugin│ │
│ │ (@LogCall, etc.) │ │ (IR transforms) │ │ (Gradle DSL)│ │
│ └──────────────────┘ └───────────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────────┘
▲
│
┌─────────────────────────────────────────────────────────────────┐
│ build-logic/convention │
│ (8 convention plugins - standardized module configuration) │
└─────────────────────────────────────────────────────────────────┘
- Compile time: Compiler plugin scans for
@LogCall/@LogConstructor/@LogPropertyannotations - IR transformation: Plugin wraps annotated code with
LoggerIntrinsics.logCall()calls - Runtime:
LoggerHubreceives structuredLogEventobjects - Output: Configurable
LogSinkimplementations handle persistence/transmission
| Category | Technology | Version |
|---|---|---|
| Language | Kotlin | 2.2.20 |
| UI | Compose Multiplatform | 1.8.2 |
| Async | Kotlinx Coroutines | 1.10.2 |
| Serialization | Kotlinx Serialization | 1.9.0 |
| DI | Koin | 4.1.0 |
| Android | Compile SDK 36 / Min SDK 24 | |
| Build | Gradle with Configuration Cache | |
| Testing | JUnit 5, Robolectric, Turbine | |
| Quality | Detekt, Ktlint, Kover |
| Command | Purpose |
|---|---|
./gradlew :composeApp:assembleDebug |
Build Android debug APK |
./gradlew testAll |
Run all unit tests across all modules |
./gradlew ktlintCheck |
Lint Kotlin code style |
./gradlew detekt |
Run static analysis |
./gradlew koverXmlReport |
Generate code coverage report |
./gradlew koverVerify |
Enforce coverage thresholds |
./gradlew clean build |
Full clean build |
GitHub Actions workflows are pre-configured:
ci.yml — Runs on every push/PR to main:
- JDK 17 + Android SDK setup
- Gradle wrapper validation
- Ktlint + Detekt static analysis
- Unit tests with coverage (
testAll,koverXmlReport,koverVerify) - Android build verification
- Report artifact upload
build.yml — Extended pipeline with:
- All of the above
- Gitleaks secret scanning
Configure in gradle.properties:
APP_ID=com.example.myapp # Android application ID
PKG_ROOT=com.example # Root package for code generation
APP_NAME=MyApp # Display name
ENABLE_KSP=true # Enable KSP processors
ENABLE_KCP=false # Enable compiler pluginPre-configured in gradle.properties:
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configuration-cache=true
org.gradle.configuration-cache.parallel=true
kotlin.incremental.native=trueThe convention plugins support iOS (arm64, x64, simulator) by default. To add Desktop or Web:
- Modify the appropriate convention plugin in
build-logic/convention/ - Add target configuration in
configureIOSPlatform()(or create newconfigureDesktopPlatform()) - Update source sets in consuming modules
Use tooling/logger/ as a template:
- Copy the structure:
plugin-annotations/,compiler-plugin/,gradle-plugin/ - Apply
nexkmp.plugin.compiler.pluginconvention - Implement your IR transformations in
compiler-plugin/src/main/kotlin/.../ir/ - Register your plugin in
LoggerPluginComponentRegistrarequivalent - Test using the built-in test harness infrastructure
- Add Desktop (JVM) target with convention plugin support
- Add Web (Wasm/JS) target support
- Project generator script for new feature modules
- Design system components library (
core-design-system)
- Navigation framework integration (Nav3)
- Network layer with Ktor conventions
- Local persistence with SQLDelight/Room conventions
- Analytics infrastructure module
- Crashlytics/error reporting integration
- CLI tool for project scaffolding
- IDE plugin for module generation
- Sample real-world app demonstrating all patterns
- Performance monitoring and build-time optimization tools
See CONTRIBUTING.md for package naming conventions, module structure, and contribution workflow.
# Development workflow
git checkout -b feature/your-feature
# ... make changes ...
./gradlew clean build testAll koverVerify
git commit -m "feat: your feature"
# Open PROpen for everyone.
Built with engineering discipline. Ready for production.