Kotlin · Jetpack Compose
Android (Kotlin, Jetpack Compose) rules for Cursor
State hoisting, lifecycle and ViewModel rules for Compose apps.
The rule
Save as .cursor/rules/android-compose.mdc. Cursor picks it up on the next request.
.cursor/rules/android-compose.mdc
--- description: Jetpack Compose app conventions globs: **/*.kt, **/*.kts alwaysApply: false --- - Hoist state: composables take state and event lambdas as parameters; screen state lives in a ViewModel. - Expose UI state from the ViewModel as StateFlow and collect it with collectAsStateWithLifecycle(). - Wrap state in remember, or rememberSaveable when it must survive configuration changes. - Never launch coroutines or do I/O directly in a composable body; use LaunchedEffect, event callbacks or viewModelScope. - Every reusable composable takes modifier: Modifier = Modifier as its first optional parameter and applies it to the root. - Use Material 3 components and MaterialTheme colors and typography instead of hard-coded values. - Put user-facing text in string resources and read it with stringResource(). - Use lazy layouts (LazyColumn, LazyRow) with stable keys for lists. - Add @Preview functions for new screens, and run the Gradle build and tests before finishing.
How Cursor loads this rule
Read from the frontmatter above, per Cursor's rules documentation.
alwaysApply: falsewithglobs: **/*.kt, **/*.kts: attached automatically when a matching file is in context.- Keep the
.mdcextension. A plain.mdfile in .cursor/rules is ignored by the rules system. - Prefer to generate your own? Type
/create-rulein Agent and describe what you want; Cursor saves the file to .cursor/rules. - Team Rules come first, then Project Rules like this one, then User Rules. Earlier sources win when guidance conflicts.
Cursor rules setup guideCursor Team RulesLet Cursor run commands without asking
Android (Kotlin, Jetpack Compose) rules for Claude Code, Copilot, Kiro and other agents
The same instructions work as plain Markdown in AGENTS.md, which Codex, Gemini CLI, GitHub Copilot and most other coding agents read.
AGENTS.md (section)
## Android (Kotlin, Jetpack Compose) - Hoist state: composables take state and event lambdas as parameters; screen state lives in a ViewModel. - Expose UI state from the ViewModel as StateFlow and collect it with collectAsStateWithLifecycle(). - Wrap state in remember, or rememberSaveable when it must survive configuration changes. - Never launch coroutines or do I/O directly in a composable body; use LaunchedEffect, event callbacks or viewModelScope. - Every reusable composable takes modifier: Modifier = Modifier as its first optional parameter and applies it to the root. - Use Material 3 components and MaterialTheme colors and typography instead of hard-coded values. - Put user-facing text in string resources and read it with stringResource(). - Use lazy layouts (LazyColumn, LazyRow) with stable keys for lists. - Add @Preview functions for new screens, and run the Gradle build and tests before finishing.
Android (Kotlin, Jetpack Compose) rules for Claude Code.claude/rules/android-compose.md
.claude/rules/android-compose.md
--- paths: - "**/*.kt" - "**/*.kts" --- - Hoist state: composables take state and event lambdas as parameters; screen state lives in a ViewModel. - Expose UI state from the ViewModel as StateFlow and collect it with collectAsStateWithLifecycle(). - Wrap state in remember, or rememberSaveable when it must survive configuration changes. - Never launch coroutines or do I/O directly in a composable body; use LaunchedEffect, event callbacks or viewModelScope. - Every reusable composable takes modifier: Modifier = Modifier as its first optional parameter and applies it to the root. - Use Material 3 components and MaterialTheme colors and typography instead of hard-coded values. - Put user-facing text in string resources and read it with stringResource(). - Use lazy layouts (LazyColumn, LazyRow) with stable keys for lists. - Add @Preview functions for new screens, and run the Gradle build and tests before finishing.
Android (Kotlin, Jetpack Compose) rules for GitHub Copilot.github/instructions/android-compose.instructions.md
.github/instructions/android-compose.instructions.md
--- applyTo: "**/*.kt,**/*.kts" --- - Hoist state: composables take state and event lambdas as parameters; screen state lives in a ViewModel. - Expose UI state from the ViewModel as StateFlow and collect it with collectAsStateWithLifecycle(). - Wrap state in remember, or rememberSaveable when it must survive configuration changes. - Never launch coroutines or do I/O directly in a composable body; use LaunchedEffect, event callbacks or viewModelScope. - Every reusable composable takes modifier: Modifier = Modifier as its first optional parameter and applies it to the root. - Use Material 3 components and MaterialTheme colors and typography instead of hard-coded values. - Put user-facing text in string resources and read it with stringResource(). - Use lazy layouts (LazyColumn, LazyRow) with stable keys for lists. - Add @Preview functions for new screens, and run the Gradle build and tests before finishing.
Android (Kotlin, Jetpack Compose) rules for Kiro.kiro/steering/android-compose.md
.kiro/steering/android-compose.md
--- inclusion: fileMatch fileMatchPattern: ["**/*.kt", "**/*.kts"] --- - Hoist state: composables take state and event lambdas as parameters; screen state lives in a ViewModel. - Expose UI state from the ViewModel as StateFlow and collect it with collectAsStateWithLifecycle(). - Wrap state in remember, or rememberSaveable when it must survive configuration changes. - Never launch coroutines or do I/O directly in a composable body; use LaunchedEffect, event callbacks or viewModelScope. - Every reusable composable takes modifier: Modifier = Modifier as its first optional parameter and applies it to the root. - Use Material 3 components and MaterialTheme colors and typography instead of hard-coded values. - Put user-facing text in string resources and read it with stringResource(). - Use lazy layouts (LazyColumn, LazyRow) with stable keys for lists. - Add @Preview functions for new screens, and run the Gradle build and tests before finishing.
Android (Kotlin, Jetpack Compose) rules for Antigravity.agents/rules/android-compose.md
.agents/rules/android-compose.md
--- trigger: glob globs: "**/*.kt, **/*.kts" --- - Hoist state: composables take state and event lambdas as parameters; screen state lives in a ViewModel. - Expose UI state from the ViewModel as StateFlow and collect it with collectAsStateWithLifecycle(). - Wrap state in remember, or rememberSaveable when it must survive configuration changes. - Never launch coroutines or do I/O directly in a composable body; use LaunchedEffect, event callbacks or viewModelScope. - Every reusable composable takes modifier: Modifier = Modifier as its first optional parameter and applies it to the root. - Use Material 3 components and MaterialTheme colors and typography instead of hard-coded values. - Put user-facing text in string resources and read it with stringResource(). - Use lazy layouts (LazyColumn, LazyRow) with stable keys for lists. - Add @Preview functions for new screens, and run the Gradle build and tests before finishing.
Android (Kotlin, Jetpack Compose) rules for Devin Desktop (Windsurf).devin/rules/android-compose.md
.devin/rules/android-compose.md
--- trigger: glob globs: **/*.kt, **/*.kts --- - Hoist state: composables take state and event lambdas as parameters; screen state lives in a ViewModel. - Expose UI state from the ViewModel as StateFlow and collect it with collectAsStateWithLifecycle(). - Wrap state in remember, or rememberSaveable when it must survive configuration changes. - Never launch coroutines or do I/O directly in a composable body; use LaunchedEffect, event callbacks or viewModelScope. - Every reusable composable takes modifier: Modifier = Modifier as its first optional parameter and applies it to the root. - Use Material 3 components and MaterialTheme colors and typography instead of hard-coded values. - Put user-facing text in string resources and read it with stringResource(). - Use lazy layouts (LazyColumn, LazyRow) with stable keys for lists. - Add @Preview functions for new screens, and run the Gradle build and tests before finishing.
Android (Kotlin, Jetpack Compose) rules for Cline.clinerules/android-compose.md
.clinerules/android-compose.md
--- paths: - "**/*.kt" - "**/*.kts" --- - Hoist state: composables take state and event lambdas as parameters; screen state lives in a ViewModel. - Expose UI state from the ViewModel as StateFlow and collect it with collectAsStateWithLifecycle(). - Wrap state in remember, or rememberSaveable when it must survive configuration changes. - Never launch coroutines or do I/O directly in a composable body; use LaunchedEffect, event callbacks or viewModelScope. - Every reusable composable takes modifier: Modifier = Modifier as its first optional parameter and applies it to the root. - Use Material 3 components and MaterialTheme colors and typography instead of hard-coded values. - Put user-facing text in string resources and read it with stringResource(). - Use lazy layouts (LazyColumn, LazyRow) with stable keys for lists. - Add @Preview functions for new screens, and run the Gradle build and tests before finishing.
Android (Kotlin, Jetpack Compose) rules for Continue.continue/rules/android-compose.md
.continue/rules/android-compose.md
--- name: "android-compose" globs: ["**/*.kt", "**/*.kts"] --- - Hoist state: composables take state and event lambdas as parameters; screen state lives in a ViewModel. - Expose UI state from the ViewModel as StateFlow and collect it with collectAsStateWithLifecycle(). - Wrap state in remember, or rememberSaveable when it must survive configuration changes. - Never launch coroutines or do I/O directly in a composable body; use LaunchedEffect, event callbacks or viewModelScope. - Every reusable composable takes modifier: Modifier = Modifier as its first optional parameter and applies it to the root. - Use Material 3 components and MaterialTheme colors and typography instead of hard-coded values. - Put user-facing text in string resources and read it with stringResource(). - Use lazy layouts (LazyColumn, LazyRow) with stable keys for lists. - Add @Preview functions for new screens, and run the Gradle build and tests before finishing.
More templates
Get Cursor rules and settings changes by email
When Cursor changes how rules, run modes or settings work, we update these templates from the docs and send a short note. One email a week at most.
Reviewed Oct 20, 2026. Written by AgentAtlas. Adapt it to your codebase before relying on it.