$npx -y skills add mmiani/kotlin-kmp-claude-agent-skills --skill kotlin-navigation-compose-multiplatformUse when designing, implementing, or reviewing navigation in Compose Multiplatform projects — route modeling, back stack ownership, argument passing, NavOptions, conditional flows, deep links, and adaptive navigation UI.
| 1 | # Compose Multiplatform Navigation |
| 2 | |
| 3 | Use this skill when designing, implementing, or reviewing navigation in a Compose Multiplatform project. |
| 4 | |
| 5 | This skill is intentionally strict. Its purpose is to keep route modeling coherent, back stack behavior explicit, argument passing minimal, navigation side effects controlled, and multiplatform routing boundaries clean across Android and shared Compose code. |
| 6 | |
| 7 | > **Navigation library scope**: This skill covers **Jetpack Navigation 2** and its Compose Multiplatform equivalent — the current stable navigation library. **Navigation 3** (Jetpack Navigation 3, a ground-up redesign) was in alpha as of mid-2025 and has a substantially different back-stack model, entry API, and lifecycle integration. If your project uses Navigation 3, verify which guidance applies before proceeding. Navigation 3 status: https://developer.android.com/guide/navigation/navigation3 |
| 8 | |
| 9 | ## Primary goals |
| 10 | |
| 11 | The navigation design should optimize for: |
| 12 | |
| 13 | - clear route ownership |
| 14 | - explicit back stack ownership |
| 15 | - controlled navigation side effects |
| 16 | - minimal and stable argument passing |
| 17 | - predictable back-stack behavior |
| 18 | - conditional flows that preserve user context |
| 19 | - coherent deep-link handling |
| 20 | - separation between shared routing logic and platform entry concerns |
| 21 | - adaptive navigation chrome for different window sizes |
| 22 | - previewable and testable navigation-hosting UI |
| 23 | |
| 24 | Do not treat navigation as only “go from screen A to screen B”. |
| 25 | Treat it as app-state movement with user-history consequences. |
| 26 | |
| 27 | ## Navigation library version note |
| 28 | |
| 29 | This skill covers Compose Multiplatform Navigation 2 (current stable as of mid-2025), which is the `navigation-compose` integration used in most KMP projects today. |
| 30 | |
| 31 | Jetpack Navigation 3 (a significant redesign with a different back-stack model built around `NavDisplay` and `NavEntry`) was in alpha as of mid-2025. If the project is using Navigation 3, some of this guidance — particularly around `NavController` ownership, `popUpTo`, and argument passing — applies differently. Verify against current Navigation 3 documentation before applying this skill to a Navigation 3 project. |
| 32 | |
| 33 | ## Navigation library version scope |
| 34 | |
| 35 | This skill covers **Jetpack Navigation 2** (stable) as used in Compose Multiplatform, including the `compose-navigation` artifact and the `NavHost`/`NavController` model. **Navigation 3** (a separate alpha-stage redesign as of mid-2025) uses a fundamentally different back-stack model and is not covered here. If the project uses Navigation 3, verify that the patterns below still apply — some will, some will not. Check the [Navigation 3 documentation](https://kotlinlang.org/docs/multiplatform/compose-navigation-3.html) for current guidance. |
| 36 | |
| 37 | ## Official defaults to prefer |
| 38 | |
| 39 | Unless the project has a strong reason not to, prefer: |
| 40 | |
| 41 | - a single owner of `NavController` or equivalent navigation state |
| 42 | - event-based navigation from composables instead of passing `NavController` downward |
| 43 | - typed or otherwise structured routes |
| 44 | - minimal argument payloads, usually identifiers rather than complex objects |
| 45 | - explicit use of back-stack options like `popUpTo`, `inclusive`, `saveState`, `restoreState`, and `launchSingleTop` |
| 46 | - conditional navigation driven by shared state rather than duplicated guards |
| 47 | - deep-link patterns that are non-overlapping and predictable |
| 48 | - shared route interpretation in common code when valid across targets |
| 49 | - browser URL binding only at the platform/web edge |
| 50 | |
| 51 | --- |
| 52 | |
| 53 | ## Review dimensions |
| 54 | |
| 55 | ### 1. Route modeling |
| 56 | |
| 57 | Check whether routes are modeled clearly and intentionally. |
| 58 | |
| 59 | Prefer: |
| 60 | - route models that are explicit and typed where possible |
| 61 | - destination identity that is understandable from the code |
| 62 | - route definitions separated from screen implementation details |
| 63 | |
| 64 | In Compose Multiplatform navigation, a route identifies a destination and defines the arguments required to navigate there, while staying separate from the UI implementation. |
| 65 | |
| 66 | Flag as a concern when: |
| 67 | - routes are brittle string literals scattered through the app |
| 68 | - route parameters are implicit or weakly structured |
| 69 | - screen identity and navigation actions are hard to trace |
| 70 | |
| 71 | ### 2. NavController ownership and navigation events |
| 72 | |
| 73 | Android explicitly recommends that composables expose navigation events rather than receiving a `NavController` reference directly. |
| 74 | |
| 75 | Check whether: |
| 76 | - the navigation host or app shell owns the `NavController` |
| 77 | - lower composables expose callbacks like `onOpenDetails()` rather than calling `navigate()` directly |
| 78 | - `navigate()` is called from callbacks or controlled side effects, not from normal rendering paths |
| 79 | |
| 80 | Flag as a concern when: |
| 81 | - `NavController |