Skip to content

KMP (Kotlin Multiplatform) Support #13

Description

@easyhooon

Overview

Dari is currently an Android-only library. Kotlin Multiplatform (KMP) support remains a long-term roadmap item, but the migration should start by separating portable contracts from Android-specific runtime boundaries rather than promising a full platform rewrite up front.

The main blocker is not that every current dependency is Android-only. Room, Compose, and DataStore all have multiplatform paths. The harder part is that Dari's current runtime is shaped around Android app framework APIs: Context, Application, AndroidX Startup, Activity/Intent navigation, WebView integration, notifications, launcher shortcuts, sensors, and permission flows.

Current architecture

dari-core/    -> Shared models and contracts, close to KMP-ready
dari/         -> Android runtime and UI
dari-noop/    -> Android no-op runtime

Portable candidates

These areas are likely candidates for common code:

  • MessageEntry, DariConfig, DariInterceptor, MessageStatus, MessageDirection
  • Request/response matching and message lifecycle rules
  • Exportable message formatting
  • JSON handling through kotlinx.serialization
  • Preferences through DataStore KMP, with platform-specific file creation
  • Persistence through Room KMP, SQLDelight, or another KMP-compatible storage layer
  • Parts of the Compose UI, if screen ownership and navigation are separated from Android Activity

Android-specific boundaries

These areas need platform-specific abstractions or Android-only implementations:

  • Android WebView bridge integration
  • Context and Application access
  • AndroidX Startup auto-initialization
  • Activity and Intent based navigation
  • Notifications
  • Launcher shortcuts
  • Shake sensor access
  • Runtime permissions

Migration plan

Phase 1: Convert shared contracts first

  • Convert dari-core to a KMP module
  • Move shared models and interfaces to commonMain
  • Keep Android publication coordinates compatible for existing consumers
  • Add API compatibility checks before changing more runtime code

Phase 2: Define runtime boundaries

  • Identify which APIs belong to the shared contract and which are Android runtime APIs
  • Introduce minimal platform interfaces only where they replace direct Android framework access
  • Keep Dari.createInterceptor() and dari-noop behavior stable for Android consumers

Phase 3: Evaluate storage options

  • Prototype Room KMP with the current message schema
  • Compare Room KMP with SQLDelight for schema control and generated API ergonomics
  • Keep DataStore for preferences if the platform file setup remains small

Phase 4: Evaluate UI portability

  • Separate inspector screen state from Activity ownership
  • Check which Compose UI pieces can move to common code
  • Keep Android-specific entry points for notifications, intents, and permissions

Phase 5: Add non-Android targets only after the boundaries are proven

  • Add an iOS target only after shared contracts, persistence, and UI boundaries are stable
  • Define platform-specific integration points for iOS WebView bridge capture
  • Add platform no-op stubs where needed

Non-goals for the first pass

  • Do not rewrite the full Android runtime in one change
  • Do not replace Room only because it is currently Android-scoped
  • Do not promise iOS feature parity before WebView bridge integration is designed
  • Do not break existing Android setup for a speculative multiplatform target

Notes

  • dari-core is the safest first step because it has no Android framework dependency today.
  • Room, Compose, and DataStore should be evaluated as KMP-compatible options, not treated as automatic blockers.
  • The first useful milestone is a clearer Android/runtime boundary, even before adding a second platform.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions