
Comprehensive UI component suite with 72 reusable controls across forms, navigation, data display, feedback and layout. Runtime theme and language switching, per-component demos and spec-driven CI.
Build beautiful, iOS-inspired UI across iOS, Android, Web, and HarmonyOS with GearUI Kit, a Kotlin Multiplatform (KMP) UI framework.
com.gearui:gearui-kit:1.0.0-beta8
1.0.0-beta1 was the first public release (2026-08-15)ohosArm64) through a separate configuration; not published to Maven Centralzoujiaqing
zoujiaqing@gmail.com
Captured from the sample app on an iPhone 17 Pro Max simulator (iOS 26.2).
| Home (Chinese) | Home (English) | Settings (Light) | Settings (Dark) |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Language and theme are switched at runtime from the settings page; every component follows both without any per-screen wiring.
82 components in 6 categories. Every one of them ships a demo page in the sample app.
| Category | Components |
|---|---|
| Basic (9) |
Button, Icon, Link, CloseButton, PressableFeedback, Text, Tag, Badge, Divider
|
| Form (22) |
Input, Checkbox, AgreementCheckbox, Radio, InputOTP, ComboBox, NumberField, ToggleButton, InputGroup, Switch, Slider, Stepper, Textarea, Rate, Select, Picker, DatePicker, Upload, Form, Cascader, ListBox, ColorPicker
|
| Navigation (8) |
NavBar, BottomNavBar, Tabs, Drawer, Steps, IndexBar, Segmented, Toolbar
|
| Data display (21) |
List, Card, Cell, CellGroup, Table, Image, ImageViewer, Avatar, ScrollShadow, Collapse, Progress, Empty, Skeleton, Timeline, Calendar, Format, Watermark, Meter, User, Code, Kbd
|
| Feedback (15) |
SwipeCell, ActionSheet, Toast, Dialog, Tooltip, ContextMenu, Loading, Alert, NoticeBar, Notification, Snackbar, Popup, Popover, Result, Tour
|
| Layout (7) |
Grid, Swiper, SearchBar, PullRefresh, LoadMore, BottomSheet, BackTop
|
Basic
| Component | Purpose |
|---|---|
Button |
Trigger actions |
Icon |
Icon display |
Link |
Link and LinkButton |
CloseButton |
Unified dismiss button |
PressableFeedback |
Scale and highlight for any tappable area |
Text |
Text display |
Tag |
Marking and classification |
Badge |
Message count indicator |
Divider |
Content separator |
Form
| Component | Purpose |
|---|---|
Input |
Text input |
Checkbox |
Multiple selection |
AgreementCheckbox |
Terms and privacy consent |
Radio |
Single selection |
InputOTP |
One-time code input |
ComboBox |
Filterable suggestions |
NumberField |
Typed and stepped number |
ToggleButton |
Toggle and button group |
InputGroup |
Field with attached blocks |
Switch |
Toggle switch |
Slider |
Value selection |
Stepper |
Number stepper |
Textarea |
Multiline text input |
Rate |
Rating |
Select |
Dropdown selector |
Picker |
Multi-column picker |
DatePicker |
Date & time picker |
Upload |
File upload |
Form |
Form container |
Cascader |
Cascade selector |
ListBox |
Single or multiple choice shown in the page |
ColorPicker |
Swatches, color plane and hex entry |
Navigation
| Component | Purpose |
|---|---|
NavBar |
Page navigation bar |
BottomNavBar |
App bottom navigation |
Tabs |
Content switching |
Drawer |
Slide drawer |
Steps |
Step indicator |
IndexBar |
Alphabet index |
Segmented |
Segmented control |
Toolbar |
Related actions that wrap on narrow screens |
Data display
| Component | Purpose |
|---|---|
List |
List display |
Card |
Card container |
Cell |
List cell component |
CellGroup |
Grouped list rows |
Table |
Data table |
Image |
Image display |
ImageViewer |
Image preview |
Avatar |
User avatar |
ScrollShadow |
Fades scrollable edges |
Collapse |
Content collapse |
Progress |
Progress display |
Empty |
Empty state |
Skeleton |
Loading placeholder |
Timeline |
Timeline display |
Calendar |
Calendar display |
Format |
Compact numbers, relative time, lunar |
Watermark |
Page watermark |
Meter |
A measurement within known bounds |
User |
Avatar, name and description |
Code |
Inline code and copyable snippets |
Kbd |
Web and external-keyboard shortcut hint |
Feedback
| Component | Purpose |
|---|---|
SwipeCell |
Swipeable cell |
ActionSheet |
Bottom action sheet |
Toast |
Message toast |
Dialog |
Modal dialog |
Tooltip |
Tooltip |
ContextMenu |
Context menu |
Loading |
Loading state |
Alert |
Inline status message |
NoticeBar |
Scrolling announcement |
Notification |
Global notification |
Snackbar |
Bottom message |
Popup |
Popup content |
Popover |
Popover tooltip |
Result |
Operation result |
Tour |
Feature guide |
Layout
| Component | Purpose |
|---|---|
Grid |
Grid layout |
Swiper |
Content carousel |
SearchBar |
Search input |
PullRefresh |
Pull to refresh a list |
LoadMore |
Load the next page of a list |
BottomSheet |
Bottom sheet |
BackTop |
Back to top |
The table above is generated from sample/.../config/ComponentConfig.kt by
scripts/gen_component_index.py; a CI check fails when it goes stale.
Released on Maven Central. Declare the single root coordinate — Gradle reads the
module metadata and resolves the per-target artifact (-android, -js,
-iosarm64, …) for whatever you are compiling. Never depend on those directly.
GearUI Kit depends on KuiklyUI, and KuiklyUI 2.x is published to Tencent's Maven mirror rather than Maven Central, so add that repository too — without it the dependency does not resolve.
repositories {
mavenCentral()
maven("https://mirrors.tencent.com/nexus/repository/maven-tencent/") // KuiklyUI 2.x
}
kotlin {
sourceSets {
commonMain.dependencies {
implementation("com.gearui:gearui-kit:1.0.0-beta8")
}
}
}First publish from the gearui-kit project to your local Maven repository:
./gradlew :gearui-kit:publishToMavenLocalThen add it in your app project:
repositories {
mavenLocal()
mavenCentral()
maven("https://mirrors.tencent.com/nexus/repository/maven-tencent/") // KuiklyUI 2.x
}
kotlin {
sourceSets {
commonMain.dependencies {
implementation("com.gearui:gearui-kit:1.0.0-beta8")
}
}
}dependencies {
implementation(project(":gearui-kit"))
}@Page("MainPage")
class MainPage : View() {
@Composable
// View mounts the App root (theme, i18n, overlays, safe area) for you.
// Override themeMode() / themeSpec() to change it; do not call App() here.
override fun Content() {
MainPageContent()
}
}
@Composable
private fun MainPageContent() {
val colors = Theme.colors
Column(
modifier = Modifier
.fillMaxSize()
.background(colors.background)
.padding(16.dp)
) {
Button(
text = I18n.strings.buttonConfirm,
theme = ButtonTheme.PRIMARY,
onClick = {}
)
}
}Kuikly runs composition, measure and layout on its own context thread, created with the platform default stack (about 1 MB). Placement recurses once per layout level, so deep screens can overflow it — debuggable builds first, since ART runs them without optimisations. Give the thread the main thread's 8 MB before the first page opens:
KuiklyRenderAdapterManager.krThreadAdapter = object : IKRThreadAdapter {
private val executor = Executors.newCachedThreadPool()
override fun executeOnSubThread(task: () -> Unit) = executor.execute(task)
override fun stackSize(): Long = 8L * 1024 * 1024
}The sample does this in SampleThreadAdapter.
| Platform | Library | Sample | CI |
|---|---|---|---|
| Android | ✅ | ✅ | ✅ |
| iOS | ✅ | ✅ | ✅ |
| Web (H5) | ✅ | ✅ 75 of 76 demos | ✅ |
| HarmonyOS | ✅ | ✅ builds | — |
Web runs through KuiklyUI's web renderer; the one demo that fails is Table,
on a Kotlin/JS partial-linkage error in the sample's own demo file rather than
in the component. See sample/jsApp/README.md.
HarmonyOS is supported and builds end to end — Kotlin/Native → CMake NAPI glue
→ ArkTS → an installable HAP carrying both libshared.so and
libkuikly_entry.so. It cannot be a target of the normal build: the KuiklyUI
artifacts carrying ohosArm64 are published against Kotlin 2.0.21-KBA-010, so
ohos uses a parallel build configuration selected with
-c settings.ohos.gradle.kts:
./gradlew -c settings.ohos.gradle.kts :sample:linkSharedDebugSharedOhosArm64The HAP has not been launched on a device or emulator yet, so nothing about the UI is verified there — installing needs an emulator image and a signed package, both behind a Huawei developer account. See sample/ohosApp/README.md for the build steps and exactly what remains.
gearui-kit/src/commonMain/kotlin/com/gearui/components
sample/
Tabs (content switching).Collapse.Accordion (no standalone Accordion component maintained).Documentation is written in English first; *.zh-Hans.md files are the Chinese
counterparts. Code comments are English only — enforced by
scripts/ci/check_english_comments.sh (see
docs/COMPONENT_SPEC.md §8).
# Build the library per platform
./gradlew :gearui-kit:compileDebugKotlinAndroid
./gradlew :gearui-kit:compileKotlinIosSimulatorArm64
./gradlew :gearui-kit:compileKotlinJs
# Run the sample
./gradlew :sample:installDebug # Android
./gradlew :sample:jsApp:jsBrowserDevelopmentRun # Web, then open http://localhost:8081/
# HarmonyOS uses a parallel build configuration (unbuilt — see sample/ohosApp/README.md)
./gradlew -c settings.ohos.gradle.kts :sample:linkSharedDebugSharedOhosArm64
# Architecture guardrails — 20 checks, all runnable locally
for f in scripts/ci/check_*.sh; do "$f"; doneApache License 2.0 — see LICENSE and NOTICE.
Copyright 2026 Shanghai Boyu Information Technology Co., Ltd. Developed by zoujiaqing (zoujiaqing@gmail.com) · netonstream.com
Build beautiful, iOS-inspired UI across iOS, Android, Web, and HarmonyOS with GearUI Kit, a Kotlin Multiplatform (KMP) UI framework.
com.gearui:gearui-kit:1.0.0-beta8
1.0.0-beta1 was the first public release (2026-08-15)ohosArm64) through a separate configuration; not published to Maven Centralzoujiaqing
zoujiaqing@gmail.com
Captured from the sample app on an iPhone 17 Pro Max simulator (iOS 26.2).
| Home (Chinese) | Home (English) | Settings (Light) | Settings (Dark) |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Language and theme are switched at runtime from the settings page; every component follows both without any per-screen wiring.
82 components in 6 categories. Every one of them ships a demo page in the sample app.
| Category | Components |
|---|---|
| Basic (9) |
Button, Icon, Link, CloseButton, PressableFeedback, Text, Tag, Badge, Divider
|
| Form (22) |
Input, Checkbox, AgreementCheckbox, Radio, InputOTP, ComboBox, NumberField, ToggleButton, InputGroup, Switch, Slider, Stepper, Textarea, Rate, Select, Picker, DatePicker, Upload, Form, Cascader, ListBox, ColorPicker
|
| Navigation (8) |
NavBar, BottomNavBar, Tabs, Drawer, Steps, IndexBar, Segmented, Toolbar
|
| Data display (21) |
List, Card, Cell, CellGroup, Table, Image, ImageViewer, Avatar, ScrollShadow, Collapse, Progress, Empty, Skeleton, Timeline, Calendar, Format, Watermark, Meter, User, Code, Kbd
|
| Feedback (15) |
SwipeCell, ActionSheet, Toast, Dialog, Tooltip, ContextMenu, Loading, Alert, NoticeBar, Notification, Snackbar, Popup, Popover, Result, Tour
|
| Layout (7) |
Grid, Swiper, SearchBar, PullRefresh, LoadMore, BottomSheet, BackTop
|
Basic
| Component | Purpose |
|---|---|
Button |
Trigger actions |
Icon |
Icon display |
Link |
Link and LinkButton |
CloseButton |
Unified dismiss button |
PressableFeedback |
Scale and highlight for any tappable area |
Text |
Text display |
Tag |
Marking and classification |
Badge |
Message count indicator |
Divider |
Content separator |
Form
| Component | Purpose |
|---|---|
Input |
Text input |
Checkbox |
Multiple selection |
AgreementCheckbox |
Terms and privacy consent |
Radio |
Single selection |
InputOTP |
One-time code input |
ComboBox |
Filterable suggestions |
NumberField |
Typed and stepped number |
ToggleButton |
Toggle and button group |
InputGroup |
Field with attached blocks |
Switch |
Toggle switch |
Slider |
Value selection |
Stepper |
Number stepper |
Textarea |
Multiline text input |
Rate |
Rating |
Select |
Dropdown selector |
Picker |
Multi-column picker |
DatePicker |
Date & time picker |
Upload |
File upload |
Form |
Form container |
Cascader |
Cascade selector |
ListBox |
Single or multiple choice shown in the page |
ColorPicker |
Swatches, color plane and hex entry |
Navigation
| Component | Purpose |
|---|---|
NavBar |
Page navigation bar |
BottomNavBar |
App bottom navigation |
Tabs |
Content switching |
Drawer |
Slide drawer |
Steps |
Step indicator |
IndexBar |
Alphabet index |
Segmented |
Segmented control |
Toolbar |
Related actions that wrap on narrow screens |
Data display
| Component | Purpose |
|---|---|
List |
List display |
Card |
Card container |
Cell |
List cell component |
CellGroup |
Grouped list rows |
Table |
Data table |
Image |
Image display |
ImageViewer |
Image preview |
Avatar |
User avatar |
ScrollShadow |
Fades scrollable edges |
Collapse |
Content collapse |
Progress |
Progress display |
Empty |
Empty state |
Skeleton |
Loading placeholder |
Timeline |
Timeline display |
Calendar |
Calendar display |
Format |
Compact numbers, relative time, lunar |
Watermark |
Page watermark |
Meter |
A measurement within known bounds |
User |
Avatar, name and description |
Code |
Inline code and copyable snippets |
Kbd |
Web and external-keyboard shortcut hint |
Feedback
| Component | Purpose |
|---|---|
SwipeCell |
Swipeable cell |
ActionSheet |
Bottom action sheet |
Toast |
Message toast |
Dialog |
Modal dialog |
Tooltip |
Tooltip |
ContextMenu |
Context menu |
Loading |
Loading state |
Alert |
Inline status message |
NoticeBar |
Scrolling announcement |
Notification |
Global notification |
Snackbar |
Bottom message |
Popup |
Popup content |
Popover |
Popover tooltip |
Result |
Operation result |
Tour |
Feature guide |
Layout
| Component | Purpose |
|---|---|
Grid |
Grid layout |
Swiper |
Content carousel |
SearchBar |
Search input |
PullRefresh |
Pull to refresh a list |
LoadMore |
Load the next page of a list |
BottomSheet |
Bottom sheet |
BackTop |
Back to top |
The table above is generated from sample/.../config/ComponentConfig.kt by
scripts/gen_component_index.py; a CI check fails when it goes stale.
Released on Maven Central. Declare the single root coordinate — Gradle reads the
module metadata and resolves the per-target artifact (-android, -js,
-iosarm64, …) for whatever you are compiling. Never depend on those directly.
GearUI Kit depends on KuiklyUI, and KuiklyUI 2.x is published to Tencent's Maven mirror rather than Maven Central, so add that repository too — without it the dependency does not resolve.
repositories {
mavenCentral()
maven("https://mirrors.tencent.com/nexus/repository/maven-tencent/") // KuiklyUI 2.x
}
kotlin {
sourceSets {
commonMain.dependencies {
implementation("com.gearui:gearui-kit:1.0.0-beta8")
}
}
}First publish from the gearui-kit project to your local Maven repository:
./gradlew :gearui-kit:publishToMavenLocalThen add it in your app project:
repositories {
mavenLocal()
mavenCentral()
maven("https://mirrors.tencent.com/nexus/repository/maven-tencent/") // KuiklyUI 2.x
}
kotlin {
sourceSets {
commonMain.dependencies {
implementation("com.gearui:gearui-kit:1.0.0-beta8")
}
}
}dependencies {
implementation(project(":gearui-kit"))
}@Page("MainPage")
class MainPage : View() {
@Composable
// View mounts the App root (theme, i18n, overlays, safe area) for you.
// Override themeMode() / themeSpec() to change it; do not call App() here.
override fun Content() {
MainPageContent()
}
}
@Composable
private fun MainPageContent() {
val colors = Theme.colors
Column(
modifier = Modifier
.fillMaxSize()
.background(colors.background)
.padding(16.dp)
) {
Button(
text = I18n.strings.buttonConfirm,
theme = ButtonTheme.PRIMARY,
onClick = {}
)
}
}Kuikly runs composition, measure and layout on its own context thread, created with the platform default stack (about 1 MB). Placement recurses once per layout level, so deep screens can overflow it — debuggable builds first, since ART runs them without optimisations. Give the thread the main thread's 8 MB before the first page opens:
KuiklyRenderAdapterManager.krThreadAdapter = object : IKRThreadAdapter {
private val executor = Executors.newCachedThreadPool()
override fun executeOnSubThread(task: () -> Unit) = executor.execute(task)
override fun stackSize(): Long = 8L * 1024 * 1024
}The sample does this in SampleThreadAdapter.
| Platform | Library | Sample | CI |
|---|---|---|---|
| Android | ✅ | ✅ | ✅ |
| iOS | ✅ | ✅ | ✅ |
| Web (H5) | ✅ | ✅ 75 of 76 demos | ✅ |
| HarmonyOS | ✅ | ✅ builds | — |
Web runs through KuiklyUI's web renderer; the one demo that fails is Table,
on a Kotlin/JS partial-linkage error in the sample's own demo file rather than
in the component. See sample/jsApp/README.md.
HarmonyOS is supported and builds end to end — Kotlin/Native → CMake NAPI glue
→ ArkTS → an installable HAP carrying both libshared.so and
libkuikly_entry.so. It cannot be a target of the normal build: the KuiklyUI
artifacts carrying ohosArm64 are published against Kotlin 2.0.21-KBA-010, so
ohos uses a parallel build configuration selected with
-c settings.ohos.gradle.kts:
./gradlew -c settings.ohos.gradle.kts :sample:linkSharedDebugSharedOhosArm64The HAP has not been launched on a device or emulator yet, so nothing about the UI is verified there — installing needs an emulator image and a signed package, both behind a Huawei developer account. See sample/ohosApp/README.md for the build steps and exactly what remains.
gearui-kit/src/commonMain/kotlin/com/gearui/components
sample/
Tabs (content switching).Collapse.Accordion (no standalone Accordion component maintained).Documentation is written in English first; *.zh-Hans.md files are the Chinese
counterparts. Code comments are English only — enforced by
scripts/ci/check_english_comments.sh (see
docs/COMPONENT_SPEC.md §8).
# Build the library per platform
./gradlew :gearui-kit:compileDebugKotlinAndroid
./gradlew :gearui-kit:compileKotlinIosSimulatorArm64
./gradlew :gearui-kit:compileKotlinJs
# Run the sample
./gradlew :sample:installDebug # Android
./gradlew :sample:jsApp:jsBrowserDevelopmentRun # Web, then open http://localhost:8081/
# HarmonyOS uses a parallel build configuration (unbuilt — see sample/ohosApp/README.md)
./gradlew -c settings.ohos.gradle.kts :sample:linkSharedDebugSharedOhosArm64
# Architecture guardrails — 20 checks, all runnable locally
for f in scripts/ci/check_*.sh; do "$f"; doneApache License 2.0 — see LICENSE and NOTICE.
Copyright 2026 Shanghai Boyu Information Technology Co., Ltd. Developed by zoujiaqing (zoujiaqing@gmail.com) · netonstream.com