compose-state-hoisting

Guides placement of Jetpack Compose UI state across remember, hoisted parameters, state holders, and ViewModels.

Updated Jul 1, 2026
One-click install
npx skills add https://github.com/w0lzard/Wolzard-s-Marketplace --skill compose-state-hoisting-w0lzard
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: compose-state-hoisting
Source: https://github.com/w0lzard/Wolzard-s-Marketplace/tree/main/plugins/personal-skills/skills/compose-state-hoisting
Command: npx skills add https://github.com/w0lzard/Wolzard-s-Marketplace --skill compose-state-hoisting-w0lzard

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Deciding where UI state should live in a Jetpack Compose codebase is a recurring source of confusion: state hoisted too high creates coupling, while state kept too local blocks sharing and testing. This Skill provides a decision framework for choosing between local remember state, hoisted composable parameters, plain state holder classes, and screen-level ViewModels. ## Core Features & Use Cases - Decision table: Maps concrete situations (single-composable state, sibling sharing, UI logic extraction, business logic) to the correct state owner. - Plain state holder pattern: Provides a complete Kotlin template with @Stable classes, remember...State factory functions, and intent-style methods for UI behaviors like search, scroll, and focus. - Common mistakes reference: Lists anti-patterns such as over-hoisting, putting repository calls in Compose state holders, and calling animation suspend functions from viewModelScope, each with its fix. - Use Case: When a search screen accumulates query text, filter sheet visibility, list scroll position, and focus handling in one composable, use this Skill to extract a cohesive ProductSearchState holder while keeping repository-backed suggestion logic in the ViewModel. ## Quick Start Ask the AI to review your composable and decide where each piece of UI state should live using the compose state hoisting guidelines.

Frequently Asked Questions about compose-state-hoisting

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I decide where to put state in Jetpack Compose?

Keep state local with remember when one composable reads and writes it, hoist to the lowest common ancestor when siblings need it, extract a plain state holder class when related UI state and logic clutter a composable, and use a ViewModel when business logic or repository data is involved.

When should I extract a plain state holder class in Compose?

Extract one when multiple related remember values share callbacks, UI state needs named operations like clear or jumpToTop, or previews and tests must drive long UI sequences. Do not extract for a single boolean or trivial show/hide logic.

What is the difference between a plain state holder and a ViewModel in Compose?

A plain state holder owns UI element state and UI logic, is remembered in composition, and can hold Compose objects like LazyListState or FocusRequester. A ViewModel owns screen UI state and business logic such as repository calls, persistence, and data preparation for display.

Can I call scroll or drawer animations from viewModelScope?

No. Suspend UI operations that require a frame clock, such as scroll or drawer animations, must run in a composition-scoped coroutine like rememberCoroutineScope or LaunchedEffect, not in viewModelScope.

How do I save Compose state holder state across process death?

Use rememberSaveable or a custom Saver only for serializable values like query strings or selected filter IDs. Do not save runtime objects such as LazyListState, FocusRequester, or coroutine scopes; save the minimal values needed to rebuild behavior.