Skip to content

naikdp7/Keystonekmp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

KeystoneKMP

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.


✨ Key Principles

  • 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.


πŸ“Œ High level Diagram

                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                  β”‚        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)      β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“ Project Structure

.
β”œβ”€β”€ 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

πŸ“± App Modules

composeApp

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

iosApp

iOS application shell responsible for:

  • SwiftUI / UIKit UI
  • iOS navigation & lifecycle
  • Dependency wiring
  • Feature entry composition

🧩 Feature Modules

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

Feature Rules

  • 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

🎨 UI Strategy

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

πŸ”Œ Shared Infrastructure Modules

These modules are reused across all features and provided by the app via dependency injection.

analytics

Provides analytics interfaces.
The app decides the actual analytics backend implementation.

designSystem

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

logger

Logging abstraction layer.
Features log through the interface; the app provides the concrete implementation.

network

Defines network client abstractions and factories.
A singleton instance is created and provided by the app using DI.

localStorage

Key-value storage and caching abstractions with platform-specific implementations.


🧭 Navigation Model

Navigation is intentionally split into two layers.

App-Level Navigation

Handles:

  • Entering and exiting features
  • Deep links
  • Back stack management

Owned by:

  • composeApp
  • iosApp

Feature-Internal Navigation

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.


πŸ§ͺ ViewModel & State Management

Each feature follows:

  • One primary state owner (ViewModel)
  • StateFlow as 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

πŸ”§ Dependency Injection

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

πŸš€ Why β€œKeystone”?

A keystone is the central stone that holds an arch together.

This architecture keeps:

  • Features independent
  • Infrastructure replaceable
  • The system stable as it scales

❌ Non-Goals

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

🧭 Guiding Philosophy

Share what makes sense.
Specialize when necessary.
Isolate features.
Keep infrastructure replaceable.


πŸ“Œ Intended Usage

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.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors