README.en.md

May 28, 2026 · View on GitHub

中文

A Compose Multiplatform open-source Github client App, sharing a single Kotlin / Compose code base across Android / Desktop JVM (macOS + Windows + Linux) / iOS / macOS Native — 5 targets in total. It aims to better manage and maintain personal Github projects daily, offering a richer feature set and a more consistent cross-platform experience~~Σ( ̄。 ̄ノ)ノ. The repo's rootProject is GSYGithubAppCompose, and various counterparts are provided for comparison:

Official AccountJuejinZhihuCSDNJianshu
GSYTechClick MeClick MeClick MeClick Me

Official Account QR Code

A cross-platform App built on Compose Multiplatform 1.10.3 + Kotlin 2.3.20.
A single repository ships Android / Desktop JVM (macOS + Windows + Linux) / iOS / macOS Native at the same time.

The project's goal is to facilitate daily maintenance and browsing of Github,
and it is also a great playground for learning Compose Multiplatform — covering KMP targets,
expect/actual, multiplatform navigation, multiplatform ViewModel/Lifecycle, Ktor networking,
Koin DI, Coil image loading, Apollo GraphQL and more.

Based on usage and feedback, the user experience and features will be updated and improved
from time to time. Feel free to raise issues.

Github Actions GitHub stars GitHub forks GitHub issues GitHub license

The 5 Targets at a Glance (Compose Multiplatform Targets)

PlatformKMP TargetEntry ModuleKey Identifiers
AndroidandroidTargetandroidAppapplicationId com.shuyu.gsygithubappcompose, minSdk 24, compileSdk 36
Desktop JVM (macOS + Windows + Linux)jvmdesktopAppmainClass com.shuyu.gsygithubappcompose.desktop.MainKt, targetFormats Exe / Msi / Dmg / Deb
iOS (Device)iosArm64iosAppXcodeGen + bundle id com.shuyu.gsygithubappcompose, deploymentTarget iOS 15.0
iOS (Simulator)iosSimulatorArm64iosAppSame as above, runs on Apple Silicon Simulator
macOS NativemacosArm64composeShared framework + native hostApple Silicon native framework

Shared cross-platform code lives in the commonMain of composeShared, core, data and feature; each platform entry module only acts as a minimal host.

How to Compile and Run

Environment Requirements:

  • AGP 9.0.0 — Android Studio Otter (2025.1.1) Feature Drop or higher is required to build Android successfully.
  • Compose Multiplatform 1.10.3 + Kotlin 2.3.20 — using a matching IntelliJ IDEA / Android Studio toolchain is recommended.
  • iOS / macOS Native targets require a macOS host with Xcode 15+, xcodegen and xcodebuild installed.
  • Desktop JVM packaging (Dmg / Msi / Deb) is provided by Compose Desktop and must run on the corresponding host OS.

Important: You need to configure the local.properties file in the project root (see local.properties.sample) and enter your registered Github client_id and client_secret.

ndk.dir="xxxxxxxx"
CLIENT_ID = "xxxxxx"
CLIENT_SECRET = "xxxxxx"

Portal to register a Github APP , of course, the prerequisite is that you have a Github account (~ ̄▽ ̄)~.

The Github API requires secure (authorized) login, so you must fill in the Authorization callback URL field as follows when registering your Github App:

gsygithubapp://authed

Build Commands for All 5 Targets

# 1) Android (debug apk, installed on [androidApp](file:///Users/guoshuyu/workspace/android/GSYGithubAppCMP/androidApp))
./gradlew :androidApp:assembleDebug

# 2) Desktop JVM run (dev mode: any of macOS / Windows / Linux)
./gradlew :desktopApp:run

# 3) Desktop JVM platform-native installers
./gradlew :desktopApp:packageDmg     # macOS  → .dmg
./gradlew :desktopApp:packageMsi     # Windows → .msi
./gradlew :desktopApp:packageDeb     # Linux   → .deb

# 4) iOS: generate the Xcode project with XcodeGen, then build with xcodebuild (inside [iosApp](file:///Users/guoshuyu/workspace/android/GSYGithubAppCMP/iosApp))
cd iosApp && xcodegen generate
xcodebuild -project iosApp.xcodeproj -scheme iosApp -configuration Debug \
  -destination 'generic/platform=iOS Simulator' build

# 5) Compose Multiplatform Framework artifacts (linked by iOS / macOS hosts)
./gradlew :composeShared:linkDebugFrameworkIosSimulatorArm64
./gradlew :composeShared:linkDebugFrameworkMacosArm64

For a step-by-step developer onboarding flow across all 5 targets, see QUICK_START.md.

Project Structure Diagrams

KeyFeatures

Core Technologies

Layer Structure

Technology Stack

Data Flow Architecture

Overall Architecture Diagram

┌─────────────────────────────────────────────────────────────────────────┐
│                          GSYGithubAppCompose                            │
│              (Compose Multiplatform + KMP + MVVM + Koin)                │
└─────────────────────────────────────────────────────────────────────────┘

        ┌──────────────┬────────────┼────────────┬──────────────┐
        │              │            │            │              │
   ┌────▼───┐    ┌─────▼────┐  ┌────▼───┐  ┌────▼───┐    ┌─────▼─────┐
   │androidApp│  │desktopApp│  │ iosApp │  │macosApp│    │ Web (TBD) │
   │(android  │  │  (jvm)   │  │(iosArm/│  │(macos  │    │ (planned) │
   │ Target)  │  │          │  │ iosSim)│  │ Arm64) │    │            │
   └────┬─────┘  └────┬─────┘  └────┬───┘  └────┬───┘    └────────────┘
        │             │             │           │
        └─────────────┴──────┬──────┴───────────┘

                ┌────────────▼────────────┐
                │      composeShared      │
                │ (cross-platform UI hub) │
                └────────────┬────────────┘

        ┌────────────────────┼────────────────────┐
        │                    │                    │
 ┌──────▼──────┐    ┌────────▼────────┐    ┌─────▼──────┐
 │  feature/*  │    │      data       │    │   core/*   │
 │ (13 modules)│    │ Repository      │    │ network/db │
 └─────────────┘    └─────────────────┘    │ common/ui  │
                                           └────────────┘

Module Dependency Diagram

                ┌────────────┐ ┌────────────┐ ┌────────┐ ┌─────────┐
                │ androidApp │ │ desktopApp │ │ iosApp │ │macosHost│
                └─────┬──────┘ └─────┬──────┘ └────┬───┘ └────┬────┘
                      │              │             │          │
                      └──────┬───────┴─────────────┴──────────┘

                       ┌─────▼─────┐
                       │composeShared│
                       └─────┬─────┘

        ┌────────────────────┼────────────────────────┐
        │                    │                        │
 ┌──────▼──────┐      ┌──────▼──────┐         ┌──────▼──────┐
 │  feature/*  │      │    data     │         │   core/ui   │
 │             │      │             │         │             │
 │ All Feature │◄─────┤ Repository  │         │ Common UI   │
 │   Modules   │      │             │         │ Components  │
 └──────┬──────┘      └──────┬──────┘         └──────┬──────┘
        │                    │                       │
        │            ┌───────┼────────┐              │
        │            │       │        │              │
        └────────────┼───────┼────────┼──────────────┘
                     │       │        │
         ┌───────────▼─┐  ┌──▼────────▼──┐  ┌──────────────┐
         │core/network │  │core/database │  │ core/common  │
         │             │  │              │  │              │
         │ Ktor 3.1.0  │  │   Room KMP   │  │ DataStore    │
         │ Apollo      │  │   Entity/DAO │  │  Token       │
         │ Models      │  │              │  │  Resources   │
         └─────────────┘  └──────────────┘  └──────────────┘

Dependency Rules:
  androidApp / desktopApp / iosApp / macosHost → composeShared
  composeShared → feature/*, core/ui, data
  feature/*    → data, core/ui, core/common
  data         → core/network, core/database, core/common
  core/ui      → core/common
  core/network → (Independent Module)
  core/database→ (Independent Module)
  core/common  → (Independent Module)

Detailed Module Structure

GSYGithubAppCompose/

├── androidApp/                             # Android entry host (applicationId com.shuyu.gsygithubappcompose)
│   ├── MainActivity.kt                     # Main entry, mounts composeShared
│   ├── GSYApplication.kt                   # Application, Koin startup
│   └── di/AppModule.kt                     # Android-specific module

├── desktopApp/                             # Desktop JVM entry (mainClass com.shuyu.gsygithubappcompose.desktop.MainKt)
│   ├── Main.kt                             # singleWindowApplication entry
│   ├── language/JvmLanguageDataStore.kt    # JVM DataStore adapter
│   ├── session/DesktopUserSession.kt       # Desktop session
│   └── diagnostics/StartRouteDiagnostics.kt# Startup route diagnostics

├── iosApp/                                 # iOS entry host (XcodeGen + Swift shell)
│   ├── project.yml                         # XcodeGen project description
│   ├── iosApp/iOSApp.swift                 # SwiftUI App entry
│   ├── iosApp/ContentView.swift            # Hosts composeShared MainViewController
│   └── iosApp/Assets.xcassets/             # AppIcon / launch_image (shared with Android)

├── composeShared/                          # Cross-platform UI hub + iOS glue
│   └── src/iosMain/kotlin/.../MainViewController.kt

├── core/                                   # Core base modules (commonMain-first)
│   │
│   ├── network/                            # Network layer (Ktor 3.1.0 + Apollo GraphQL)
│   │   ├── api/GitHubApiService.kt         # GitHub REST API interface (commonMain)
│   │   ├── graphql/                        # Apollo schema + queries
│   │   └── di/NetworkModule.kt             # Koin 4.2.1 module
│   │
│   ├── database/                           # Database layer (Room KMP)
│   │   ├── entity/                         # Entities (commonMain)
│   │   ├── dao/                            # DAOs
│   │   └── AppDatabase.kt
│   │
│   ├── common/                             # Common resources / DataStore / i18n
│   │   ├── composeResources/               # Compose Multiplatform resources (drawable / files / values)
│   │   │   ├── drawable/ic_launcher.png    # Single source of truth for AppIcon (5 targets)
│   │   │   ├── drawable/launch_image.png   # Single source of truth for LaunchScreen (5 targets)
│   │   │   └── files/launcher_lottie.json
│   │   └── androidMain/res/                # Android mipmap resources (mirrored from commonMain)
│   │
│   └── ui/                                 # UI components / theme / navigation
│       ├── components/                     # GSYPullRefresh / GSYTopAppBar etc.
│       ├── theme/                          # Material 3
│       └── navigation/                     # Built on jetbrains-navigation-compose 2.9.1

├── data/                                   # Data layer (Repository + expect/actual Dispatcher)
│   ├── commonMain/.../repository/          # Cross-platform Repository implementations
│   ├── androidMain/.../Dispatchers.android.kt
│   ├── jvmMain/.../Dispatchers.jvm.kt
│   ├── iosMain/.../Dispatchers.ios.kt
│   └── macosMain/.../Dispatchers.macos.kt

└── feature/                                # 13 feature modules (all commonMain)
    ├── welcome/                            # Welcome screen
    ├── login/                              # OAuth login
    ├── home/                               # Home (bottom navigation)
    ├── dynamic/                            # Dynamic (event stream)
    ├── trending/                           # Trending
    ├── profile/                            # Profile
    ├── search/                             # Search
    ├── detail/                             # Repository detail
    ├── code/                               # Code browsing
    ├── issue/                              # Issue management
    ├── push/                               # Push management
    ├── list/                               # List
    ├── notification/                       # Notifications
    ├── info/                               # Info
    └── history/                            # Browsing history

Per-module build scripts: androidApp/build.gradle.kts, desktopApp/build.gradle.kts, composeShared/build.gradle.kts, iosApp/project.yml; the version catalog is at gradle/libs.versions.toml.

Technology Architecture Diagram

┌─────────────────────────────────────────────────────────────────────┐
│                         Tech Stack                                   │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  Cross-platform        Compose Multiplatform 1.10.3                 │
│                        Kotlin 2.3.20 + AGP 9.0.0                    │
│                        KMP targets: androidTarget / jvm /           │
│                        iosArm64 / iosSimulatorArm64 / macosArm64    │
│  ├─────────────────────────────────────────────────────────────┤   │
│                                                                     │
│  UI Layer              Compose Multiplatform + Material 3           │
│                        jetbrains-navigation-compose 2.9.1           │
│                        jetbrains-lifecycle 2.10.0                   │
│                        Coil 2.7.0 (Image Loading)                   │
│                        Lottie (Complex Animations)                  │
│  ├─────────────────────────────────────────────────────────────┤   │
│                                                                     │
│  State Management      StateFlow + ViewModel (KMP)                  │
│                        Kotlin Coroutines + Flow                     │
│  ├─────────────────────────────────────────────────────────────┤   │
│                                                                     │
│  Dependency Injection  Koin 4.2.1 (unified across 5 targets)        │
│  ├─────────────────────────────────────────────────────────────┤   │
│                                                                     │
│  Network Layer         Ktor 3.1.0 (commonMain)                      │
│                        Apollo GraphQL                               │
│                        Kotlinx Serialization                        │
│  ├─────────────────────────────────────────────────────────────┤   │
│                                                                     │
│  Database Layer        Room KMP                                     │
│                        DataStore (replaces SharedPreferences)       │
│  ├─────────────────────────────────────────────────────────────┤   │
│                                                                     │
│  Architecture          MVVM + Repository Pattern                    │
│                        Clean Architecture                           │
│                        Unidirectional Data Flow                     │
│                        expect / actual platform dispatch            │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Data Flow Diagram

┌──────────────┐        ┌──────────────┐        ┌──────────────┐
│              │        │              │        │              │
│   Screen     │◄───────┤  ViewModel   │◄───────┤  Repository  │
│  (Compose MP)│ State  │   (KMP)      │  Flow  │ (commonMain) │
│              │        │              │        │              │
└──────┬───────┘        └──────┬───────┘        └──────┬───────┘
       │                       │                       │
       │ User Action           │ Business Logic        │ Data Source
       │                       │                       │
       ▼                       ▼                       ▼
┌──────────────┐        ┌──────────────┐        ┌──────────────┐
│              │        │              │        │              │
│   onClick    │───────►│  loadData()  │───────►│ Ktor 3.1.0 / │
│   onRefresh  │ Event  │  refresh()   │ Call   │  Room KMP    │
│              │        │              │        │              │
└──────────────┘        └──────────────┘        └──────────────┘

Data Flow:
1. User actions trigger UI events (one Composable across 5 targets).
2. ViewModel handles business logic (KMP commonMain).
3. Repository coordinates data sources (Ktor network / Room KMP).
4. Data is returned to the ViewModel via Flow.
5. ViewModel updates UiState.
6. The UI auto-recomposes (consistent on Android / Desktop / iOS / macOS).

Layer Responsibilities

LayerModuleResponsibilityKey Technologies
Presentationfeature/UI rendering, user interactionCompose Multiplatform, jetbrains-navigation-compose 2.9.1
Businessdata (ViewModel)Business logic, state managementStateFlow, Coroutines, jetbrains-lifecycle 2.10.0
Datadata (Repository)Data access, caching strategyRepository Pattern, expect/actual
Networkcore/networkAPI calls, network requestsKtor 3.1.0, Apollo GraphQL
Storagecore/databaseLocal caching, data persistenceRoom KMP, DataStore
Foundationcore/common / core/uiCommon utilities, UI componentscomposeResources, Koin 4.2.1, Coil 2.7.0

Manual Test Playbooks

Copy-runnable manual regression playbooks across Android / iOS / macOS-Desktop / Windows-Desktop / Linux-Desktop:

PlatformEntryToolchain
Android (uiautomator)testing/uiautomator/playbook.mdadb + input swipe x y x y 80 + screencap
iOS Simulatortesting/ios/playbook.mdxcrun simctl + idb ui tap + pasteboard
macOS Desktop (DMG)testing/macos-desktop/playbook.mdcliclick + osascript + screencapture

E2E dual-track scripts (13 routes, all PASS):

13 routes covered: welcome / login / home / dynamic / profile / trending / search / repodetail / code / issue / push / notification / history / info — dual-track screenshots + logs all PASS, with artifacts under tools/screenshots/ios, tools/screenshots/macos, tools/logs/ios, tools/logs/macos.

The iOS AppIcon and LaunchScreen now share a single source of truth with Android (both come from ic_launcher / launch_image in core/common); see iosApp/iosApp/Assets.xcassets/AppIcon.appiconset and iosApp/iosApp/Assets.xcassets/launch_image.imageset.

Start here: cross-platform diff cheatsheet → testing/PLATFORM_DIFF.md

Each P-XX play (P-00 Cold Boot / P-01 Login / P-02 Dynamic / P-03 RepoDetail / P-04 PushDetail / P-05 Trending / P-06 Profile / P-08 Notification) shares identical structure and verification points across the three playbooks; only the underlying tool commands differ. Each platform's device / window metadata lives in its own device.md, and per-screen element coordinates in its own screen_map.md.

⚠️ "This document matters more than the README" — after a UI change, the first thing to update is screen_map, then run regression.

Download

Desktop Dmg / Msi / Deb and iOS ipa are published alongside Releases on a rolling basis; if a particular release is missing, please build locally with the 5-target commands above.

Sample Images (Screenshots may not be fully up-to-date)

Thanks

https://deepwiki.com/CarGuo/GSYGithubAppCompose

LICENSE

CarGuo/GSYGithubAppFlutter is licensed under the
Apache License 2.0

A permissive license whose main conditions require preservation of copyright and license notices.
Contributors provide an express grant of patent rights.
Licensed works, modifications, and larger works may be distributed under different terms and without source code.