Help us improve
Share bugs, ideas, or general feedback.
From everything-claude-code-mobile
Provides Jetpack Compose patterns for state hoisting, remember variants, slot APIs, modifiers, side effects, theming, animations, and performance in Android UI development.
npx claudepluginhub ahmed3elshaer/everything-claude-code-mobile --plugin everything-claude-code-mobileHow this skill is triggered — by the user, by Claude, or both
Slash command
/everything-claude-code-mobile:jetpack-composeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Modern declarative UI patterns for Android.
Guides building native Android UIs with Jetpack Compose, including state management via remember/mutableStateOf, state hoisting, and ViewModel integration.
Provides expertise in Jetpack Compose and Compose Multiplatform for UI development across Android, Desktop, iOS, Web. Covers APIs, navigation, Paging 3, Android TV, design systems, and PR reviews.
Provides Android and Kotlin development patterns for Jetpack Compose, architecture, coroutines, Room, navigation, Hilt. Use when building Android apps, writing Compose UI, or reviewing Android code.
Share bugs, ideas, or general feedback.
Modern declarative UI patterns for Android.
// ✅ CORRECT: Stateless composable
@Composable
fun Counter(
count: Int,
onIncrement: () -> Unit,
modifier: Modifier = Modifier
) {
Row(modifier = modifier) {
Text("Count: $count")
Button(onClick = onIncrement) {
Text("+")
}
}
}
// Parent owns state
@Composable
fun CounterScreen() {
var count by rememberSaveable { mutableStateOf(0) }
Counter(
count = count,
onIncrement = { count++ }
)
}
// remember - Survives recomposition
val alpha by remember { mutableStateOf(1f) }
// rememberSaveable - Survives config change
var count by rememberSaveable { mutableStateOf(0) }
// remember with key - Resets on key change
val animation = remember(itemId) { Animatable(0f) }
// derivedStateOf - Computed, updates only when result changes
val isValid by remember {
derivedStateOf { email.isNotBlank() && password.length >= 8 }
}
@Composable
fun AppBar(
title: @Composable () -> Unit,
navigationIcon: @Composable () -> Unit = {},
actions: @Composable RowScope.() -> Unit = {}
) {
TopAppBar(
title = { title() },
navigationIcon = { navigationIcon() },
actions = actions
)
}
// Usage
AppBar(
title = { Text("Home") },
navigationIcon = { IconButton(onClick = {}) { Icon(Icons.Default.Menu, null) } },
actions = {
IconButton(onClick = {}) { Icon(Icons.Default.Search, null) }
}
)
@Composable
fun CustomButton(
onClick: () -> Unit,
modifier: Modifier = Modifier, // First optional parameter
enabled: Boolean = true,
content: @Composable RowScope.() -> Unit
) {
Button(
onClick = onClick,
modifier = modifier, // Apply modifier first
enabled = enabled,
content = content
)
}
@Composable
fun HomeScreen(viewModel: HomeViewModel) {
// Runs once
LaunchedEffect(Unit) {
viewModel.loadData()
}
// Runs when key changes
LaunchedEffect(userId) {
viewModel.loadUser(userId)
}
}
@Composable
fun LifecycleObserver(onResume: () -> Unit) {
val lifecycleOwner = LocalLifecycleOwner.current
DisposableEffect(lifecycleOwner) {
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_RESUME) onResume()
}
lifecycleOwner.lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
}
@Composable
fun AppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
val colorScheme = if (darkTheme) DarkColorScheme else LightColorScheme
MaterialTheme(
colorScheme = colorScheme,
typography = AppTypography,
content = content
)
}
// Usage
val backgroundColor = MaterialTheme.colorScheme.surface
val textStyle = MaterialTheme.typography.bodyLarge
LazyColumn {
items(
items = users,
key = { it.id } // Critical for performance
) { user ->
UserItem(user = user)
}
}
val alpha by animateFloatAsState(
targetValue = if (visible) 1f else 0f,
animationSpec = tween(durationMillis = 300)
)
val size by animateDpAsState(
targetValue = if (expanded) 200.dp else 100.dp
)
AnimatedContent(
targetState = state,
transitionSpec = {
fadeIn() togetherWith fadeOut()
}
) { targetState ->
when (targetState) {
is Loading -> LoadingContent()
is Success -> SuccessContent(targetState.data)
is Error -> ErrorContent()
}
}
Remember: Compose is declarative. Describe the UI, don't command it.