compose-expert
Advanced Compose Multiplatform UI patterns for shared composables. Use when working with visual UI components, state management patterns (remember, derivedStateOf, produceState), recomposition optimization (@Stable/@Immutable visual usage), Material3 theming, custom ImageVector icons, or determining
By vitorpamplona · 1,240 installs
npx skills add vitorpamplona/amethyst --skill compose-expert
Source repository · Upstream listing
Compose Multiplatform Expert
Visual UI patterns for sharing composables across Android and Desktop.
When to Use This Skill
Creating or refactoring shared UI components
Deciding whether to share UI in commonMain or keep platform specific
Building custom ImageVector icons (robohash pattern)
State management: remember, derivedStateOf, produceState
Recomposition optimization: visual usage of @Stable/@Immutable
Material3 theming and styling
Performance: lazy lists, image loading
Delegate to other skills:
Navigation structure → android expert , desktop expert
Kotlin state patterns (StateFlow, sealed classes) → kotlin expert
Build configuration → gradle expert
Philosophy: Share by Default
Default to commonsUI/commonMain (shared composables live in :commonsUI , the Compose half of the shared layer; headless state/ViewModels stay in :commons ) unless platform experts indicate otherwise.
Always Share
UI components : Buttons, cards, lists, dialogs, inputs
State visualization : Loading, empty, error states
Custom icons : ImageVector assets (robohash, custom paths)
Theme utilities : Color calculations, style helpers
Material3 components : Any UI using Material primitives
Keep Platform Specific
Navigation structure : Bottom nav (Android) vs Sidebar (Desktop)
Screen layouts : Platform specific scaffolding
System integrations : File pickers, notifications, share sheets
Platform UX : Gestures, keyboard shortcuts, window management
Decision Framework
1. Uses only Material3 primitives? → Share in commonMain
2. Requires platform system APIs? → Platform specific
3. Pure visual component without navigation? → Share in commonMain
4. Needs platform UX patterns? → Ask android expert or desktop expert
If uncertain, default to sharing easier to split later than merge.
Shared Composable Anatomy
Structure
Pattern : State down, events up
Parameters above modifier = required state/events
modifier parameter = layout control
Parameters below modifier = optional customization
Example: AddButton
Why this works on all platforms:
Material3 primitives (OutlinedButton, Text)
No platform APIs
Configurable through parameters
Consistent styling via shared constants
State Management Patterns
remember Cache Across Recompositions
Visual pattern : Toggle button → state changes → UI expands/collapses
Use for : Simple UI state (toggles, counters, text input)
derivedStateOf Optimize Frequent Changes
Visual pattern : Scroll position (0, 1, 2...) → boolean (show/hide) → Button visibility
Use for : Input changes frequently, derived result changes rarely
Performance : Prevents recomposition on every scroll event
produceState Async to Compose State
Visual pattern : Async operation → state updates → UI reflects changes
Use for : Convert Flow, LiveData, callbacks into Compose state
Lifecycle : Coroutine cancelled when composable leaves composition
For Kotlin specific state patterns (StateFlow, sealed classes), see kotlin expert .
State Hoisting
Move state up to make composables reusable:
Principle : State up, events down
State: query: String (read only parameter)
Events: onQueryChange: (String) Unit (callback parameter)
Recomposition Optimization
Visual Usage of @Immutable
Use @Immutable on data classes passed to composables:
Visual effect : Prevents recomposition when parent recomposes with same data
Pattern : Mark parameter data classes as @Immutable
Note : For Kotlin language details on @Immutable, see kotlin expert
Stable Parameters
For @Stable annotation details, see kotlin expert .
Material3 Theming
All shared composables use Material3 for consistency:
Principles:
Colors: MaterialTheme.colorScheme.
Typography: MaterialTheme.typography.
Shapes: MaterialTheme.shapes.
Theme Detection
Custom Icons: ImageVector Pattern
Amethyst uses ImageVector for multiplatform icons.
roboBuilder DSL
Building Icons
Why ImageVector?
Pure Kotlin, no XML
Works on Android, Desktop, iOS
GPU accelerated
Type safe
Caching Pattern
For detailed icon patterns, see references/icon assets.md .
Common Visual Patterns
State Visualization
Components (all in commonsUI/commonMain ):
LoadingState Progress indicator + message
EmptyState Empty message + optional refresh button
ErrorState Error message + optional retry button
Relay Status (Amethyst Pattern)
Visual mapping :
0 relays → Red + X icon
1 2 relays → Yellow + Check icon
3+ relays → Green + Check icon
Placeholder Pattern
Pattern : Generic composable + specific wrappers with preset text
Performance
Avoid Unnecessary Recomposition
Lazy Lists
Key principle : Use key parameter for stable item identity
Bundled Resources
references/shared composables catalog.md Complete catalog of shared UI components
references/state patterns.md State management patterns with visual examples
references/icon assets.md Custom ImageVector icon patterns
references/rich text parsing.md RichTextParser , UrlParser , GalleryParser , Patterns , MediaContentModels ; NIP 92 imeta enrichment
scripts/find composables.sh Find all @Composable functions in codebase
Quick Reference
Task Pattern Location
Reusable UI State hoisting commonsUI/commonMain
Simple state remember { mutableStateOf() } Composable scope
Derived state derivedStateOf { } remember block
Async → state produceState { } Composable function
Custom icons roboBuilder + PathData commonsUI/icons
Loading/Error LoadingState, ErrorState commonsUI/ui/components
Theme colors MaterialTheme.colorScheme Any @Composable
Navigation Delegate to platform expert amethyst/, desktopApp/
Common Workflows
Creating a Shared Component
1. Start in commonsUI/src/commonMain/kotlin/.../ui/components/
2. Use Material3 primitives only
3. Hoist state (parameters for data, callbacks for events)
4. Add modifier parameter
5. Use MaterialTheme for colors/typography
6. Test on both Android and Desktop
Converting Existing Component
1. Read current implementation in amethyst/ or desktopApp/
2. Identify pure visual logic (no platform APIs)
3. Create in commonsUI/commonMain with hoisted state
4. Replace platform implementations with shared component
5. Keep platform specific wrappers if needed
Custom Icon
1. Export SVG from design tool
2. Convert to PathData using Android Studio
3. Create icon function with roboBuilder
4. Add caching if generated dynamically
5. Wrap in @Composable for easy use
Navigation (Delegate)
For navigation patterns:
Android bottom nav → android expert
Desktop sidebar → desktop expert
Multi window → desktop expert
Related Skills
kotlin expert Kotlin language aspects (@Immutable details, StateFlow, sealed classes)
android expert Android navigation, platform APIs
desktop expert Desktop navigation, window management, OS specifics
kotlin coroutines Async patterns, Flow integration