
Rxjava To Coroutines Migration
- 254 installs
- 910 repo stars
- Updated July 27, 2026
- new-silvermoon/awesome-android-agent-skills
Refactor Android screens and ViewModels from RxJava Observables/Singles to Kotlin coroutines, Flow, and suspend APIs while preserving threading, error handling, and tests.
About
Android agent skill for migrating RxJava reactive streams to Kotlin coroutines and Flow: replace Observables with suspend functions, adopt structured concurrency, fix threading and cancellation, and keep ViewModel behavior and tests intact.
- RxJava-to-Flow mapping
- suspend repository APIs
- structured concurrency scopes
- lifecycle-aware collection
- unit test migration
Rxjava To Coroutines Migration by the numbers
- 254 all-time installs (skills.sh)
- +8 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #392 of 1,039 Mobile Development skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/new-silvermoon/awesome-android-agent-skills --skill rxjava-to-coroutines-migrationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 254 |
|---|---|
| repo stars | ★ 910 |
| Last updated | July 27, 2026 |
| Repository | new-silvermoon/awesome-android-agent-skills ↗ |
What it does
Refactor Android screens and ViewModels from RxJava Observables/Singles to Kotlin coroutines, Flow, and suspend APIs while preserving threading, error handling, and tests.
Files
RxJava to Kotlin Coroutines Migration Skill
A specialized skill designed to safely and idiomatically refactor Android or Kotlin codebases from RxJava to Kotlin Coroutines and Flow.
Migration Mapping Guide
When migrating RxJava components to Kotlin Coroutines, use the following standard mappings:
1. Base Types
- `Single<T>` ->
suspend fun ...(): T - A single asynchronous value.
- `Maybe<T>` ->
suspend fun ...(): T? - A single asynchronous value that might not exist.
- `Completable` ->
suspend fun ...() - An asynchronous operation that completes without a value.
- `Observable<T>` ->
Flow<T> - A cold stream of values.
- `Flowable<T>` ->
Flow<T> - Coroutines Flow natively handles backpressure.
2. Subjects to Hot Flows
- `PublishSubject<T>` ->
MutableSharedFlow<T> - Broadcasts events to multiple subscribers. Use
MutableSharedFlow(extraBufferCapacity = ...)if buffering is needed. - `BehaviorSubject<T>` ->
MutableStateFlow<T> - Holds state and emits the current/latest value to new subscribers. Requires an initial value.
- `ReplaySubject<T>` ->
MutableSharedFlow<T>(replay = N) - Replays the last N emitted values to new subscribers.
3. Schedulers to Dispatchers
- `Schedulers.io()` ->
Dispatchers.IO - `Schedulers.computation()` ->
Dispatchers.Default - `AndroidSchedulers.mainThread()` ->
Dispatchers.Main - Context Switching:
subscribeOnandobserveOnare typically replaced bywithContext(Dispatcher)orflowOn(Dispatcher)for Flows.
4. Operators
- `map` ->
map - `filter` ->
filter - `flatMap` ->
flatMapMerge(concurrent) orflatMapConcat(sequential) - `switchMap` ->
flatMapLatest - `doOnNext` / `doOnSuccess` ->
onEach - `onErrorReturn` / `onErrorResumeNext` ->
catch { emit(...) } - `startWith` ->
onStart { emit(...) } - `combineLatest` ->
combine - `zip` ->
zip - `delay` ->
delay(suspend function) oronEach { delay(...) }
5. Execution and Lifecycle
- `subscribe()` ->
collect {}(for Flows) or direct invocation (for suspend functions) inside aCoroutineScope. - `Disposable.dispose()` ->
Job.cancel() - `CompositeDisposable.clear()` -> Cancel the parent
CoroutineScopeorJob.
Execution Steps
1. Analyze the RxJava Chain: Identify the source type (Single, Observable, etc.), operators used, and where the subscription happens. 2. Convert the Source: Change the return type in the repository or data source layer first. Convert to suspend functions for one-shot operations, and Flow for streams. 3. Rewrite Operators: Translate the RxJava operators to their Flow or Coroutine equivalents. Note that many RxJava operators can simply be replaced by standard Kotlin collection/sequence operations inside a map or onEach block. 4. Update the Subscription: Replace .subscribe(...) with launch { ... } and .collect { ... } in the ViewModel or Presenter. Ensure the launch is tied to the correct lifecycle scope (e.g., viewModelScope). 5. Handle Errors: Replace onError blocks with try/catch around suspend functions, or .catch { } operators on Flows. 6. Handle Threading: Remove .subscribeOn() and .observeOn(). Use withContext where necessary, or .flowOn() to change the context of the upstream flow.
Example Transformation
RxJava:
fun getUser(id: String): Single<User> { ... }
disposable.add(
getUser("123")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ user ->
view.showUser(user)
}, { error ->
view.showError(error)
})
)Coroutines/Flow:
suspend fun getUser(id: String): User { ... } // Internally uses withContext(Dispatchers.IO) if needed
viewModelScope.launch {
try {
val user = getUser("123")
view.showUser(user)
} catch (e: Exception) {
view.showError(e)
}
}Best Practices
- Favor Suspend Functions: Default to
suspendfunctions instead ofFlowunless you actually have a stream of multiple values over time.SingleandCompletablealmost always becomesuspendfunctions. - State Handling: Use
StateFlowin ViewModels to expose state to the UI instead ofBehaviorSubjectorLiveData. - Lifecycle Awareness: Use
repeatOnLifecycleorflowWithLifecyclein the UI layer when collecting Flows to avoid background work when the view is not visible.