{"id":"7cb0333e-9870-45a7-bb5a-aea43b412d57","shortId":"eMQCKu","kind":"skill","title":"android-rxjava-to-coroutines-migration","tagline":"Migrate Android RxJava code to Kotlin coroutines and Flow with safe lifecycle-aware replacements.","description":"# Android RxJava To Coroutines Migration\n\n## When To Use\n- Use this skill when the request is about: rxjava to coroutines android, observable to flow android, replace composite disposable android.\n- Primary outcome: Migrate Android RxJava code to Kotlin coroutines and Flow with safe lifecycle-aware replacements.\n- Reach for this skill when the codebase still exposes `Single`, `Observable`, schedulers, or disposables and the goal is to move to `suspend`, `Flow`, `StateFlow`, or `SharedFlow`.\n- Read `references/patterns.md` for the type-mapping matrix and operator red-flag checklist.\n- Read `references/scenarios.md` for staged migration and inventory-first workflows.\n- Handoff skills when the scope expands:\n- `android-modernization-upgrade`\n- `android-coroutines-flow`\n\n## Workflow\n1. Scan the codebase for RxJava imports, base types, subjects, and scheduler usage before changing any API surface.\n2. Classify each usage as one-shot work, stream work, hot state, hot events, callback bridging, or backpressure-sensitive work.\n3. Replace repository and domain APIs first, then move UI-layer subscriptions to lifecycle-aware collection.\n4. Rewrite scheduler and disposable management as dispatcher, scope, structured-concurrency ownership, and lifecycle-aware collection such as `repeatOnLifecycle`.\n5. Leave a checklist for ambiguous operators or custom bridges instead of pretending every chain can be auto-converted safely.\n\n## Guardrails\n- Prefer `suspend` functions for one-shot work and `Flow` for streams; do not force everything into `Flow`.\n- Preserve lifecycle ownership when replacing `CompositeDisposable` and manual subscription chains.\n- Call out operator semantics that need human review, especially `flatMap`, `switchMap`, replay, and threading assumptions.\n- Preserve hot-state and replay semantics explicitly with `StateFlow`, `SharedFlow`, `shareIn`, or `stateIn` instead of assuming cold `Flow` is equivalent.\n- Treat migration as behavior-preserving refactor work, not a chance to redesign unrelated business logic.\n\n## Anti-Patterns\n- Converting every Rx type to `Flow` even when a `suspend` function is the better match.\n- Dropping replay, buffering, or hot-stream semantics during subject migration.\n- Leaving `observeOn` and `subscribeOn` assumptions undocumented after moving to dispatchers.\n- Rewriting repository, ViewModel, and UI layers all at once with no staged verification.\n\n## Review Focus\n- Type mapping: `Single`, `Maybe`, `Completable`, `Observable`, `Flowable`, and Subjects.\n- Hot vs cold semantics, replay behavior, and backpressure expectations.\n- Dispatcher ownership, `viewModelScope`, and lifecycle collection.\n- Testing fallout for coroutine timing, cancellation, and stream assertions.\n\n## Examples\n### Happy path\n- Scenario: Scan a legacy RxJava sample and generate a migration checklist for repositories, ViewModels, and UI subscriptions.\n- Command: `bash skills/android-rxjava-to-coroutines-migration/scripts/run_examples.sh`\n\n### Edge case\n- Scenario: Inventory subjects, disposables, and scheduler usage before converting state or one-off events.\n- Command: `python3 skills/android-rxjava-to-coroutines-migration/scripts/scan_rxjava_usage.py examples/fixtures/rxjava-legacy-sample --json`\n\n### Failure recovery\n- Scenario: Produce a deterministic checklist when parts of the chain still need manual operator review.\n- Command: `python3 skills/android-rxjava-to-coroutines-migration/scripts/generate_migration_checklist.py examples/fixtures/rxjava-legacy-sample`\n\n## Done Checklist\n- RxJava types and operators were inventoried before code changes were proposed.\n- One-shot APIs, streams, hot state, and hot events are mapped to the right coroutine primitives.\n- Lifecycle ownership and dispatcher assumptions are explicit.\n- Ambiguous operators or bridging cases are recorded as manual follow-up work.\n\n## Official References\n- [https://developer.android.com/kotlin/coroutines](https://developer.android.com/kotlin/coroutines)\n- [https://developer.android.com/kotlin/flow](https://developer.android.com/kotlin/flow)\n- [https://developer.android.com/kotlin/coroutines/coroutines-best-practices](https://developer.android.com/kotlin/coroutines/coroutines-best-practices)\n- [https://developer.android.com/topic/libraries/architecture/coroutines](https://developer.android.com/topic/libraries/architecture/coroutines)\n- [https://developer.android.com/kotlin/flow/stateflow-and-sharedflow](https://developer.android.com/kotlin/flow/stateflow-and-sharedflow)\n- [https://kotlinlang.org/docs/flow.html](https://kotlinlang.org/docs/flow.html)","tags":["android","rxjava","coroutines","migration","agent","skills","krutikjain","agent-skills","android-development","android-skills","androidx","claude-code"],"capabilities":["skill","source-krutikjain","skill-android-rxjava-to-coroutines-migration","topic-agent-skills","topic-android","topic-android-development","topic-android-skills","topic-androidx","topic-claude-code","topic-codex","topic-cursor","topic-jetpack-compose","topic-kotlin","topic-skills"],"categories":["android-agent-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/krutikJain/android-agent-skills/android-rxjava-to-coroutines-migration","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add krutikJain/android-agent-skills","source_repo":"https://github.com/krutikJain/android-agent-skills","install_from":"skills.sh"}},"qualityScore":"0.454","qualityRationale":"deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 8 github stars · SKILL.md body (4,591 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:13:28.742Z","embedding":null,"createdAt":"2026-05-18T13:20:51.598Z","updatedAt":"2026-05-18T19:13:28.742Z","lastSeenAt":"2026-05-18T19:13:28.742Z","tsv":"'/docs/flow.html](https://kotlinlang.org/docs/flow.html)':535 '/kotlin/coroutines/coroutines-best-practices](https://developer.android.com/kotlin/coroutines/coroutines-best-practices)':526 '/kotlin/coroutines](https://developer.android.com/kotlin/coroutines)':520 '/kotlin/flow/stateflow-and-sharedflow](https://developer.android.com/kotlin/flow/stateflow-and-sharedflow)':532 '/kotlin/flow](https://developer.android.com/kotlin/flow)':523 '/topic/libraries/architecture/coroutines](https://developer.android.com/topic/libraries/architecture/coroutines)':529 '1':132 '2':150 '3':172 '4':190 '5':211 'ambigu':216,503 'android':2,8,22,41,45,49,53,124,128 'android-coroutines-flow':127 'android-modernization-upgrad':123 'android-rxjava-to-coroutines-migr':1 'anti':314 'anti-pattern':313 'api':148,177,482 'assert':399 'assum':292 'assumpt':275,346,500 'auto':229 'auto-convert':228 'awar':20,65,188,206 'backpressur':169,383 'backpressure-sensit':168 'base':139 'bash':421 'behavior':301,381 'behavior-preserv':300 'better':329 'bridg':166,220,506 'buffer':333 'busi':311 'call':261 'callback':165 'cancel':396 'case':424,507 'chain':225,260,456 'chanc':307 'chang':146,476 'checklist':106,214,413,451,467 'classifi':151 'code':10,55,475 'codebas':73,135 'cold':293,378 'collect':189,207,390 'command':420,440,462 'complet':371 'composit':47 'compositedispos':256 'concurr':201 'convert':230,316,433 'coroutin':5,13,25,40,58,129,394,494 'custom':219 'determinist':450 'developer.android.com':519,522,525,528,531 'developer.android.com/kotlin/coroutines/coroutines-best-practices](https://developer.android.com/kotlin/coroutines/coroutines-best-practices)':524 'developer.android.com/kotlin/coroutines](https://developer.android.com/kotlin/coroutines)':518 'developer.android.com/kotlin/flow/stateflow-and-sharedflow](https://developer.android.com/kotlin/flow/stateflow-and-sharedflow)':530 'developer.android.com/kotlin/flow](https://developer.android.com/kotlin/flow)':521 'developer.android.com/topic/libraries/architecture/coroutines](https://developer.android.com/topic/libraries/architecture/coroutines)':527 'dispatch':197,351,385,499 'dispos':48,80,194,428 'domain':176 'done':466 'drop':331 'edg':423 'equival':296 'especi':269 'even':322 'event':164,439,488 'everi':224,317 'everyth':248 'exampl':400 'examples/fixtures/rxjava-legacy-sample':443,465 'expand':122 'expect':384 'explicit':283,502 'expos':75 'failur':445 'fallout':392 'first':115,178 'flag':105 'flatmap':270 'flow':15,44,60,89,130,242,250,294,321 'flowabl':373 'focus':366 'follow':513 'follow-up':512 'forc':247 'function':235,326 'generat':410 'goal':83 'guardrail':232 'handoff':117 'happi':401 'hot':161,163,278,336,376,484,487 'hot-stat':277 'hot-stream':335 'human':267 'import':138 'instead':221,290 'inventori':114,426,473 'inventory-first':113 'json':444 'kotlin':12,57 'kotlinlang.org':534 'kotlinlang.org/docs/flow.html](https://kotlinlang.org/docs/flow.html)':533 'layer':183,357 'leav':212,342 'legaci':406 'lifecycl':19,64,187,205,252,389,496 'lifecycle-awar':18,63,186,204 'logic':312 'manag':195 'manual':258,459,511 'map':99,368,490 'match':330 'matrix':100 'mayb':370 'migrat':6,7,26,52,111,298,341,412 'modern':125 'move':86,180,349 'need':266,458 'observ':42,77,372 'observeon':343 'offici':516 'one':156,238,437,480 'one-off':436 'one-shot':155,237,479 'oper':102,217,263,460,471,504 'outcom':51 'ownership':202,253,386,497 'part':453 'path':402 'pattern':315 'prefer':233 'preserv':251,276,302 'pretend':223 'primari':50 'primit':495 'produc':448 'propos':478 'python3':441,463 'reach':67 'read':93,107 'record':509 'recoveri':446 'red':104 'red-flag':103 'redesign':309 'refactor':303 'refer':517 'references/patterns.md':94 'references/scenarios.md':108 'repeatonlifecycl':210 'replac':21,46,66,173,255 'replay':272,281,332,380 'repositori':174,353,415 'request':35 'review':268,365,461 'rewrit':191,352 'right':493 'rx':318 'rxjava':3,9,23,38,54,137,407,468 'safe':17,62,231 'sampl':408 'scan':133,404 'scenario':403,425,447 'schedul':78,143,192,430 'scope':121,198 'semant':264,282,338,379 'sensit':170 'sharedflow':92,286 'sharein':287 'shot':157,239,481 'singl':76,369 'skill':32,70,118 'skill-android-rxjava-to-coroutines-migration' 'skills/android-rxjava-to-coroutines-migration/scripts/generate_migration_checklist.py':464 'skills/android-rxjava-to-coroutines-migration/scripts/run_examples.sh':422 'skills/android-rxjava-to-coroutines-migration/scripts/scan_rxjava_usage.py':442 'source-krutikjain' 'stage':110,363 'state':162,279,434,485 'stateflow':90,285 'statein':289 'still':74,457 'stream':159,244,337,398,483 'structur':200 'structured-concurr':199 'subject':141,340,375,427 'subscribeon':345 'subscript':184,259,419 'surfac':149 'suspend':88,234,325 'switchmap':271 'test':391 'thread':274 'time':395 'topic-agent-skills' 'topic-android' 'topic-android-development' 'topic-android-skills' 'topic-androidx' 'topic-claude-code' 'topic-codex' 'topic-cursor' 'topic-jetpack-compose' 'topic-kotlin' 'topic-skills' 'treat':297 'type':98,140,319,367,469 'type-map':97 'ui':182,356,418 'ui-lay':181 'undocu':347 'unrel':310 'upgrad':126 'usag':144,153,431 'use':29,30 'verif':364 'viewmodel':354,416 'viewmodelscop':387 'vs':377 'work':158,160,171,240,304,515 'workflow':116,131","prices":[{"id":"95c87d3b-ff10-4b5e-8d16-69dd6a2a8e37","listingId":"7cb0333e-9870-45a7-bb5a-aea43b412d57","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"krutikJain","category":"android-agent-skills","install_from":"skills.sh"},"createdAt":"2026-05-18T13:20:51.598Z"}],"sources":[{"listingId":"7cb0333e-9870-45a7-bb5a-aea43b412d57","source":"github","sourceId":"krutikJain/android-agent-skills/android-rxjava-to-coroutines-migration","sourceUrl":"https://github.com/krutikJain/android-agent-skills/tree/main/skills/android-rxjava-to-coroutines-migration","isPrimary":false,"firstSeenAt":"2026-05-18T13:20:51.598Z","lastSeenAt":"2026-05-18T19:13:28.742Z"}],"details":{"listingId":"7cb0333e-9870-45a7-bb5a-aea43b412d57","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"krutikJain","slug":"android-rxjava-to-coroutines-migration","github":{"repo":"krutikJain/android-agent-skills","stars":8,"topics":["agent-skills","android","android-development","android-skills","androidx","claude-code","codex","cursor","jetpack-compose","kotlin","skills"],"license":"mit","html_url":"https://github.com/krutikJain/android-agent-skills","pushed_at":"2026-03-25T05:47:20Z","description":"Android skills repository for Kotlin, Compose, XML, testing, CI, release work, and legacy upgrades","skill_md_sha":"bc45a7815d4aa4d0d88bfe616b00b7713655dbac","skill_md_path":"skills/android-rxjava-to-coroutines-migration/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/krutikJain/android-agent-skills/tree/main/skills/android-rxjava-to-coroutines-migration"},"layout":"multi","source":"github","category":"android-agent-skills","frontmatter":{"name":"android-rxjava-to-coroutines-migration","description":"Migrate Android RxJava code to Kotlin coroutines and Flow with safe lifecycle-aware replacements."},"skills_sh_url":"https://skills.sh/krutikJain/android-agent-skills/android-rxjava-to-coroutines-migration"},"updatedAt":"2026-05-18T19:13:28.742Z"}}