Gamopedia is a modern, offline-first mobile application built with Kotlin Multiplatform (KMP) and Compose Multiplatform. It runs natively on both Android and iOS while sharing over 99% of the codebase, including UI, business logic, and data handling.
The app allows users to discover video games, search the RAWG database, view detailed information, and manage a local wishlist—all with a robust caching strategy that works seamlessly offline.
| Home Screen | Categories | Game Details | Search | Wishlist |
|---|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
| Android | iOS |
|---|---|
screen-20251222-132210.mp4 |
Simulator-Screen-Recording-iPhon.mp4 |
- Cross-Platform: Single codebase running on Android & iOS.
- Offline-First Architecture: Browsing history, game details, and search results are cached locally. The app remains fully functional without an internet connection.
- Smart Search: Search for games with debounce handling and local caching.
- Local Wishlist: Save your favorite games to a persistent local database (separated from cache to prevent data loss).
- Rich Media: High-quality image loading with memory caching.
- Reactive UI: Built entirely with Declarative UI (Compose) utilizing Unidirectional Data Flow (UDF).
This project uses the latest libraries in the Kotlin Multiplatform ecosystem:
| Category | Library | Description |
|---|---|---|
| Language | Kotlin | 100% Kotlin codebase. |
| UI Framework | Compose Multiplatform | Declarative UI shared across Android & iOS. |
| Architecture | MVVM + Repository | Clean architecture with separation of concerns. |
| Networking | Ktor | Asynchronous HTTP client for REST APIs. |
| DI | Koin | Pragmatic lightweight dependency injection. |
| Database | Room | Persistence library over SQLite. |
| Async | Coroutines & Flow | Managing background threads and reactive streams. |
| Navigation | Voyager | Multiplatform navigation library. |
| Image Loading | Coil 3 | Image loading for Compose Multiplatform. |
| Logging | Kermit | Centralized logging utility. |
| Config | BuildKonfig | Type-safe access to build configurations (API Keys). |
The app follows the Model-View-ViewModel (MVVM) pattern combined with the Repository Pattern to ensure a clean separation of concerns and a robust offline-first experience.
- UI Layer (Compose): Reactive UI that observes state from the ViewModel. It follows Unidirectional Data Flow (UDF).
- ViewModel: Holds the UI state and exposes it via
StateFlow. It acts as a bridge between the UI and the Data Layer. - Repository: The Mediator. It abstracts the data sources (Local vs Remote) from the rest of the app.
- Data Source:
- Local (Room): The Single Source of Truth (SSOT). The UI always displays data from here.
- Remote (Ktor): Used only to fetch fresh data and update the Local Database.
This project implements a "Stale-While-Revalidate" strategy using Reactive Streams (Flow).
- The UI subscribes to the Database immediately (showing cached data instantly).
- A background network call fetches fresh data from the API.
- The new data is saved to the Database.
- The Database automatically emits the new update to the UI.
├── di/ # Koin Dependency Injection modules
├── domain/ # Models and Entities
├── data/ # Repository implementation, API, and DB logic
├── database/ # Room Database setup and DAOs
├── network/ # Ktor HTTP client setup
├── viewmodel/ # Shared ViewModels (State Management)
└── ui/ # Shared Compose Multiplatform Screens```




