A modern e-commerce Android application built with Kotlin, Jetpack Compose, and Clean Architecture.
| Category | Technology |
|---|---|
| Language | Kotlin |
| UI | Jetpack Compose, Material 3 |
| Architecture | Clean Architecture + MVVM + MVI |
| DI | Hilt |
| Networking | Retrofit, OkHttp, Kotlinx Serialization |
| Local Database | Room |
| Local Preferences | DataStore |
| Image Loading | Coil |
| Pagination | Paging 3 |
| Navigation | Navigation Compose |
| Async | Coroutines + Flow |
| Testing | JUnit 5, MockK, Turbine, Compose UI Test |
The project follows the official Android architecture guidelines with a multi-module Clean Architecture approach.
┌──────────────────────────────────────────────────────────────────────────┐
│ APP LAYER │
│ App (@HiltAndroidApp) → MainActivity → NavHost → Feature Screens │
└──────────────────────────────────────────────────────────────────────────┘
│
┌──────────────────────────────────────────────────────────────────────────┐
│ FEATURE LAYER (MVVM + MVI) │
│ Screen (Compose) ←→ ViewModel (MVI) ←→ Contract (State/Event/Effect) │
└──────────────────────────────────────────────────────────────────────────┘
│
┌──────────────────────────────────────────────────────────────────────────┐
│ DOMAIN LAYER (Pure Kotlin) │
│ Use Cases → Repository Interfaces → Domain Models │
└──────────────────────────────────────────────────────────────────────────┘
│
┌──────────────────────────────────────────────────────────────────────────┐
│ DATA LAYER │
│ Repository Impl → Mappers → Remote API (Retrofit) + Local DB (Room) │
└──────────────────────────────────────────────────────────────────────────┘
│
┌──────────────────────────────────────────────────────────────────────────┐
│ CORE LAYER (Shared Infrastructure) │
│ common network database datastore designsystem │
└──────────────────────────────────────────────────────────────────────────┘
┌─────────────────────┐
│ app │
└──────┬──────┬───────┘
│ │
┌────────────┘ └────────────┐
v v
┌─────────────────┐ ┌──────────────────┐
│ feature/* │ ──────────► │ domain │
│ (auth, home, │ │ (use cases, │
│ product, cart, │ │ models, │
│ profile) │ │ interfaces) │
└────────┬─────────┘ └────────┬─────────┘
│ │
└──────────┐ ┌────────┘
v v
┌────────────────────────────┐
│ data │
│ (repo impl, DTOs, DAOs, │
│ mappers) │
└──────┬──────┬──────┬───────┘
│ │ │
┌───────┘ │ └────────┐
v v v
┌──────────┐ ┌────────────┐ ┌──────────────┐
│common │ │network │ │database │
└──────────┘ └────────────┘ └──────────────┘
│ │
└──────┐ ┌────────┘
v v
┌──────────────┐ ┌─────────────────┐
│datastore │ │designsystem │
└──────────────┘ └─────────────────┘
The application entry point. Hosts MainActivity, global NavHost, bottom navigation, and top-level Hilt modules (AppModule, NetworkModule).
Shared utilities, Kotlin extensions (ContextExt, FlowExt, StringExt, DateExt), resource wrappers (Resource<T>, UiEvent), and constants.
Retrofit + OkHttp infrastructure. Provides configured HTTP client, auth and logging interceptors, and a NetworkResult<T> call adapter for type-safe API responses.
Room database setup. Declares the CommerceDatabase abstract class with all DAOs. Includes type converters and the Hilt module that provides the database instance.
DataStore-backed user preferences (auth token, theme selection, onboarding state). Exposes reactive Flow reads and one-shot suspend writes.
Material 3 design system. Defines the app theme (CommerceTheme), palette, typography, shapes, and reusable component library (CommerceButton, CommerceTextField, CommerceCard, ErrorView, LoadingIndicator, etc.).
The innermost layer containing business logic. Defines domain models, repository interfaces, and use cases. Has zero framework dependencies — no Hilt, no Retrofit, no Room.
Implements repository interfaces from the domain layer. Orchestrates remote API calls (Retrofit) and local persistence (Room). Contains DTOs, entities, mappers for data transformation, and the DI module that binds implementations to interfaces.
Authentication flow: login, registration. MVI pattern with AuthContract (State/Event/Effect), AuthViewModel, and Compose screens.
Home dashboard: banner carousel, category grid, recommended product rows.
Product browsing: paginated list with filtering/sorting via Paging 3, and product detail page with image gallery.
Shopping cart: cart items list, quantity adjustment, checkout screen. Supports offline cart persistence.
User profile: profile display/edit, order history, app settings (theme, notifications, logout).
Each feature follows a consistent MVI contract pattern:
FeatureContract.kt
├── data class FeatureUiState — Immutable state snapshot
├── sealed interface FeatureUiEvent — User intents (click, scroll, type)
└── sealed interface FeatureSideEffect — One-shot effects (snackbar, navigation)
The ViewModel:
- Receives
UiEvents from the UI - Reduces them into new
UiStateviaStateFlow - Emits one-shot
SideEffects via a sharedChannel<SideEffect>→Flow
CommerceAndroidCompose/
├── app/
├── core/
│ ├── common/
│ ├── network/
│ ├── database/
│ ├── datastore/
│ └── designsystem/
├── data/
├── domain/
└── feature/
├── auth/
├── home/
├── product/
├── cart/
└── profile/
Each module follows the package convention com.example.commerce.<module>.
-
Clone the repository
git clone <repo-url>
-
Open in Android Studio — Use File → Open and select the project root.
-
Sync dependencies
./gradlew build
-
Run Select the
appconfiguration and run on a device/emulator (API 26+).
| Variant | Description |
|---|---|
| debug | Development, logging enabled |
| release | Optimized, no logging |
- JUnit 5 for test execution
- MockK for mocking
- Turbine for testing Kotlin Flows
- Location:
src/test/in each module
- Compose UI Test for Compose screen interaction
- Espresso for supplemental UI assertions
- Location:
src/androidTest/in feature modules
# Run all tests
./gradlew test
# Run all instrumented tests
./gradlew connectedAndroidTestDependency versions are managed centrally in gradle/libs.versions.toml (Gradle Version Catalog).
Key libraries:
- AndroidX: Core KTX, Activity Compose, Lifecycle, Navigation
- Compose: BOM, Material 3, UI, Tooling
- Hilt: DI, ViewModel injection, Navigation
- Retrofit: HTTP client, Kotlinx Serialization converter
- Room: Database, Coroutines support
- DataStore: Preferences, Proto DataStore
- Paging 3: Compose integration
- Coil: Async image loading
- Testing: JUnit 5, MockK, Turbine, Compose UI Test
- Separation of concerns: Business logic is isolated from framework details
- Testability: Domain layer is pure Kotlin — trivial to unit test
- Scalability: Feature modules can be developed independently
- Build time: Gradle parallelizes module builds; incremental changes are faster
- Unidirectional data flow — state is predictable and debuggable
- Immutable state — no accidental mutations
- Side effect channel — one-shot events (navigation, snackbar) don't survive configuration changes incorrectly
- Shared caching policies, offline-first logic, and cross-feature data access are easier with a unified data layer
- Simpler DI graph — one
RepositoryModuleinstead of one per feature - Avoids circular dependencies between feature data layers
Copyright 2026
Licensed under the Apache License, Version 2.0 ...