compose-kotlin-agent-skills
NewEnterprise Android/Kotlin skill for 2026 — Kotlin 2.x K2 compiler, AGP 9, Navigation 3, edge-to-edge Compose, strict MVI with atomic _state.update, banned AI antipatterns. Jetpack Compose, Hilt, Room, KMP, CameraX/ML Kit, performance, testing. Use when writing Kotlin for Android, building Compose UI, MVVM/MVI architecture, debugging recomposition, Room DAOs, Navigation 3, coroutines, or asking "structure Android app", "ViewModel UiState", "collectAsStateWithLifecycle", "edge to edge", "AGP 9", "K2 compiler", "Play Store release".
Overview
Android & Kotlin — Enterprise Production Skill (2026)
Authoritative Android engineering kit. Real patterns from AnimatedClockJetpacl, Authenticator, RepLock.
Not an Android library, voice-assistant skill, on-device LLM SDK, or Compose UI library.
This is markdown for coding AIs — clone into
.cursor/skills/or.claude/skills/. See README § "What this is NOT".
Meta index: `AGENTS.md` · CI: python3 scripts/validate_skills.py
Sub-Skills (Modular)
| Skill | Path | Scope |
|---|---|---|
| Architecture | `skills/android-kotlin-architecture/SKILL.md` | MVI/MVVM, modules, UseCases, UDF |
| Compose UI | `skills/android-kotlin-compose/SKILL.md` | UI, edge-to-edge, performance, motion |
| Testing | `skills/android-kotlin-testing/SKILL.md` | Turbine, Compose tests, Hilt fakes |
2026 Toolchain — Non-Negotiable
| Tool | Minimum | Notes |
|---|---|---|
| Kotlin | 2.0+ (2.1.x) | K2 compiler only — no K1 fallback |
| AGP | 9.0+ | Built-in Kotlin, new DSL defaults |
| Compose BOM | 2025.05+ | Material 3, strong skipping default |
| Navigation | 3.x (2.9+ artifact) | Type-safe NavKey, @Serializable routes |
| compileSdk / targetSdk | 35+ | Edge-to-edge mandatory |
| JDK | 17 | Required for AGP 9 |
[versions]
kotlin = "2.1.20"
agp = "9.0.0"
compose-bom = "2025.05.00"
navigation = "2.9.0"
room = "2.7.1"
hilt = "2.56.2"
lifecycle = "2.9.0"
coroutines = "1.10.2"Kotlin 2.x / K2 Compiler Constraints
- Enable K2 —
kotlin.compiler.execution.strategydefault; usekspnotkaptfor Hilt/Room. - Smart casts — prefer
when (val x = state) { is Loaded -> ... }over unsafe!!. - Sealed hierarchy —
sealed interface UiState+data object Loading : UiStatefor exhaustivewhen. - `@JvmInline value class` for IDs (
@JvmInline value class UserId(val raw: String)). - `@Immutable` / `@Stable` on UiState and UI models passed to Compose.
- Explicit API optional for libraries —
kotlin { explicitApi() }in published modules. - No `!!` except in tests with comment — use
requireNotNull/ early return. - `data class` copy for state — never mutate UiState fields in place.
sealed interface AccountsUiState {
data object Loading : AccountsUiState
data class Ready(
val accounts: List<AccountUi>,
val query: String = ""
) : AccountsUiState
data class Error(@StringRes val messageRes: Int) : AccountsUiState
}MVI Guardrails — Atomic State Only
Allowed mutation: _state.update { it.copy(...) } or _state.update { prev -> ... }.
Banned in ViewModel:
// BANNED
_state.value = AccountsUiState(...) // naked assign
_state.value.accounts.add(item) // mutating list inside state
mutableStateOf / mutableStateListOf in VM // Compose scope only
viewModelScope.launch { _state.value = ... } // use update inside launchRequired pattern:
class AccountsViewModel @Inject constructor(
private val repository: AccountsRepository
) : ViewModel() {
private val _state = MutableStateFlow<AccountsUiState>(AccountsUiState.Loading)
val state: StateFlow<AccountsUiState> = _state.asStateFlow()
private val _effects = Channel<AccountsEffect>(Channel.BUFFERED)
val effects: Flow<AccountsEffect> = _effects.receiveAsFlow()
fun onEvent(event: AccountsEvent) {
when (event) {
AccountsEvent.Refresh -> refresh()
is AccountsEvent.QueryChanged -> _state.update { current ->
when (current) {
is AccountsUiState.Ready -> current.copy(query = event.query)
else -> current
}
}
}
}
private fun refresh() {
viewModelScope.launch {
_state.update { AccountsUiState.Loading }
repository.load()
.onSuccess { list ->
_state.update { AccountsUiState.Ready(accounts = list.map { it.toUi() }) }
}
.onFailure {
_state.update { AccountsUiState.Error(R.string.error_load_failed) }
}
}
}
}UI collects:
@Composable
fun AccountsRoute(vm: AccountsViewModel = hiltViewModel()) {
val state by vm.state.collectAsStateWithLifecycle()
LaunchedEffect(Unit) {
vm.effects.collect { effect -> /* one-shot: nav, snackbar */ }
}
AccountsScreen(state = state, onEvent = vm::onEvent)
}Navigation 3 + Edge-to-Edge
@Serializable data object Home
@Serializable data class Detail(val id: String)
@Composable
fun AppNavHost(navController: NavHostController = rememberNavController()) {
NavHost(navController, startDestination = Home) {
composable<Home> { HomeScreen(onOpen = { navController.navigate(Detail(it)) }) }
composable<Detail> { entry ->
val route = entry.toRoute<Detail>()
DetailScreen(id = route.id)
}
}
}- •Routes =
@Serializabletypes, not string paths - •Pass IDs in nav args — fetch models in destination ViewModel
- •
enableEdgeToEdge()in Activity — see compose sub-skill
Deep dive: `references/07-navigation.md`
Banned Antipatterns — AI Hallucination Lookup
Full table with WRONG/RIGHT pairs and row numbers: [`references/00-banned-antipatterns.md`](references/00-banned-antipatterns.md)
Load before reviewing any agent-generated Kotlin. Compose audit checklist: `skills/android-kotlin-compose/SKILL.md` § REVIEW MODE.
Reference Routing
| File | Topic |
|---|---|
references/00-banned-antipatterns.md | Master banned table — load first for reviews |
references/01-architecture.md | Clean Arch, MVVM, modules |
references/02-compose-ui.md | Composition, M3, theming |
references/03-animations.md | Motion, Canvas |
references/04-coroutines-flow.md | Flow, errors, cancellation |
references/05-hilt-di.md | DI, scopes |
references/06-room-db.md | Room, offline-first |
references/07-navigation.md | Nav 3, deep links |
references/08-kmp-cmp.md | KMP, expect/actual |
references/09-networking.md | Ktor, JWT |
references/10-performance.md | Recomposition, Coil, profiles |
references/11-testing.md | Turbine, UI tests |
references/12-camera-mlkit.md | CameraX, pose |
references/13-release-checklist.md | R8, Play Store |
references/14-datastore.md | DataStore, SP migration, encryption |
references/15-paging3.md | Paging 3, RemoteMediator, asState() |
references/16-coil-image.md | Coil 3.4, AsyncImage, cache |
references/17-accessibility.md | TalkBack, semantics, WCAG |
references/18-gradle-build-logic.md | Convention plugins, KSP, R8, baseline profiles |
references/19-xml-to-compose-migration.md | XML → Compose, RxJava → Flow |
Platforms
Target (what the docs teach): Android · Kotlin Multiplatform · Compose Multiplatform Host (where the docs are read): macOS · Linux · Windows — anywhere your AI agent runs Agent compatibility: 27 install guides → `agents/README.md`
Repo: https://github.com/haidrrrry/compose-kotlin-agent-skills
Mandatory Defaults (Summary)
- •Strings:
stringResource/@StringRes— zero hardcoded UI text - •State: ViewModel
StateFlow+_state.update { } - •UI: Stateless composables,
modifierfirst optional param - •Lists:
LazyColumn+ keys +contentType - •DI:
@HiltViewModel+ constructor inject - •Tests: Fakes + Turbine — see testing sub-skill
Validation Before PR
python3 scripts/validate_skills.py --strictAnti-Rationalizations
| Excuse | Reality |
|---|---|
| "UiState overkill" | data object Loading costs one line |
| "Keys later" | Broken scroll/focus NOW |
| "Prototype skip repo" | Prototypes ship |
| "collectAsState fine" | Background collector drains battery |
Examples
| Path | Patterns |
|---|---|
examples/animated-clock/ | Canvas, rotate(), particles |
examples/authenticator/ | Room Flow, combine, CompositionLocal theme |
Install & Usage
mkdir -p .claude/agentsAdd the configuration to .claude/agents/compose-kotlin-agent-skills.md
@compose-kotlin-agent-skillsSecurity Audits
Frequently Asked Questions
What is compose-kotlin-agent-skills?
Enterprise Android/Kotlin skill for 2026 — Kotlin 2.x K2 compiler, AGP 9, Navigation 3, edge-to-edge Compose, strict MVI with atomic _state.update, banned AI antipatterns. Jetpack Compose, Hilt, Room, KMP, CameraX/ML Kit, performance, testing. Use when writing Kotlin for Android, building Compose UI, MVVM/MVI architecture, debugging recomposition, Room DAOs, Navigation 3, coroutines, or asking "structure Android app", "ViewModel UiState", "collectAsStateWithLifecycle", "edge to edge", "AGP 9", "K2 compiler", "Play Store release".
How to install compose-kotlin-agent-skills?
To install compose-kotlin-agent-skills: create the agents directory (mkdir -p .claude/agents), then add the config to .claude/agents/compose-kotlin-agent-skills.md. Finally, @compose-kotlin-agent-skills in Claude Code.
What is compose-kotlin-agent-skills best for?
compose-kotlin-agent-skills is a agent categorized under General. It is designed for: testing, agent. Created by haidrrrry.