new-silvermoon/compose-ui
Best practices for building UI with Jetpack Compose, focusing on state hoisting, detailed performance optimizations, and theming. Use this when writing or refactoring Composable functions.
npx skills add https://github.com/new-silvermoon/awesome-android-agent-skills --skill compose-ui
Follow these guidelines to create performant, reusable, and testable Composables.
Make Composables stateless whenever possible by moving state to the caller.
@Composable
fun MyComponent(
value: String, // State flows down
onValueChange: (String) -> Unit, // Events flow up
modifier: Modifier = Modifier // Standard modifier parameter
)
viewModel.uiState.collectAsStateWithLifecycle()) and passes it down.modifier: Modifier = Modifier as the first optional parameter.modifier to the *root* layout element of your Composable.padding().clickable() is different from clickable().padding(). Generally apply layout-affecting modifiers (like padding) *after* click listeners if you want the padding to be clickable.remember: Use remember { ... } to cache expensive calculations across recompositions.derivedStateOf: Use derivedStateOf { ... } when a state changes frequently (like scroll position) but the UI only needs to react to a threshold or summary (e.g., show "Jump to Top" button). This prevents unnecessary recompositions. val showButton by remember {
derivedStateOf { listState.firstVisibleItemIndex > 0 }
}
viewModel::onEvent) or remembered lambdas to prevent unstable types from triggering recomposition of children.MaterialTheme.colorScheme and MaterialTheme.typography instead of hardcoded colors or text styles.DesignSystem.kt or Components.kt) if they are shared across features.@Preview(showBackground = true) and include Light/Dark mode previews if applicable.Take new-silvermoon/compose-ui from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.