跪拜 Guibai
← All articles
Android · Frontend

Kuikly Is a KMP UI Framework That Renders Natively on Six Targets

By 黄林晴 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Kuikly gives Kotlin-centric Android teams a path to ship UI on iOS, HarmonyOS, and the web without adopting Dart or JavaScript. The native-per-platform renderer model avoids embedding a heavy generic engine, but the real integration cost shows up in the adapter surface — images, routing, threading, and logging all need host-side wiring.

Summary

Kuikly splits cross-platform work into two layers: a shared Kotlin Multiplatform core handles declarative UI, reactive state, layout, and bridge communication, while per-platform renderers draw the actual native widgets. Android, iOS, HarmonyOS, Web, Mini Program, and macOS targets each get their own rendering shell. The AOT-mode SDK footprint is about 300 KB on Android and 1.2 MB on iOS, keeping the engine itself small.

Integrating into an existing Android app means adding the renderer dependency, wiring up a container Activity that delegates lifecycle events, and implementing five required adapters for images, logging, exceptions, routing, and threading. Version mismatches between the core and renderer artifacts can cause runtime failures rather than compile errors.

Kuikly also ships a Compose DSL adapted from Jetpack Compose 1.7.3, repackaged under a Tencent namespace. This is not stock Compose Multiplatform; it is a fork tuned for Kuikly's own rendering pipeline. The framework's dynamic product support makes it suited for large apps that need per-page grayscale releases and modular distribution.

Takeaways
AOT-mode SDK overhead is roughly 300 KB on Android and 1.2 MB on iOS, not counting app-specific pages and resources.
Kuikly separates a shared KMP Core (UI, state, layout, bridge) from per-platform Render modules that draw native widgets.
The framework supports Android 5.0+, iOS 12.0+, and HarmonyOS Next 5.0.0(12)+, covering older Android devices.
Web and Mini Program targets are currently beta; macOS support is alpha.
Existing Android apps need a container Activity, lifecycle forwarding to a delegator, and five adapters: images, logging, exceptions, routing, and threading.
Version alignment between core and renderer artifacts is critical; mismatches surface as runtime bugs, not build failures.
The Compose DSL is a fork of Jetpack Compose 1.7.3 repackaged under com.tencent.kuikly.compose, not stock Compose Multiplatform.
Each platform keeps its own shell project and toolchain; shared KMP pages do not eliminate per-platform build and signing work.
Conclusions

Kuikly's architecture treats the shared KMP layer as a UI protocol, not a rendering engine. That shifts the complexity from 'how do we draw pixels everywhere' to 'how do we map a common widget tree onto each platform's native controls,' which is a different set of trade-offs than Flutter's approach.

The 300 KB / 1.2 MB AOT numbers are unusually specific for a cross-platform framework announcement and signal that binary size was a first-order design constraint, not an afterthought.

Forking Jetpack Compose 1.7.3 into a Tencent namespace rather than using Compose Multiplatform directly suggests the rendering requirements diverged enough that a stock solution wouldn't suffice. Teams evaluating Kuikly should treat the Compose DSL as a separate API surface, not a drop-in compatibility layer.

Requiring five host-side adapters for a basic integration makes Kuikly closer to an SDK than a UI library. The integration surface is explicit and documented, but it means adoption in a brownfield app is non-trivial engineering work, not a single dependency addition.

Concepts & terms
KuiklyCore
The shared Kotlin Multiplatform module that handles declarative UI, reactive state updates, layout algorithms, and bridge communication across all target platforms.
KuiklyRender
The per-platform rendering layer that takes the widget tree declared by KuiklyCore and draws it using each platform's native UI components (Android Views, iOS UIKit, etc.).
ContextCodeHandler
A Kuikly integration class on Android that initializes the rendering context and provides the openPage() method to mount a Kuikly page into a host ViewGroup.
KuiklyRenderViewBaseDelegator
The object that manages a Kuikly page's lifecycle on Android; the host Activity must forward onResume, onPause, and onDetach calls to it.
From the discussion
Featured comments
迎风破浪

I tried the official demo and didn't want to continue. 1. The demo project had a bunch of errors and warnings without changing anything. It runs, but I can't accept that. 2. In a newly created project, the Kuikly version was from last year. It took ages to find where to change the version number, and the official site only lists the latest Kuikly version — I couldn't find the latest KOTLIN_OHOS_VERSION anywhere. 3. Shouldn't the version be declared in Gradle? It's declared through an object instead, so changing it doesn't even trigger a Gradle sync.

See top comments, translated →
Source: juejin.cn ↗ Google Translate ↗ Backup ↗