Skip to content

Repository files navigation

MemGym

MemGym is a cross-platform educational quiz application designed to make studying more interactive and measurable. The app lets users study topic-based facts through multiple-choice and short-answer quizzes, while tracking their scores and progress.

It is built with Kotlin Multiplatform and Compose Multiplatform, targeting Android, iOS, and Web from a shared codebase. This project demonstrates how to build a production-style application while maintaining a consistent user experience across multiple platforms. More than 85% of the application code is shared, including domain logic, data access, state management, navigation, and Compose UI.

Highlights

  • Cross-platform application for Android, iOS, JavaScript Web, and Kotlin/Wasm Web
  • More than 85% shared code across supported platforms
  • Shared quiz engine with reusable progression and scoring logic
  • Multiple quiz formats, including:
    • Multiple choice
    • Short answer
  • Topic-based learning content
  • Score tracking and quiz completion statistics
  • Elapsed quiz-time tracking
  • Optional images for individual facts
  • Persistent local storage
  • Reactive UI state management with Kotlin StateFlow
  • Dependency injection with Koin
  • Unit tests for core quiz behavior and scoring logic
  • Platform-specific implementations where native functionality is required

Technical Overview

Kotlin Multiplatform

Kotlin Multiplatform allows MemGym to share application logic across Android, iOS, and Web while still supporting platform-specific integrations when necessary.

The shared module contains the majority of the application, while platform-specific source sets provide implementations for functionality such as database initialization and native application entry points.

Supported targets include:

  • Android
  • iOS arm64
  • iOS Simulator
  • JavaScript Web
  • Kotlin/Wasm Web

Compose Multiplatform

The user interface is built with Compose Multiplatform. This enables the same declarative UI approach and reusable composable components across Android, iOS, JavaScript, and Wasm.

Shared UI includes:

  • Topic and quiz screens
  • Multiple-choice question layouts
  • Short-answer question layouts
  • Answer feedback
  • Progress indicators
  • Completion summaries
  • Reusable fact-image components
  • Cross-platform navigation

This approach keeps the visual experience consistent while reducing duplicated presentation code.

Shared Quiz Engine

The quiz engine is implemented as reusable shared Kotlin logic rather than being tied to a specific screen or operating system.

The quiz session is responsible for:

  • Shuffling questions
  • Tracking the current question
  • Tracking correct answers
  • Reporting quiz progress
  • Determining when a session is complete
  • Measuring elapsed quiz time
  • Supporting deterministic testing through injectable randomness and time sources

Quiz formats are modeled as an extensible domain concept, allowing additional formats to be added without redesigning the application foundation.

Architecture

MemGym follows a layered architecture inspired by Clean Architecture principles:

Presentation

  • Compose screens, ViewModels, UI state

Domain

  • Facts, topics, quiz formats, quiz sessions, statistics

Data

  • Repositories, Room database, DAOs, platform database builders

The architecture separates responsibilities so that:

  • UI code focuses on rendering state and handling user interaction
  • ViewModels coordinate screen behavior and expose observable UI state
  • Domain logic remains platform-independent and testable
  • Repositories abstract data access from the rest of the application
  • Platform-specific database setup is isolated behind Kotlin Multiplatform expect/actual declarations

Persistence and Dependency Injection

MemGym uses Room 3 for local persistence and SQLite drivers appropriate to each platform.

The database layer stores learning content and topic-related information while exposing shared data access APIs. Platform-specific database builders are provided for Android, iOS, JavaScript, and Wasm targets.

Koin is used for dependency injection, allowing repositories, database components, and ViewModels to be provided consistently across platforms. This reduces manual object creation and makes application components easier to test and replace.

Running the Project

Android Build the Android debug application with: ./gradlew :androidApp:assembleDebug

The Android application can also be launched using the run configuration provided by the IDE.

Web with Kotlin/Wasm Kotlin/Wasm is the recommended web target for modern browsers: ./gradlew :webApp:wasmJsBrowserDevelopmentRun

Web with JavaScript The JavaScript target provides support for browsers that do not support Kotlin/Wasm: ./gradlew :webApp:jsBrowserDevelopmentRun

iOS Open the iosApp directory in Xcode and run the application using an iOS simulator or connected device.

Running Tests

Android ./gradlew :shared:testAndroidHostTest

Kotlin/Wasm ./gradlew :shared:wasmJsTest

JavaScript ./gradlew :shared:jsTest

iOS Simulator ./gradlew :shared:iosSimulatorArm64Test

Image Content

Facts can optionally reference a bundled image: Fact( id = "kotlin_multiplatform", prompt = "What is Kotlin Multiplatform?", answer = "A technology for sharing Kotlin code across platforms", imageResourceName = "kotlin_multiplatform" )

Fact images are stored in: shared/src/commonMain/composeResources/drawable

Compose Multiplatform resource handling allows the same fact-image component to display supported image formats across Android, iOS, JavaScript, and Kotlin/Wasm.

Engineering Takeaways

MemGym was built to explore and demonstrate several practical software engineering concepts:

  • Designing shared business logic for multiple platforms
  • Balancing code reuse with platform-specific requirements
  • Building reactive interfaces with Compose and StateFlow
  • Structuring a project around domain, data, and presentation layers
  • Creating reusable components for multiple quiz experiences
  • Persisting application data with a multiplatform database strategy
  • Using dependency injection to improve modularity and testability
  • Writing deterministic tests for time- and randomness-dependent logic
  • Supporting both modern Kotlin/Wasm and JavaScript web targets

Technology Stack

  • Kotlin
  • Kotlin Multiplatform
  • Compose Multiplatform
  • Kotlin Coroutines
  • Kotlin StateFlow
  • AndroidX ViewModel
  • AndroidX Navigation Compose
  • Room 3
  • SQLite
  • Koin
  • Kotlin Serialization
  • Kotlin/Wasm
  • Kotlin/JS
  • Gradle Kotlin DSL
  • Xcode and Swift for the iOS application entry point

Future Improvements

  • User-created topics and facts
  • Cloud synchronization across devices
  • Additional quiz formats
  • Spaced-repetition scheduling
  • More detailed learning analytics
  • Authentication and user profiles
  • Expanded accessibility support
  • Automated release builds for each platform

About

Cross-platform quiz & memorization app for iOS, Android, and Web built with Kotlin Multiplatform.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages