Skip to main content
skill CX Codex

styles — Claude Code skill: Jetpack Compose Styles API

Walks an Android coding agent through moving a project onto the experimental Jetpack Compose Styles API, from Gradle opt-in to component-by-component migration.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add android/skills --skill styles -a claude-code
Open on GitHub

What styles does

The skill drives an agent through migrating an Android project to the Jetpack Compose Styles API. It checks the ground first: compileSdk 37, androidx.compose.foundation:foundation at 1.12.0-alpha01 or Compose BOM 2026.04.01. Then it adds -opt-in=androidx.compose.foundation.style.ExperimentalFoundationStyleApi to build.gradle.kts. Skip that flag and the module will not compile, which makes it the first thing to verify.

Next comes ComponentStyles.kt holding your style objects, plus a static reference from the custom theme instead of CompositionLocals. Components get converted one at a time. Styling parameters leave the signature, style: Style = Style goes in, interactive ones get a MutableStyleState, and the root modifier becomes Modifier.styleable(). With an emulator available, the skill asks for a screenshot before the edit and a comparison against the Compose Preview after.

The API is experimental, so alpha dependencies and project-wide opt-in are part of the deal. Material Design component Styles are not supported. If the design system sits on Material theming, that is worth checking before you start.

What it helps with

  • convert custom components to Style without visual regressions
  • pull hardcoded colors and shapes into ComponentStyles.kt
  • wire the experimental opt-in flag into Gradle and raise the dependencies
  • connect style definitions to a custom theme with a static reference
  • track pressed and hover states with MutableStyleState and Modifier.styleable()

Example prompts for the agent

  • Migrate CustomButton to the Styles API and diff the screenshot against the current render
  • Create ComponentStyles.kt and wire it into our theme
  • Check whether the project meets the compileSdk 37 and 1.12.0-alpha01 foundation requirements

How to install styles

1Skills CLI (Vercel)

npx skills add android/skills --skill styles -a claude-code

2Manually: put the files in place

~/.claude/skills/styles/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/styles/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about styles

How do I install styles in Claude Code?

Run npx skills add android/skills --skill styles -a claude-code, which lands the skill at ~/.claude/skills/styles/SKILL.md.

What does styles do?

It guides an agent through the Jetpack Compose Styles API migration: dependency upgrade, ComponentStyles.kt setup, signature changes on custom components, and a screenshot check for visual parity.

Does styles handle Material Design components?

No. It covers custom UI components and custom themes only; Material Design component Styles are out of scope.

Source text

SKILL.md · Apache-2.0
---
name: styles
description: Use this skill to integrate the Jetpack Compose Styles API into an Android
  project. This skill guides you through upgrading dependencies, setting up component
  themes, making custom components styleable, and migrating existing layout properties
  to use unified styles. Migrate custom design system components, replace hard coded
  parameters with Style attributes, and use Modifier.styleable for interaction states.
license: Complete terms in LICENSE.txt
metadata:
  author: Google LLC
  last-updated: '2026-10-20'
  keywords:
  - Jetpack Compose
  - Styles
  - Theming with Styles
  - Migrate to Styles
  - Modifier.styleable
---

## Limitations

- Warn the user that this skill is EXPERIMENTAL and requires updating to alpha version of Compose and opting in to the Experimental APIs.
- This skill only supports custom UI components and custom themes.
- This skill does not support Material Design component Styles.

## Prerequisites

### 1. Upgrade dependencies

- The project must use `compileSdk` version 37 or higher.
- The project must use `androidx.compose.foundation:foundation` version `1.12.0-alpha01` or higher.
- Alternatively, the project must use Compose BOM version `2026.04.01` or higher.
- The API requires this exact package: `import
  androidx.compose.foundation.style.Style`

### 2. Configure compiler options to enable experimental API

You must opt-in to the experimental API at the project level. Add the following
block to your module's `build.gradle.kts`:

    kotlin {
        compilerOptions {
            jvmTarget = JvmTarget.fromTarget("17")
            freeCompilerArgs.add("-opt-in=androidx.compose.foundation.style.ExperimentalFoundationStyleApi")
        }
    }

## Core workflows and guides

Refer to the official documentation to complete specific development tasks:

- Basic Style Usage: To set backgrounds, sizes, and alignments on a component, follow the [Compose Styles Fundamentals
  Guide](references/android/develop/ui/compose/styles/fundamentals.md).
- State and Transitions: To configure property changes for state shifts (like pressed or hovered), follow the [Animations and State-Based Styling
  Guide](references/android/develop/ui/compose/styles/state-animations.md).
- Architecture Trade offs: To decide when to use a Style versus a standard Modifier, follow the [Styles versus Modifiers
  Comparison](references/android/develop/ui/compose/styles/styles-vs-modifiers.md).
- Theme Level Integration: To connect style definitions with custom themes, follow [Theming with Styles](references/android/develop/ui/compose/styles/theming.md) and [Custom Themes in Compose](references/android/develop/ui/compose/designsystems/custom.md).

## Step-by-Step Migration Workflow

### Step 1: Analyze theme structure

1. Locate your central theme file (such as `Theme.kt`).
2. Identify design tokens. Note references for colors, typography, and shapes (for example, `LocalColorScheme`, `LocalTypography`, or `LocalShapes`).
3. If the project lacks Jetpack Compose dependencies, stop. Instruct the user to migrate to Jetpack Compose first.
4. If the project imports `androidx.compose.material.MaterialTheme`, recommend migrating to Material 3 before proceeding.

### Step 2: Establish `ComponentStyles`

1. Create a new file named `ComponentStyles.kt` in your theme directory.
2. Define a top-level data class to hold your component styles, for example, the Jetsnack one is called `JetsnackStyles`:


   ```kotlin
   object ExampleComponentStyles {
       val customButtonStyle: Style = {

       }
       val customTextFieldStyle: Style = {

       }
   }
   ```

   <br />

3. Expose this class through your custom theme with a static reference, don't
   use `CompositionLocals` here as it's not required.


   ```kotlin
   @Immutable
   class JetsnackTheme(
       // other Design system properties
   ) {
       companion object {
           val colors: CustomThemingWithStyles.JetsnackColors
               @Composable @ReadOnlyComposable
               get() = LocalJetsnackTheme.current.colors
           // ...

           // add helper static reference
           val styles: ComponentStyles = ComponentStyles
       }
   }
   ```

   <br />

4. Provide extensions on `StyleScope` to reference theme tokens directly if
   they are exposed using `CompositionLocals`. For example:


   ```kotlin
   val StyleScope.colors: JetsnackColors
       get() = LocalJetsnackTheme.currentValue.colors

   val StyleScope.typography: androidx.compose.material3.Typography
       get() = LocalJetsnackTheme.currentValue.typography

   val StyleScope.shapes: Shapes
       get() = LocalJetsnackTheme.currentValue.shapes
   ```

   <br />

### Step 3: Migrate a component to Styles API

For each custom component (for example, `CustomButton`), complete the following
sequence:

1. **Establish a visual baseline (If an emulator is available):**
   - **If you CANNOT run an Android emulator:** Skip this step entirely and proceed to Step 2.
   - **If you CAN run an Android emulator:** Perform the following to capture a baseline screenshot:
     - **Option A:** Locate and run an existing screenshot test for the component.
     - **Option B (If no test exists):** Create a test using the project's existing testing framework, then run it.
     - **Option C (If no framework exists):** Create a minimal screenshot test using UI Automator or Espresso, then run it.
2. **Remove individual styling parameters** : Remove styling parameters such as `backgroundColor`, `shape`, `textStyle`, and `contentPadding` from the signature - anything that `StyleScope` supports.
3. **Add the style parameter** : Add `style: Style = Style` to the function signature. Always ensure the default value is exactly `Style` (e.g., `style:
   Style = Style`) and not a specific style default like `ChipStyleDefault` or any other value.
4. **Declare state tracking** : If the component is interactable, create a `MutableStyleState` using the interaction source. Update state fields (such as `isEnabled`) inside the Composable to track the state correctly.
5. **Apply styleable modifier** : Replace specific layout modifiers on the root element with `Modifier.styleable()`.
6. **Move defaults to ComponentStyles** : Move hardcoded values from the component definition to a dedicated `Style` instance in `ComponentStyles.kt`.
7. **Validate component:** Compare the baseline screenshot image taken at the start with the rendered Compose Preview of the new composable. Ignore string content; focus on layout and styling. Iterate on the Compose code until visual parity is achieved. Once verified, write a Compose UI test for the new composable.

#### Migration example

Before Migration:


```kotlin
@Composable
fun CustomButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    backgroundColor: Color = JetsnackTheme.colors.brandLight,
    disabledBackgroundColor: Color = JetsnackTheme.colors.brandSecondary,
    shape: Shape = JetsnackTheme.shapes.extraLarge,
    textStyle: TextStyle = JetsnackTheme.typography.labelLarge,
    enabled: Boolean = true,
    content: @Composable RowScope.() -> Unit,
) {
    val interactionSource = remember { MutableInteractionSource() }
    Row(
        modifier
            .clickable(onClick = onClick, indication = null, interactionSource = interactionSource)
            .background(if (enabled) backgroundColor else disabledBackgroundColor, shape)
            .defaultMinSize(58.dp, 40.dp),
        horizontalArrangement = Arrangement.Center,
        verticalAlignment = Alignment.CenterVertically,
        content = content,
    )
}
```

<br />

After Migration:


```kotlin
// Exposed via ComponentStyles.kt
object ComponentStyles {
    val buttonStyle = Style {
        background(colors.brandLight)
        shape(shapes.extraLarge)
        minWidth(58.dp)
        minHeight(40.dp)
        textStyle(typography.labelLarge)
        disabled {
            background(colors.brandSecondary)
        }
    }
}

@Composable
fun CustomButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    style: Style = Style,
    enabled: Boolean = true,
    content: @Composable RowScope.() -> Unit,
) {
    val interactionSource = remember { MutableInteractionSource() }
    val styleState = rememberUpdatedStyleState(interactionSource) {
        it.isEnabled = enabled
    }
    Row(
        modifier
            .clickable(onClick = onClick, indication = null, interactionSource = interactionSource)
            .styleable(styleState, JetsnackTheme.styles.buttonStyle, style),
        horizontalArrangement = Arrangement.Center,
        verticalAlignment = Alignment.CenterVertically,
        content = content,
    )
}
```

<br />

### Step 4: Validate Changes

1. Build the project. Verify that there are no compilation errors.
2. Run your module's screenshot tests.
3. Compare visual outputs of the whole app between the previous and updated components. Verify that no visual layout regressions occur.

© Google LLC · Apache-2.0 · android/skills

Similar skills

Everything for Mobile →

From the same set24

r8-analyzer Inspects Android build files and R8 keep rules for redundant or package-wide directives. Helps slim down app size during Proguard troubleshooting. CX Codex +1 3,200installs testing-setup Analyzes your Android app's testing strategy and installs libraries, infrastructure, and frameworks for unit tests, UI tests, screenshot tests, and end-to-end tests. CX Codex +1 2,500installs adaptive Guides the agent in adapting Android Compose UI for foldables, tablets, desktop, and phones. Helpful when supporting multiple screen sizes and input devices. CX Codex +1 2,400installs migrate-xml-views-to-jetpack-compose Guides the migration of one Android XML screen to Jetpack Compose, from project review through validation and legacy XML cleanup. CX Codex +1 2,400installs play-billing-library-version-upgrade Walks an Android project from any legacy Google Play Billing Library version to the current stable one. It finds the Gradle dependency itself and rebuilds after every step. CX Codex +1 1,900installs android-intent-security Audits AndroidManifest.xml component settings and intent-handling code to stop Intent Redirection and unauthorized component execution. CX Codex +1 1,700installs engage-sdk-integration Takes an Android app through a Play Engage SDK integration: picks the right vertical, generates the publishing classes, then compiles until it builds. CX Codex +1 1,500installs display-glasses-with-jetpack-compose-glimmer Guidelines for building projected Android XR apps on display glasses with Jetpack Compose Glimmer: theming, focus and additive display behaviour. CX Codex +1 1,500installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor