This is a Kotlin Multiplatform project targeting Android, iOS, Desktop (JVM), and Server. It allows for sharing code across different platforms, reducing development time and ensuring consistency.
The project is organized into several modules, each serving a distinct purpose. Here's an overview of the key modules:
flowchart TD
subgraph "Platform-Specific Apps"
S[":server"]
APP[":library:app"]
end
subgraph "Feature Modules"
FL[":library:feature:login"]
FLR[":library:feature:learning"]
FD[":library:feature:dictionary"]
end
subgraph "Domain"
D[":library:domain"]
DA[":library:domain:auth"]
end
subgraph "Data"
N[":library:data:network"]
DB[":library:data:database"]
PR[":library:data:preferences"]
end
subgraph "Core"
LOG[":library:core:logger"]
UT[":library:core:utils"]
PRM[":library:core:permission"]
FB[":library:core:firebase"]
end
subgraph "Design System"
DS[":library:design-system"]
end
subgraph "Shared (Client + Server)"
AC[":api-contracts"]
end
APP --> FL
APP --> FLR
APP --> FD
APP --> DS
FL --> DA
FLR --> D
FD --> D
DA --> D
D --> N
D --> DB
D --> PR
N --> AC
N --> LOG
DB --> LOG
PR --> LOG
D --> LOG
D --> UT
S --> AC
Defines shared DTOs and API route definitions. Consumed by :library:data:network on the client
side and :server on the backend, ensuring a type-safe contract between both ends.
- Targets:
commonMain - Key Libraries: Kotlinx Serialization
Ktor-based backend server. Consumes :api-contracts to expose type-safe endpoints matching what the
client expects.
- Targets: JVM
- Key Libraries: Ktor Server
Feature modules contain UI and presentation logic for a specific user-facing area. They depend on domain modules for business logic and on the design system for UI components.
Handles authentication flows — sign-in, sign-up, and session restore. Depends on
:library:domain:auth for authentication-specific use cases.
- Targets:
commonMain
Learning experience feature. Depends on :library:domain for shared use cases and domain models.
- Targets:
commonMain
Dictionary and vocabulary feature. Depends on :library:domain for shared use cases and domain
models.
- Targets:
commonMain
Domain modules contain business logic, use cases, and domain models (DomainModel — no suffix).
They are free of any framework or platform dependency.
Houses shared business logic, use cases, and domain models used across multiple features.
Sub-domains (e.g. :domain:auth) extend this layer for feature-specific business rules.
- Targets:
commonMain,androidMain,iosMain,jvmMain - Key Libraries: Kotlinx Coroutines
- Todo: Split into sub-domains
Authentication-specific use cases and domain models — login, session, and token management. Depends
on :library:domain for shared domain primitives.
- Targets:
commonMain - Key Libraries: Kotlinx Coroutines
Data modules handle all I/O concerns — network, local database, and preferences. They expose
repositories consumed by the domain layer and work with Dto objects from :api-contracts at the
network boundary.
Implements the network client for API communication. Consumes :api-contracts DTOs for type-safe
requests and responses, and maps them to domain models before exposing them upward.
- Targets:
commonMain,androidMain,iosMain,jvmMain(platform-specific Ktor engines) - Key Libraries: Ktor Client
Manages local data persistence using a multiplatform database solution.
- Targets:
commonMain,androidMain,iosMain,jvmMain(platform-specific drivers) - Key Libraries: Room
Handles lightweight key-value storage for user preferences and app settings.
- Targets:
commonMain,androidMain,iosMain,jvmMain - Key Libraries: DataStore
Core modules provide low-level, domain-agnostic utilities. They have no knowledge of features, domain, or data layers and can be depended on by any module.
Provides a shared logging abstraction across all client modules.
- Targets:
commonMain - Key Libraries: Kermit
General-purpose utility functions and extensions shared across client modules.
- Targets:
commonMain - Todo: Split into sub-domains (e.g Navigation)
Abstracts platform-specific permission handling (camera, location, etc.).
- Targets:
commonMain,androidMain,iosMain
Firebase integration — analytics, crash reporting, and other Firebase services — shared across client modules.
- Targets:
commonMain,androidMain,iosMain - Key Libraries: GitLive Firebase KMP SDK
Contains reusable, domain-agnostic UI components, theming, and typography shared across all features. Has no dependency on domain or data layers.
- Targets:
commonMain - Key Libraries: Compose Multiplatform
The top-level shared UI entry point. Wires together feature modules, applies the design system, and hosts navigation and app-level scaffolding.
- Targets:
commonMain,androidMain,iosMain,jvmMain - Key Libraries: Compose Multiplatform
| Layer | Suffix | Example |
|---|---|---|
:api-contracts DTOs |
Dto |
UserDto, LoginResponseDto |
:library:domain models |
none | User, LoginResult |
DTOs represent the raw wire format exchanged with the server. Domain models are the canonical
representation used throughout the app. Mapping between the two happens at the data layer boundary (
e.g. UserDto.toDomain(): User).
This project leverages Gradle's build-logic module to centralize and manage build configurations
through convention plugins. This approach promotes:
- Consistency: Ensures uniform application of settings, dependencies, and plugins across similar modules.
- Maintainability: Simplifies updates to build configurations as changes are made in one place.
- Readability: Reduces boilerplate in individual module
build.gradle.ktsfiles, making them cleaner and focused on module-specific declarations.
Convention plugins are defined as Kotlin classes plugins (e.g., ApplicationPlugin,
LibraryPlugin) within the /build-logic/src/main/kotlin directory.
Modules can then apply these conventions using a simple plugin ID, for example:
// In a module's build.gradle.kts
plugins {
id("kotlin-multiplatform-convention")
// ... other plugins
}This setup helps in managing a complex multi-module project more efficiently.
In Kotlin Multiplatform modules, you'll typically find the following source sets:
commonMain: Code that is common to all targeted platforms.androidMain: Kotlin code specific to the Android platform.iosMain: Kotlin code specific to the iOS platform (compiled to Native).jvmMain: Kotlin code specific to JVM environments (e.g., Desktop applications).(platform)Test: Unit tests for a specific platform, e.g.commonTest,jvmTest.
For detailed build and run instructions for each platform, please refer to the following sections.
Check formatting:
./gradlew ktlintCheckAuto-fix formatting:
./gradlew ktlintFormatGenerate HTML coverage report:
./gradlew koverHtmlReportReport: build/reports/kover/html/index.html
Run on all modules and merge reports:
./gradlew detektAllRun on a specific module:
./gradlew :module:path:detektReport: build/reports/detekt/merge.sarif
Generate HTML documentation:
./gradlew dokkaGeneratePublicationHtmlFor multi-module aggregated docs:
./gradlew dokkaGenerateModuleHtmlOutput: build/dokka/html/index.html
To build and run the development version of the Android app, use the run configuration from the run widget in your IDE’s toolbar or build it directly from the terminal:
- on macOS/Linux
./gradlew :app:app:assembleDebug
- on Windows
.\gradlew.bat :app:app:assembleDebug
To build and run the development version of the desktop app, use the run configuration from the run widget in your IDE’s toolbar or run it directly from the terminal:
- on macOS/Linux
./gradlew :app:app:run
- on Windows
.\gradlew.bat :app:app:run
To build and run the development version of the server, use the run configuration from the run widget in your IDE’s toolbar or run it directly from the terminal:
- on macOS/Linux
./gradlew :server:run
- on Windows
.\gradlew.bat :server:run
To build and run the development version of the iOS app, use the run configuration from the run
widget in your IDE’s toolbar or open the [./iosApp](./iosApp) directory in Xcode and run it from
there.
**Note on Libraries:
** The key libraries mentioned are indicative. For a complete list of dependencies for each module,
please refer to the
build.gradle.kts (or build.gradle) file within that module's directory.
Learn more about Kotlin Multiplatform…
This section outlines planned improvements and potential areas for future development:
-
Secure Data Storage on Android (SQLCipher/Room):
- Investigate and implement encrypted local database storage on Android. This involves replacing
the current placeholder database in the
/app/databasemodule with a robust solution like Room, potentially with SQLCipher for an added layer of security to protect sensitive user data.
- Investigate and implement encrypted local database storage on Android. This involves replacing
the current placeholder database in the
-
Firebase Authentication (Server-Side):
- Implement user authentication on the
/serverusing the Firebase Admin SDK. The server will handle token verification and user management, providing a secure authentication flow for all client applications.
- Implement user authentication on the
-
Koin Dependency Injection Module Verification:
- Enhance testing by adding integrity checks for Koin modules. This involves writing tests (
likely in
commonTestor platform-specific test source sets) that utilize Koin's testing utilities to verify that all dependency graphs can be correctly resolved at runtime.
- Enhance testing by adding integrity checks for Koin modules. This involves writing tests (
likely in
-
Continuous Integration/Continuous Deployment (CI/CD) with GitHub Actions:
- Set up GitHub Actions workflows to automate the building, testing, and potentially deployment of the Android app, iOS app (if feasible via command-line tools), desktop app, and server application. This will ensure code quality and streamline the release process.
-
Auto generation of Mermaid graph: *Make it reflect the current module dependency graph with a gradle task.
-
Setup Linter: