GSOC 2026:- Compose Multiplatform Migration

Introduction

Contact Information


About Me

I am a sophomore at IIITDM Jabalpur pursuing B.Tech in Computer Science and Engineering. Music runs through most of my day, while coding, while commuting, which is part of why ListenBrainz caught my attention in the first place. I started Android development in my second semester, built small apps, participated in intra-college Android events, and have been part of collaborative projects since. I also do competitive programming and mentor juniors through the institute’s Programming Club.

I have been contributing to ListenBrainz since December 2025. So far I have implemented the shimmer effect across the Feed and Profile screens, extended search to cover playlists, artists, albums and tracks, and fixed several bugs along the way.


Project Summary

ListenBrainz is Android-only right now. An earlier iOS attempt using Swift and SwiftUI did not work out well, it split the codebase in two, which meant every feature and bug fix had to be done twice. This project completes the migration to Kotlin Multiplatform (KMP) and Compose Multiplatform (CMP) so both platforms run from a single shared codebase. The approach is incremental: shared logic moves into commonMain in stages, the Android app stays functional throughout, and expect/actual is used only where the platforms genuinely differ.


What I Plan to Deliver

Compose Multiplatform UI: Migrate all screens, components, and theme from Android Jetpack Compose to JetBrains CMP in commonMain. Android keeps its Activity-based entry point and iOS gets a ComposeUIViewController.

Navigation 3: Replace the string-based Navigation 2.0 graph with a type-safe, user-owned @Serializable Screen backstack in commonMain. Both platforms get identical navigation behavior from the same code.

Dependency Injection: Swap koin-android/koin-androidx-compose for koin-compose/koin-compose-viewmodel. The shared initKoin and expect val platformModule live in commonMain, with OkHttp on Android and Darwin on iOS as platform actuals.

ViewModel and Lifecycle: Replace androidx.lifecycle with JetBrains KMP equivalents. All ViewModels move to commonMain using proper ViewModel() and viewModelScope. Android-specific dependencies like RemoteMediaHandler get abstracted behind shared interfaces.

Paging: Replace paging-runtime-ktx/paging-compose with the official KMP-compatible paging library. PagingSource, Pager, and collectAsLazyPagingItems all move to commonMain.

WebView: Replace WebViewClient subclasses with compose-webview-multiplatform by KevinnZou. The JS bridge (addJavascriptInterface on Android vs WKScriptMessageHandler on iOS) gets abstracted via expect/actual. All JS scripts stay in commonMain unchanged.

Media Player: A shared BrainzPlayer interface lives in commonMain. Android backs it with ExoPlayerController via MediaBrowserCompat. iOS backs it with AVPlayerController using AVPlayer, AVAudioSession, and MPRemoteCommandCenter.

Background Tasks: A shared BackgroundTaskScheduler interface in commonMain. Android implements it with WorkManager, iOS implements it with BGTaskScheduler.

Permissions: Replace accompanist-permissions with MOKO Permissions, which covers both platforms with a unified API.

UI Libraries: Replace com.valentinilk.shimmer with kmp-shimmer-compose, lottie-compose with Compottie, accompanist-systemuicontroller with a shared expect fun setStatusBarIconColor, and androidx.browser with expect fun openUrlInBrowser.

Onboarding: The first three screens (Introduction, Login and Create Account, Permissions) move to commonMain. The last two (Listen Submission setup and third-party app selector) depend on NotificationListenerService, which iOS does not support, so they stay in androidMain.

Spotify App Remote: Spotify has no iOS SDK. The integration stays scoped to androidMain and a minimal no-op stub lives in iosMain to keep the build green.

Testing: All platform-independent tests move to commonTest using Kotlin Test. Espresso and Compose UI tests stay in androidTest.


Timeline

Period Work
May 8 - Jun 1 Community bonding: dependency audit, migration order with mentor, iOS CI compile check
Jun 2 - Jun 8 Lifecycle and DI migration
Jun 9 - Jun 15 Full ViewModel migration + shared app entry points
Jun 16 - Jun 22 Navigation 3 migration
Jun 23 - Jun 29 Shared UI: shimmer, Lottie, system bar, browser, CMP composables
Jun 30 - Jul 6 Stabilization + pre-midterm QA, iOS simulator smoke test
Jul 7 - Jul 11 Midterm Evaluation
Jul 12 - Jul 18 KMP Paging + midterm feedback fixes
Jul 19 - Jul 25 WebView migration
Jul 26 - Aug 1 Media player abstraction
Aug 2 - Aug 8 WorkManager, permissions, onboarding, Spotify stub
Aug 9 - Aug 15 Full iOS QA + regression pass
Aug 16 - Aug 22 Documentation + cleanup
Aug 23 - Aug 25 Final submission

My college semester ends in late April, so I will be free from the start of community bonding with no competing commitments. I plan to put in 35 to 50 hours per week throughout the project.


Full Proposal

Due to the community post character limit, the complete proposal with technical details, code examples, full expect/actual implementations, and the week-by-week breakdown is here:

Full Proposal on GitHub

Any feedback or questions from mentors and the community would be helpful before I finalize the plan.

1 Like

Hi @nirvan73, thanks for writing up a contribution plan / GSoC proposal.

Great work on writing such a detailed proposal covering almost all the major areas.
My feedback:

  • Media Player Abstraction will definitely take up a bit more time than just 1 week due to the amount of hacks deployed to keep things functioning.
    The proposal could highlight if any schema changes are required for BrainzPlayer’s database. If there isn’t anything to highlight, we can skip.
  • I do not expect the whole UI to be migrated to CMP, this means that UI migration should be carried out in steps in which any piece of content is shown to user. For example, onboarding would be the first thing I would migrate to CMP before home navigation shell, then settings, then dashboard, feed (based on feature priority) and so on. I would advise BP to be delayed as much as possible to get initial UI out. But again, the Scaffold’s front layer will catch up soon (contains BP).
  • Week 3 could most probably leak into week 4 and as week 4’s tasks should be less time consuming.
  • Your exams should be somewhere between this period, maybe accommodate a rough grace period in the timeline. (Better if can have the dates themselves)
  • Getting/borrowing a mac would be nice for iOS testing. But not a blocker though.

Having said all that, I think the proposal looks pretty solid on the first go itself. Good amount of detail + focuses on important areas.

1 Like

Hey @Jasjeet , Thank you for the detailed feedback, really helpful to get this before I finalize.

On the Media Player, I checked the actual Room schema for BrainzPlayerDatabase and ListensSubmissionDatabase. None of the entities hold any ExoPlayer types directly, so no schema changes are needed when abstracting behind the shared interface. I have extended the media player to two weeks in the timeline to give it the room it needs.

On UI migration, I have restructured it to follow the priority order you suggested: onboarding first, then home navigation shell, then settings and dashboard, then feed. BrainzPlayer UI is explicitly deferred until after the media abstraction is stable. The Migration Goals section reflects this order as well.

On Week 3 and 4, I have added a note in Week 3 acknowledging that BrainzPlayerViewModel is the trickiest part and may spill over. Week 4 now explicitly notes it is lighter and scoped to absorb that overflow.

On exam dates, my end-semester exams finish before May 2, so there is no overlap with the GSoC period at all. I have added this to the timeline intro.

On Mac access, I plan to purchase one when the absolute need arises during the project. Added a line about this in the Practical Requirements section.

I have updated the same in the Google Doc shared earlier. Happy to take any further feedback before submission.

1 Like

Buying a mac is something I do not want to enforce, maybe borrowing or renting it out is the way to go if its not aligned with your future goals, but you know best.

Proposal looks good. You can submit it to GSoC website. Changes can be made after submission as well so its safe to do so.

1 Like