Skip to content

Migrating from Miuix

COUI is based on Miuix and keeps the same overall API surface, so migrating an existing Miuix project is mostly a mechanical rename: swap the dependency coordinates, update the package prefix, and rename a handful of Miuix* symbols to their COUI* counterparts. This page walks through every step.

TIP

After migration your app keeps working with the same component set — but the visuals change from Xiaomi HyperOS to ColorOS design (colors, corner radii, motion curves, press feedback). See Behavioral and visual differences below.

1. Update dependencies

Replace the Miuix Maven coordinates (top.yukonga.miuix.kmp) with the COUI ones (io.github.suqi8.coui.kmp). Every module has a 1:1 counterpart:

Miuix moduleCOUI module
top.yukonga.miuix.kmp:miuix-uiio.github.suqi8.coui.kmp:coui-ui
top.yukonga.miuix.kmp:miuix-preferenceio.github.suqi8.coui.kmp:coui-preference
top.yukonga.miuix.kmp:miuix-iconsio.github.suqi8.coui.kmp:coui-icons
top.yukonga.miuix.kmp:miuix-blurio.github.suqi8.coui.kmp:coui-blur
top.yukonga.miuix.kmp:miuix-squircleio.github.suqi8.coui.kmp:coui-squircle
top.yukonga.miuix.kmp:miuix-navio.github.suqi8.coui.kmp:coui-nav
top.yukonga.miuix.kmp:miuix-shaderio.github.suqi8.coui.kmp:coui-shader
top.yukonga.miuix.kmp:miuix-coreio.github.suqi8.coui.kmp:coui-core
kotlin
kotlin {
    sourceSets {
        commonMain.dependencies {
            implementation("io.github.suqi8.coui.kmp:coui-ui:1.1.0")
            // Optional modules, same pattern:
            implementation("io.github.suqi8.coui.kmp:coui-preference:1.1.0")
            implementation("io.github.suqi8.coui.kmp:coui-icons:1.1.0")
        }
    }
}

COUI additionally ships io.github.suqi8.coui.kmp:coui-navigation3-ui, an integration for androidx Navigation 3 — see Navigation 3.

2. Update the package prefix

Every package moves from top.yukonga.miuix.kmp.* to io.github.suqi8.coui.kmp.* with the sub-package structure unchanged (basic, theme, utils, icon, extra/preference, blur, nav, …). A single find-and-replace over your sources handles it:

shell
# macOS / Linux (run from your project root)
grep -rl "top.yukonga.miuix.kmp" src | xargs sed -i 's/top\.yukonga\.miuix\.kmp/io.github.suqi8.coui.kmp/g'

On Windows, use your IDE's "Replace in Files" (Ctrl+Shift+R in Android Studio / IntelliJ) with top.yukonga.miuix.kmpio.github.suqi8.coui.kmp.

3. Renamed APIs

All Miuix*-prefixed symbols are renamed to COUI*. The mapping is exactly 1:1:

MiuixCOUI
MiuixTheme (composable + object)COUITheme
MiuixIndicationCOUIIndication
MiuixPopupUtilsCOUIPopupUtils
MiuixPopupHostCOUIPopupHost
MiuixScrollBehaviorCOUIScrollBehavior
MiuixIconsCOUIIcons
MiuixOverscrollEffectCOUIOverscrollEffect
MiuixOverscrollFactoryCOUIOverscrollFactory
NavTransitions.MiuixDefaultNavTransitions.COUIDefault
BadgedBoxBadgeBox (signature also changed, see below)

A second find-and-replace of MiuixThemeCOUITheme, MiuixIconsCOUIIcons, etc. covers these. The folmeSpring easing helper (formerly in MiuixEasing.kt, now COUIEasing.kt) keeps its name — no code change needed there.

4. Changed APIs

A few components were rebuilt for ColorOS and their signatures differ.

Badge

Miuix's Badge takes free-form content; COUI's Badge is count-based and picks its form automatically — a dot when count <= 0, a number capsule for a positive count, and an ellipsis form for large counts. BadgedBox is renamed to BadgeBox and gains an overhang parameter controlling how far the badge sticks out of the content.

kotlin
// Miuix
BadgedBox(badge = { Badge { Text("8") } }) { Icon(...) }

// COUI
BadgeBox(badge = { Badge(count = 8) }) { Icon(...) }

TextField

COUI's TextField adds a backgroundMode: TextFieldMode parameter with three ColorOS forms — Rectangle (stroked rounded rectangle), Line (bottom underline, the default) and None (bare text). Related default changes and additions:

  • useLabelAsPlaceholder now defaults to true (ColorOS fields use a hint instead of a floating label; Miuix defaulted to false).
  • New parameters: justShowFocusLine, isError, maxCount (character counter), showClearButton, showPasswordToggle.
  • insideMargin and textStyle defaults now depend on the selected mode.

For the ColorOS "card input" with a separate title above the field, use the new InputView instead.

PressFeedbackType

PressFeedbackType (used by Card and other pressables) gains a new Tint value — the COUI press-mask feedback. Any exhaustive when over it stops compiling until you add the new branch (or an else):

kotlin
when (pressFeedbackType) {
    PressFeedbackType.None -> ...
    PressFeedbackType.Sink -> ...
    PressFeedbackType.Tilt -> ...
    PressFeedbackType.Tint -> ... // new in COUI
}

Dialog content padding

OverlayDialog / WindowDialog deliberately apply no padding to the content slot, so button bars and dividers can span the full dialog width (matching ColorOS). If your Miuix dialogs relied on built-in content insets, wrap your content in its own padding — 24.dp horizontal matches the COUI title/summary insets:

kotlin
OverlayDialog(show = showDialog, title = "Title", onDismissRequest = { ... }) {
    Column(Modifier.padding(start = 24.dp, end = 24.dp, bottom = 24.dp)) {
        // dialog body
    }
}

If you show many dialogs, wrap this once in your own AppDialog composable instead of padding every call site.

TopAppBar

The navigation icon already carries a built-in navigationIconPadding of 16.dp. If you added your own start padding around the back button under Miuix, remove it — otherwise the icon sits too far from the edge.

TabRow

TabRow is visually rebuilt as ColorOS segment buttons. The signature is compatible, with small differences: itemSpacing defaults to 0.dp (was 9.dp; TabRowWithContour was 5.dp), the plain TabRow defaults to a transparent background and accepts an indication parameter, and TabRowWithContour gains a contourPadding parameter.

Switch

Switch gains isLoading: Boolean = false — while loading, the thumb shows the COUI spinner and the switch cannot be toggled (mirroring ColorOS async settings).

5. Migrating from an older Miuix (the extra package)

Older Miuix releases shipped a top.yukonga.miuix.kmp.extra package with Super*-prefixed components. Both Miuix and COUI have since split it up; if your project still uses extra.*, map as follows:

Old Miuix (extra.*)COUI
SuperDialogoverlay.OverlayDialog (or window.WindowDialog) — show is now a plain Boolean instead of MutableState<Boolean>
SuperCheckboxcoui-preference: preference.CheckboxPreference
SuperSwitchcoui-preference: preference.SwitchPreference
SuperArrowcoui-preference: preference.ArrowPreference
SuperDropdowncoui-preference: preference.OverlayDropdownPreference / WindowDropdownPreference
SuperSpinnercoui-preference: preference.OverlaySpinnerPreference / WindowSpinnerPreference
CheckboxLocationcoui-preference: preference.CheckboxLocation
WindowBottomSheetwindow.WindowBottomSheet (package changed only)

The preference components live in the separate coui-preference artifact — add it to your dependencies if you only had miuix before. Old direct styling parameters (such as TextField's backgroundColor) have generally moved into the corresponding Defaults.…Colors(...) factories.

6. Custom color schemes

The Colors constructor keeps Miuix's parameter order, so a fully custom scheme built with positional arguments carries over unchanged and keeps compiling. That said, consider deleting your custom palette entirely — lightColorScheme() / darkColorScheme() now return the native ColorOS 16 palette, which is usually what a COUI app wants; a real-world migration removed ~220 lines of custom colors this way.

7. Behavioral and visual differences

The API stays familiar, but every component is rethemed to ColorOS 16:

  • Colors: the color scheme values follow ColorOS (accent, container and surface colors differ from HyperOS); keep using COUITheme.colorScheme.* and your code picks the new values up automatically.
  • Shape and metrics: corner radii, paddings and component sizes follow the ColorOS specification.
  • Motion: animation curves and press feedback (scale/tint) follow COUI's motion design.
  • Dynamic color: Monet / dynamic color is still supported through ThemeController (ColorSchemeMode.MonetSystem, MonetLight, MonetDark), exactly as before — see Theme System.

8. New components

Migrating also unlocks components that do not exist in Miuix:

Changelog

Released under the Apache-2.0 License