본문으로 건너뛰기
cccskills
무료GitHub에 공개

jetpack-compose-navigation-expert

Jetpack Compose navigation expert with type-safe routes, Hilt DI, and MVVM/MVI architecture. Activate on: Jetpack Compose navigation, Compose type-safe routes, Hilt dependency injection, MVVM Android, MVI pattern, Compose state management, NavHost, ViewModel. NOT for: XML layouts (use frontend-architect), iOS SwiftUI (use swiftui-data-flow-expert), React Native (use react-native-architect).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md6.9 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Jetpack Compose Navigation Expert

Expert in Jetpack Compose navigation with type-safe routes, Hilt dependency injection, and clean MVVM/MVI architecture.

Activation Triggers

Activate on: "Jetpack Compose navigation", "Compose type-safe routes", "Hilt DI", "MVVM Android", "MVI pattern", "Compose state management", "NavHost", "ViewModel Compose", "navigation-compose"

NOT for: XML layouts → frontend-architect | iOS SwiftUI → swiftui-data-flow-expert | React Native → react-native-architect

Quick Start

  1. Add Navigation Compose — implementation("androidx.navigation:navigation-compose:2.9.x") with type-safe routes
  2. Define routes as serializable classes — @Serializable data class ProductRoute(val id: String)
  3. Set up Hilt — @HiltViewModel for ViewModels with constructor injection
  4. Implement MVVM — ViewModel holds UI state, composables observe via collectAsStateWithLifecycle
  5. Handle deep links — declarative deep link mapping in NavHost

Core Capabilities

DomainTechnologies
NavigationNavigation Compose 2.9, type-safe routes, nested graphs
DIHilt 2.53, @HiltViewModel, @Inject, module scoping
ArchitectureMVVM, MVI (Circuit, Mavericks), UDF (unidirectional data flow)
StateStateFlow, collectAsStateWithLifecycle, SavedStateHandle
AsyncKotlin Coroutines, Flow, Room with Flow, Retrofit suspend

Architecture Patterns

Type-Safe Navigation (Compose 2.8+)

// Define routes as serializable data classes
@Serializable
data object HomeRoute

@Serializable
data class ProductRoute(val productId: String)

@Serializable
data class OrderRoute(val orderId: String, val showConfirmation: Boolean = false)

// NavHost with type-safe composable destinations
@Composable
fun AppNavHost(navController: NavHostController = rememberNavController()) {
    NavHost(navController = navController, startDestination = HomeRoute) {
        composable<HomeRoute> {
            HomeScreen(
                onProductClick = { id ->
                    navController.navigate(ProductRoute(productId = id))
                }
            )
        }
        composable<ProductRoute> { backStackEntry ->
            val route = backStackEntry.toRoute<ProductRoute>()
            ProductScreen(productId = route.productId)
        }
        composable<OrderRoute> { backStackEntry ->
            val route = backStackEntry.toRoute<OrderRoute>()
            OrderScreen(orderId = route.orderId)
        }
    }
}

MVVM with Hilt and UDF

@HiltViewModel
class ProductViewModel @Inject constructor(
    private val repository: ProductRepository,
    savedStateHandle: SavedStateHandle,
) : ViewModel() {

    private val productId: String = savedStateHandle.toRoute<ProductRoute>().productId

    private val _uiState = MutableStateFlow<ProductUiState>(ProductUiState.Loading)
    val uiState: StateFlow<ProductUiState> = _uiState.asStateFlow()

    init { loadProduct() }

    fun onEvent(event: ProductEvent) {
        when (event) {
            is ProductEvent.AddToCart -> addToCart(event.quantity)
            is ProductEvent.Refresh -> loadProduct()
        }
    }

    private fun loadProduct() {
        viewModelScope.launch {
            _uiState.value = ProductUiState.Loading
            repository.getProduct(productId)
                .onSuccess { _uiState.value = ProductUiState.Success(it) }
                .onFailure { _uiState.value = ProductUiState.Error(it.message) }
        }
    }
}

// Composable observes state
@Composable
fun ProductScreen(viewModel: ProductViewModel = hiltViewModel()) {
    val uiState by viewModel.uiState.collectAsStateWithLifecycle()

    when (val state = uiState) {
        is ProductUiState.Loading -> LoadingIndicator()
        is ProductUiState.Success -> ProductContent(
            product = state.product,
            onEvent = viewModel::onEvent,
        )
        is ProductUiState.Error -> ErrorMessage(state.message)
    }
}

Nested Navigation Graphs

Root NavHost
  ├─ Auth Graph (unauthenticated)
  │   ├─ Login
  │   ├─ Register
  │   └─ ForgotPassword
  ├─ Main Graph (authenticated)
  │   ├─ Home Tab
  │   │   ├─ Feed
  │   │   └─ Product Detail
  │   ├─ Search Tab
  │   │   ├─ Search
  │   │   └─ Category
  │   └─ Profile Tab
  │       ├─ Profile
  │       └─ Settings
  └─ Fullscreen overlays (shared)
      ├─ ImageViewer
      └─ VideoPlayer

Anti-Patterns

  1. String-based routes — navController.navigate("product/123") is error-prone. Use type-safe route classes (@Serializable data class ProductRoute(val id: String)).
  2. ViewModel in composable — creating ViewModel instances inside composables. Use hiltViewModel() which handles scoping to the NavBackStackEntry.
  3. Collecting Flow without lifecycle — collectAsState() keeps collecting when the app is backgrounded. Use collectAsStateWithLifecycle() to respect lifecycle.
  4. God ViewModel — single ViewModel for an entire feature with 20+ state fields. Split into smaller ViewModels or use MVI with sealed state classes.
  5. Navigation in ViewModel — calling navController.navigate() from ViewModel. Instead, expose navigation events via SharedFlow or callback lambdas; let the composable handle navigation.

Quality Checklist

[ ] Type-safe navigation routes using @Serializable classes
[ ] Hilt configured with @HiltViewModel for all ViewModels
[ ] UI state collected with collectAsStateWithLifecycle
[ ] Unidirectional data flow: events up, state down
[ ] Deep links configured in NavHost
[ ] Navigation tested with TestNavHostController
[ ] SavedStateHandle used for process death restoration
[ ] Nested graphs for auth, main, and feature flows
[ ] No navigation logic in ViewModels (events/callbacks instead)
[ ] Compose previews with mock data for all screens
[ ] ProGuard/R8 rules configured for serializable routes
[ ] Screen transitions animated with shared element transitions

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Expert in 2000s-era music visualization (Milkdrop, AVS, Geiss) and modern WebGL implementations. Specializes in Butterchurn integration, Web Audio API AnalyserNode FFT data, GLSL shaders for audio-reactive visuals, and psychedelic generative art. Activate on "Milkdrop", "music visualization", "WebGL visualizer", "Butterchurn", "audio reactive", "FFT visualization", "spectrum analyzer". NOT for simple bar charts/waveforms (use basic canvas), video editing, or non-audio visuals.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

curiositech/windags-skills162026년 10월 19일 업데이트

Expert legal research agent for finding and scraping expungement data state by state. Knows authoritative sources, URL patterns, Firecrawl configuration, and 2026 legal landscape.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

curiositech/windags-skills162026년 10월 19일 업데이트

Expert in 3D computer vision labeling tools, workflows, and AI-assisted annotation for LiDAR, point clouds, and sensor fusion. Covers SAM4D/Point-SAM, human-in-the-loop architectures, and vertical-specific training strategies. Activate on '3D labeling', 'point cloud annotation', 'LiDAR labeling', 'SAM 3D', 'SAM4D', 'sensor fusion annotation', '3D bounding box', 'semantic segmentation point cloud'. NOT for 2D image labeling (use clip-aware-embeddings), general ML training (use ml-engineer), video annotation without 3D (use computer-vision-pipeline), or VLM prompt engineering (use prompt-engineer).

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

curiositech/windags-skills162026년 10월 19일 업데이트

Apply crisis decision-making research to agent routing, uncertainty triage, and coordination failure analysis in time-pressured systems. Use when diagnosing handoff failures, analytical paralysis, or expert judgment under incomplete information. NOT for routine coding, simple CRUD design, or static single-agent tasks with complete information.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

curiositech/windags-skills162026년 10월 19일 업데이트

Use for insight, reframing, contradiction, impasse, and anomaly-driven problem solving when execution effort no longer helps. NOT for routine optimization, error correction, or well-specified tasks with known solution paths.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

curiositech/windags-skills162026년 10월 19일 업데이트

Apply normative BDI reasoning to agents that must detect norms, choose which commitments to internalize, and resolve conflicts by comparing consequences. Use when obligations, prohibitions, or policies collide in autonomous systems. NOT for simple fixed-priority rules, pure constraint satisfaction, or domains where no real normative conflict exists.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

curiositech/windags-skills162026년 10월 19일 업데이트

curiositech의 스킬 모두 보기

이 스킬의 문제 신고