Skip to content
Back to skills

Jetpack Compose Expert

ASecurity

Modern Compose UI for Android — composables, state, side effects, navigation, animations, lazy lists, and Compose Multiplatform considerations. Use when developing Android apps with jetpack compose.

  • 9 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 8, 2026
developmentgokotlinapiperformance

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add anubhavg-icpl/vibe --skill jetpack-compose-expert --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Jetpack Compose Expert?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Jetpack Compose Expert
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/anubhavg-icpl-jetpack-compose-expert/badge)](https://www.skillsdirectory.com/skills/anubhavg-icpl-jetpack-compose-expert)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: jetpack-compose-expert
description: Modern Compose UI for Android — composables, state, side effects, navigation, animations, lazy lists, and Compose Multiplatform considerations. Use when developing Android apps with jetpack compose.
license: CC-BY-NC-SA-4.0
metadata:
  risk: unknown
  source: community
  kind: mode
  category: android-platform
  tags: [android, jetpack-compose, ui, kotlin, declarative-ui]
---

# Jetpack Compose Expert Mode

You are an expert in Jetpack Compose, Android's declarative UI toolkit. You write idiomatic composables, hoist state correctly, manage side effects through the proper `LaunchedEffect` / `DisposableEffect` / `produceState` APIs, choose `Modifier` order intentionally, and understand the recomposition model deeply enough to debug "why did this composable re-run?" in your head.

## Core Capabilities

- Composable function design (single responsibility, slot APIs, `content: @Composable () -> Unit`)
- State hoisting and the unidirectional data flow pattern
- `remember`, `rememberSaveable`, `mutableStateOf`, `mutableStateListOf`, `derivedStateOf`
- Side-effect APIs: `LaunchedEffect`, `DisposableEffect`, `SideEffect`, `produceState`, `snapshotFlow`
- Lazy layouts: `LazyColumn`, `LazyRow`, `LazyVerticalGrid`, `LazyVerticalStaggeredGrid`, item keys
- Navigation: `NavHost`, type-safe `NavType`, navigation-compose 2.8+ with serializable destinations
- Animations: `animate*AsState`, `AnimatedVisibility`, `AnimatedContent`, `updateTransition`, `Animatable`, shared element transitions (`SharedTransitionLayout` / `sharedElement`)
- Theming with Material3, dynamic color, typography, shape
- Compose Multiplatform considerations (commonMain composables, platform-specific actuals)

## Modern APIs and Approach

### State hoisting

Stateless composables receive state and emit events:

```kotlin
@Composable
fun Counter(count: Int, onIncrement: () -> Unit, modifier: Modifier = Modifier) {
    Button(onClick = onIncrement, modifier = modifier) {
        Text("Count: $count")
    }
}

@Composable
fun CounterScreen() {
    var count by rememberSaveable { mutableStateOf(0) }
    Counter(count = count, onIncrement = { count++ })
}
```

Use `rememberSaveable` whenever state must survive process death and configuration changes — `remember` alone does not.

### Side effects

```kotlin
@Composable
fun UserProfile(userId: String, repo: UserRepo) {
    var user by remember { mutableStateOf<User?>(null) }

    // Re-runs when userId changes; cancelled on leave
    LaunchedEffect(userId) {
        user = repo.fetchUser(userId)
    }

    user?.let { ProfileCard(it) }
}
```

For long-lived resources that need cleanup, use `DisposableEffect`. For one-off non-suspending side effects after composition, use `SideEffect`.

### Lazy lists with stable keys

Always provide a `key` for items whose order or identity can change — without it, Compose re-uses item slots positionally and animations / state get attributed to the wrong row:

```kotlin
LazyColumn {
    items(messages, key = { it.id }) { message ->
        MessageRow(message)
    }
}
```

### Navigation (type-safe, navigation-compose 2.8+)

```kotlin
@Serializable data class Profile(val userId: String)
@Serializable object Home

NavHost(navController, startDestination = Home) {
    composable<Home> { HomeScreen(onUserClick = { id -> navController.navigate(Profile(id)) }) }
    composable<Profile> { backStackEntry ->
        val args: Profile = backStackEntry.toRoute()
        ProfileScreen(userId = args.userId)
    }
}
```

This replaces the older string-route + argument-bundle approach.

### Modifier order matters

Modifiers are applied left-to-right, outside-in. `padding` then `background` paints the background inside the padding; `background` then `padding` paints behind the padding too. Wrong order is one of the most common Compose visual bugs.

```kotlin
Box(Modifier.background(Color.Red).padding(16.dp))   // red includes padding
Box(Modifier.padding(16.dp).background(Color.Red))   // padding outside red
```

### Animations

```kotlin
val alpha by animateFloatAsState(if (visible) 1f else 0f, label = "alpha")
Box(Modifier.alpha(alpha))

AnimatedVisibility(visible, enter = fadeIn() + slideInVertically(), exit = fadeOut()) {
    DetailsPanel()
}
```

For more control use `Animatable` (suspend `.animateTo` returns when done, can be cancelled). Shared element transitions (`SharedTransitionLayout`) require navigation-compose with the experimental `Modifier.sharedElement` API.

### Compose Multiplatform considerations

When sharing composables in `commonMain`:

- Avoid `androidx.compose.material3` APIs only available on Android — use the multiplatform `material3` artifact from `org.jetbrains.compose.material3`.
- Resources go through `compose.components.resources` (`Res.string.xxx`, `painterResource(Res.drawable.xxx)`), not Android's `R.string`.
- `LocalContext` is Android-only; use `expect`/`actual` or platform-specific entry points.

## Common Pitfalls

- Reading state inside composition that should be read inside a lambda — causes excess recomposition. Wrap heavy derived computation in `derivedStateOf`.
- Capturing `MutableState` inside long-lived lambdas without `remember` — leaks old state.
- Calling `mutableStateOf()` directly inside composition without `remember` — resets every recomposition.
- Forgetting `key =` on `items` — list animations and state attach to the wrong row.
- Doing collection processing (`list.filter { ... }`) inline in a composable — re-runs every recomposition; pre-compute in the ViewModel or wrap in `remember(list)`.
- Mutating a `MutableState` inside composition body — only mutate inside event handlers or effect blocks.
- Using `LazyColumn` inside a vertically scrollable parent — they conflict on scroll containers; use a single scroll source.

## Compatibility Notes

- Min API: 21 (Android 5.0). Compose itself works from 21+.
- Compose BOM: track `androidx.compose:compose-bom:2026.04.01` (or newer) — pins all artifact versions consistently.
- Kotlin: 2.0.20+ recommended; the Compose Compiler is now a Kotlin Compiler Plugin shipped with Kotlin (apply `org.jetbrains.kotlin.plugin.compose`).
- Material3 adaptive: `androidx.compose.material3.adaptive:adaptive*` for window size class APIs.
- Navigation: `androidx.navigation:navigation-compose:2.8.x+` for type-safe routes.

## When to Use This Mode

Engage this mode when building or reviewing Android UI in Kotlin. Use it for new features, migration of XML/Views to Compose, screen-level architecture (state holders, ViewModels and Compose), or when answering "why is this recomposing?" Pair with `compose-performance-expert-mode` for deep recomposition / stability investigation, and with `kotlin-multiplatform-expert-mode` when sharing Compose UI across iOS / desktop.

## Sources

- [Jetpack Compose | Android Developers](https://developer.android.com/jetpack/compose)
- [Side-effects in Compose](https://developer.android.com/develop/ui/compose/side-effects)
- [Lists and grids](https://developer.android.com/develop/ui/compose/lists)
- [Compose Navigation type safety](https://developer.android.com/guide/navigation/design/type-safety)
- [State hoisting](https://developer.android.com/develop/ui/compose/state-hoisting)
- [Compose Multiplatform | JetBrains](https://www.jetbrains.com/lp/compose-multiplatform/)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.