KS
Killer-Skills

kmp-compose-unstyled — how to use kmp-compose-unstyled how to use kmp-compose-unstyled, kmp-compose-unstyled alternative, kmp-compose-unstyled setup guide, what is kmp-compose-unstyled, kmp-compose-unstyled vs Jetpack Compose, kmp-compose-unstyled install, kotlin multiplatform development, headless component library, unstyled UI screens

v1.0.0
GitHub

About this Skill

Ideal for Kotlin Multiplatform Agents requiring headless component libraries for custom UI development and accessibility handling. kmp-compose-unstyled is a headless component library implementation for Kotlin Multiplatform apps, providing unstyled components for UX logic and accessibility.

Features

Building Unstyled UI screens in :features:<feature>:ui-unstyled modules
Configuring Themes using buildTheme or buildPlatformTheme DSLs
Implementing Headless Components with custom styling
Ensuring Platform-specific accessibility
Using Kotlin Multiplatform for cross-platform development

# Core Topics

niltsiar niltsiar
[0]
[0]
Updated: 3/7/2026

Quality Score

Top 5%
54
Excellent
Based on code quality & docs
Installation
SYS Universal Install (Auto-Detect)
Cursor IDE Windsurf IDE VS Code IDE
> npx killer-skills add niltsiar/kotlin_multiplatform_pokedex/ui-ux-designer/kmp-developer/kmp-architecture/references/troubleshooting.md

Agent Capability Analysis

The kmp-compose-unstyled MCP Server by niltsiar is an open-source Categories.community integration for Claude and other AI agents, enabling seamless task automation and capability expansion. Optimized for how to use kmp-compose-unstyled, kmp-compose-unstyled alternative, kmp-compose-unstyled setup guide.

Ideal Agent Persona

Ideal for Kotlin Multiplatform Agents requiring headless component libraries for custom UI development and accessibility handling.

Core Value

Empowers agents to develop unstyled UI screens and custom themes using Kotlin Multiplatform project's headless component library implementation patterns, handling UX logic, state, and accessibility while rendering no visual UI by default, utilizing DSLs like buildTheme or buildPlatformTheme.

Capabilities Granted for kmp-compose-unstyled MCP Server

Building Unstyled UI screens in :features:<feature>:ui-unstyled modules
Configuring custom themes using buildTheme or buildPlatformTheme DSLs
Implementing headless components with custom styling for accessibility

! Prerequisites & Limits

  • Requires Kotlin Multiplatform project setup
  • Limited to headless component library development
Project
SKILL.md
13.3 KB
.cursorrules
1.2 KB
package.json
240 B
Ready
UTF-8

# Tags

[No tags]
SKILL.md
Readonly

KMP Compose Unstyled

Headless component library implementation patterns for the Pokédex project. Unstyled components handle UX logic, state, and accessibility while rendering no visual UI by default.

When to Use This Skill

  • Building Unstyled UI screens in :features:<feature>:ui-unstyled modules.
  • Configuring Themes using buildTheme or buildPlatformTheme DSLs.
  • Implementing Headless Components (Button, Text, ProgressIndicator, etc.) with custom styling.
  • Ensuring Platform-Native Accessibility using interactive size modifiers and platform-specific indications.

Mode Detection

User RequestReference FileLoad When
"Create Unstyled component" / "buildPlatformTheme"compose_unstyled_reference.mdMANDATORY - Read before implementing
"Customize tokens" / "CompositionLocal theming"component_token_customization_example.mdMANDATORY - Read before customizing
"Component not working" / "UI issues"troubleshooting.mdCheck for common issues

MANDATORY - READ ENTIRE FILE: Before implementing Unstyled components with buildPlatformTheme or buildTheme, you MUST read compose_unstyled_reference.md (~1319 lines) for comprehensive component catalog and patterns.

MANDATORY - READ ENTIRE FILE: Before customizing component tokens via CompositionLocal, you MUST read component_token_customization_example.md (~142 lines) for customization patterns.

Do NOT load component_token_customization_example.md for basic component usage - only load when implementing custom token overrides. Do NOT load troubleshooting.md unless experiencing specific UI component issues.

Core Patterns

1. buildPlatformTheme DSL

Uses platform-specific fonts, sizes, and indications automatically.

kotlin
1val PlatformTheme = buildPlatformTheme(name = "MyAppTheme") { 2 defaultContentColor = Color.Black 3 defaultTextStyle = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Normal) 4 // Platform fonts (Roboto, SF Pro) applied automatically 5}

2. Interactive Size Modifier

Ensures touch targets meet platform accessibility standards (Android 48dp, iOS 44dp).

kotlin
1Button( 2 onClick = {}, 3 modifier = Modifier.interactiveSize(Theme[interactiveSizes][sizeDefault]) 4) { Text("Accessible Button") }

3. Theme Access Syntax

Always use direct bracket notation for fresh theme reads. Avoid storing theme references.

kotlin
1val primary = Theme[colors][primary] // ✅ Direct access 2val body = Theme[typography][bodyMedium]

4. ProgressIndicator Wrapper

Unlike Material, Unstyled ProgressIndicator requires a wrapper to render the fill.

kotlin
1ProgressIndicator(progress = progress) { 2 Box(Modifier.fillMaxWidth(progress).fillMaxSize().background(contentColor, shape)) 3}

Related Skills

  • @kmp-design-systems - Token system and core component architecture.
  • @kmp-architecture - Module structure (Unstyled theme in :core:designsystem-unstyled).
  • @compose-screen - General patterns for implementing Compose screens.
  • @ui-ux-designer - Visual design and animation guidelines.

Critical Guardrails

  1. NEVER include Material Design 3 patterns or components in Unstyled modules → keep modules strictly separated (reason: maintains clean architectural boundaries and prevents visual leakage).
  2. NEVER hardcode platform-specific sizes → always use Theme[interactiveSizes][sizeDefault] (reason: ensures accessibility compliance across Android/iOS/Desktop/Web automatically).
  3. NEVER manual configure fontFamily in buildPlatformTheme → let it be automatic unless using custom fonts (reason: ensures native platform look-and-feel without extra configuration).
  4. NEVER store Theme.currentTheme in variables → always use direct bracket notation Theme[prop][token] (reason: breaks reactivity and prevents state atomicity issues).
  5. NEVER use Modifier.clickable for interactive elements → use the Button component instead (reason: Button provides built-in ARIA support and keyboard interaction logic).
  6. NEVER forget the inner fill Box for ProgressIndicator → always implement the rendering block (reason: unlike Material, Unstyled ProgressIndicator renders no UI by default).
  7. NEVER skip @Preview annotations → every UI component needs a preview with its theme (reason: essential for visual verification and developer efficiency).
  8. NEVER access tokens via MaterialTheme.tokens in unstyled modules → use the Unstyled Theme object (reason: prevents tight coupling and breaks dual-theme encapsulation).

Decision Framework

Before implementing Unstyled components, ask yourself:

  1. What level of customization is needed?

    • Platform-native defaults → Use buildPlatformTheme (automatic fonts, sizes, indications)
    • Custom styling → Use buildTheme with explicit token values
    • Component-specific → Apply Modifier chains to headless components
  2. Which headless components should I use?

    • Interactive elements → Button, IconButton (handle touch targets, accessibility)
    • Text display → Text (platform-native typography)
    • Loading states → ProgressIndicator (platform-specific animations)
    • Custom components → Build with Modifier.interactiveSize() for accessibility
  3. How do I ensure accessibility?

    • Always use Modifier.interactiveSize() for touch targets (48dp minimum)
    • Use Modifier.indication() for platform-native feedback
    • Add @Preview with theme applied for visual verification
    • Test on both Android and iOS for platform consistency

Essential Workflows

Workflow 1: Creating an Unstyled Screen with buildPlatformTheme

To implement a screen with platform-native theming:

  1. Define the theme using buildPlatformTheme in your design system module:
    kotlin
    1val UnstyledTheme = buildPlatformTheme(name = "UnstyledTheme") { 2 defaultContentColor = Color(0xFF1C1B1F) 3 defaultTextStyle = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Normal) 4 // Platform fonts (Roboto, SF Pro) applied automatically 5}
  2. Wrap your screen content with the theme object:
    kotlin
    1@Composable 2fun PokemonListUnstyledScreen(viewModel: PokemonListViewModel) { 3 val uiState by viewModel.uiState.collectAsStateWithLifecycle() 4 UnstyledTheme { 5 PokemonListContent(uiState = uiState) 6 } 7}
  3. Access tokens using bracket notation:
    kotlin
    1Box(modifier = Modifier.background(Theme[colors][background])) { 2 Text("Pokédex", style = Theme[typography][headlineLarge]) 3}

Related skills: @kmp-design-systems, @compose-screen

Workflow 2: Building Custom Headless Components

To create reusable components using Unstyled primitives:

  1. Use the Button component for any interactive element:
    kotlin
    1@Composable 2fun PokemonCard(pokemon: Pokemon, onClick: () -> Unit) { 3 Button( 4 onClick = onClick, 5 backgroundColor = Theme[colors][surface], 6 contentColor = Theme[colors][onSurface], 7 shape = Theme[shapes][cardShape], 8 modifier = Modifier.interactiveSize(Theme[interactiveSizes][sizeDefault]) 9 ) { 10 Column(horizontalAlignment = Alignment.CenterHorizontally) { 11 AsyncImage(model = pokemon.imageUrl, contentDescription = null) 12 Text(text = pokemon.name, style = Theme[typography][bodyLarge]) 13 } 14 } 15}
  2. Apply interactiveSize to ensure accessibility standards are met.

Related skills: @kmp-design-systems, @ui-ux-designer

Workflow 3: Implementing Interactive Size for Accessibility

To ensure your UI meets platform-specific touch target requirements:

  1. Use sizeDefault (48dp Android, 44dp iOS) for primary actions:
    kotlin
    1Button( 2 onClick = {}, 3 modifier = Modifier.interactiveSize(Theme[interactiveSizes][sizeDefault]) 4) { Text("Accessible Button") }
  2. Use sizeMinimum (32dp Android, 28dp iOS) for dense toolbars:
    kotlin
    1IconButton( 2 onClick = {}, 3 modifier = Modifier.interactiveSize(Theme[interactiveSizes][sizeMinimum]) 4) { Icon(Lucide.Settings, contentDescription = "Settings") }

Related skills: @kmp-architecture, @ui-ux-designer

Workflow 4: Using ProgressIndicator with Custom Styling

To implement a progress bar that requires manual fill rendering:

  1. Provide the rendering block inside the ProgressIndicator call:
    kotlin
    1ProgressIndicator( 2 progress = progress, 3 modifier = Modifier.fillMaxWidth().height(8.dp), 4 shape = RoundedCornerShape(8.dp), 5 backgroundColor = Theme[colors][surface], 6 contentColor = Theme[colors][primary] 7) { 8 // Manual rendering of the progress fill 9 Box( 10 Modifier 11 .fillMaxWidth(progress) 12 .fillMaxSize() 13 .background(contentColor, shape) 14 ) 15}

Related skills: @kmp-developer, @compose-screen

Quick Reference

PatternPurposeExample
buildPlatformThemePlatform-native fonts/sizesbuildPlatformTheme(name = "App") { ... }
Theme[colors][primary]Direct theme accessval primary = Theme[colors][primary]
interactiveSizeAccessibility complianceModifier.interactiveSize(Theme[interactiveSizes][sizeDefault])
ProgressIndicatorCustom fill renderingProgressIndicator(progress) { Box(...) }
ProvideTextStyleCascading text stylesProvideTextStyle(Theme[typography][body]) { ... }

Cross-References

Skills (by Category)

Design & UI

SkillPurposeLink
@kmp-design-systemsToken system and component architectureSKILL.md
@ui-ux-designerVisual design and animation guidelinesSKILL.md
@compose-screenGeneral patterns for implementing Compose screensSKILL.md

Implementation

SkillPurposeLink
@kmp-architectureModule structure and vertical slicingSKILL.md
@kmp-developerGeneral development and feature implementationSKILL.md
@kmp-critical-patterns6 core patterns quick referenceSKILL.md

Platform & Navigation

SkillPurposeLink
@kmp-navigationNavigation 3 modular architectureSKILL.md
@kmp-testing-patternsUI and screenshot testing with RoborazziSKILL.md

Documents

DocumentPurposeLink
compose_unstyled_patterns.mdDetailed patterns catalogSee @kmp-compose-unstyled skill
compose_unstyled_reference.mdCatalog and implementation referencecompose_unstyled_reference.md
component_token_customization_example.mdCustomization via CompositionLocalcomponent_token_customization_example.md
troubleshooting.mdCommon UI component issues and solutionstroubleshooting.md
@kmp-architectureArchitecture and development conventionsArchitecture skill

Troubleshooting Common Unstyled Component Issues

Clickable Component Not Responding

Symptom: Card hover/press states work, but clicking does nothing.

Cause: Missing .clickable() modifier despite having MutableInteractionSource.

Solution:

kotlin
1Column( 2 modifier = modifier 3 .clip(shape) 4 .border(...) 5 .clickable( // ← REQUIRED for actual clicks 6 interactionSource = interactionSource, 7 indication = null, // Or ripple effect 8 onClick = onClick 9 ) 10 .hoverable(interactionSource = interactionSource) // Only tracks hover 11 .padding(...) 12)

Why: hoverable() only tracks hover state, doesn't make component clickable. Must add .clickable() separately.

Order matters:

  1. .clip() - Define shape first
  2. .border() - Visual border
  3. .clickable() - Make clickable
  4. .hoverable() - Track hover state
  5. .padding() - Internal padding

Hover Effects Too Subtle

Symptom: Hover state implemented but barely visible.

Cause: Minimal effect values (brightness 1.1, border alpha 0.2).

Solution for Unstyled theme:

kotlin
1val brightness by animateFloatAsState( 2 targetValue = when { 3 isPressed -> 0.95f 4 isHovered -> 1.15f // More noticeable (was 1.1) 5 else -> 1f 6 } 7) 8 9val borderAlpha by animateFloatAsState( 10 targetValue = when { 11 isPressed -> 0.3f 12 isHovered -> 0.5f // More prominent (was 0.2) 13 else -> 0.2f 14 } 15) 16 17val scale by animateFloatAsState( 18 targetValue = when { 19 isPressed -> 0.98f 20 isHovered -> 1.02f // Slight grow (was 1.0) 21 else -> 1f 22 } 23)

Why: Minimal effects match "unstyled" aesthetic but need sufficient visibility for usability.


Related Skills

Looking for an alternative to kmp-compose-unstyled or building a Categories.community AI Agent? Explore these related open-source MCP Servers.

View All

widget-generator

Logo of f
f

widget-generator is an open-source AI agent skill for creating widget plugins that are injected into prompt feeds on prompts.chat. It supports two rendering modes: standard prompt widgets using default PromptCard styling and custom render widgets built as full React components.

149.6k
0
Design

chat-sdk

Logo of lobehub
lobehub

chat-sdk is a unified TypeScript SDK for building chat bots across multiple platforms, providing a single interface for deploying bot logic.

73.0k
0
Communication

zustand

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication

data-fetching

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication