A feature-first Kotlin Multiplatform (KMP) architecture boilerplate for building scalable, maintainable mobile applications with shared business logic and flexible UI strategies.
KeystoneKMP is designed around:
- Feature isolation
- Replaceable infrastructure
- Predictable navigation
- Shared domain logic
- Clean dependency boundaries
This repository is a boilerplate, not a framework. It provides architectural structure and conventions that can be reused across multiple applications.
- Share business logic across platforms
- Prefer shared UI when possible
- Allow platform-specific UI when required
- Keep features independent and self-contained
- Make infrastructure replaceable
- Drive UI through state, not navigation calls
Features define intent.
Apps handle mechanics.
Infrastructure remains replaceable.
┌──────────────────────────┐
│ composeApp │
│ (Android App Shell) │
│ │
│ - Navigation Impl │
│ - DI Composition Root │
│ - Feature Entry Wiring │
└────────────┬─────────────┘
│
│
┌────────────▼─────────────┐
│ iosApp │
│ (iOS App Shell) │
│ │
│ - Native Navigation │
│ - DI Composition │
│ - Feature Entry Wiring │
└────────────┬─────────────┘
│
│
┌──────────────────────────▼──────────────────────────┐
│ Feature Modules │
│ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ featureLogin │ │ featurePayment│ ... │
│ │ │ │ │ │
│ │ - Entry API │ │ - Entry API │ │
│ │ - State │ │ - State │ │
│ │ - ViewModel │ │ - ViewModel │ │
│ │ - UI Flow │ │ - UI Flow │ │
│ └───────┬────────┘ └───────┬────────┘ │
│ │ │ │
└───────────┼────────────────────┼────────────────────┘
│ │
│ │
┌───────────▼────────────────────▼─────────────────────┐
│ Shared Infrastructure Modules │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Analytics│ │ Logger │ │ Network │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ ┌──────────────┐ ┌────────────────┐ │
│ │ designSystem │ │ localStorage │ │
│ └──────────────┘ └────────────────┘ │
│ │
│ (Provided by App via DI, consumed by Features) │
└──────────────────────────────────────────────────────┘
.
├── composeApp # Android application shell
├── iosApp # iOS application shell (Xcode project)
│
├── featureLogin # Example feature module
│
├── analytics # Analytics abstraction layer
├── designSystem # Shared design tokens & UI components
├── logger # Logging abstraction
├── network # Networking abstractions & clients
├── localStorage # Persistent storage abstractions
│
└── build / gradle # Build logic & tooling
Android application shell responsible for:
- Application entry point
- Navigation implementation (e.g., Navigation 3)
- Dependency Injection composition root
- Wiring feature entry definitions
Rules:
- ❌ No business logic
- ❌ No feature internals
- ✅ Owns infrastructure lifetimes
iOS application shell responsible for:
- SwiftUI / UIKit UI
- iOS navigation & lifecycle
- Dependency wiring
- Feature entry composition
Each feature is fully self-contained and owns:
- Business rules
- State & screen flow
- Feature entry point
- Platform-specific UI when necessary
Typical internal structure:
featureLogin
├── api # Public contracts (FeatureEntry, Navigator interfaces)
├── shared # KMP business logic & state
├── android # Compose UI + Android adapters
└── ios # SwiftUI / UIKit + iOS adapters
- Features do not depend on other feature implementations
- Features expose capabilities, not screens
- Features do not directly use navigation libraries
- Internal screen transitions are driven by state
The preferred approach is to share UI across platforms when feasible.
However, when platform-specific behavior, performance, or UX differences require it, native UI implementations can be used per platform.
This flexibility allows:
- Faster development with shared UI where appropriate
- Native UX fidelity when platform nuances matter
- Incremental migration between shared and platform-specific UI
These modules are reused across all features and provided by the app via dependency injection.
Provides analytics interfaces.
The app decides the actual analytics backend implementation.
Shared UI tokens and reusable components:
- Colors, typography, spacing
- Reusable composables / SwiftUI views
Rules:
- ❌ No feature-specific screens
- ❌ No navigation logic
- ✅ Stateless UI components only
Logging abstraction layer.
Features log through the interface; the app provides the concrete implementation.
Defines network client abstractions and factories.
A singleton instance is created and provided by the app using DI.
Key-value storage and caching abstractions with platform-specific implementations.
Navigation is intentionally split into two layers.
Handles:
- Entering and exiting features
- Deep links
- Back stack management
Owned by:
composeAppiosApp
Handled using state-driven UI instead of route-based navigation.
Example:
when (state.step) {
Step.Form -> FormScreen()
Step.Otp -> OtpScreen()
Step.Success -> SuccessScreen()
}This keeps feature flows encapsulated and testable without exposing internal screens to the app.
Each feature follows:
- One primary state owner (ViewModel)
StateFlowas the source of truth- UI emits events
- State determines which screen is rendered
Rules:
- No shared base ViewModel
- No navigation logic inside features
- Business logic stays inside feature layer
Koin is used for dependency injection.
Pattern:
- Features declare dependencies
- App provides singleton instances (network, logger, etc.)
- App loads all modules at startup
Rules:
- ❌ Features never create global singletons
- ❌ UI never wires dependencies manually
- ✅ App controls lifetimes and scopes
A keystone is the central stone that holds an arch together.
This architecture keeps:
- Features independent
- Infrastructure replaceable
- The system stable as it scales
This project does not aim to:
- Force fully shared UI across platforms
- Enforce a specific navigation library
- Provide a rigid framework or SDK
- Hide complexity behind heavy abstractions
Share what makes sense.
Specialize when necessary.
Isolate features.
Keep infrastructure replaceable.
Use KeystoneKMP as:
- A starting point for new KMP applications
- A reference architecture for modular mobile systems
- A foundation for scalable, feature-driven development
Clone, adapt, and trim modules based on your product needs.