Mobile Development 25 min read

Tencent Kuikly Open-Sources HarmonyOS Support: Inside the Native-Performance Adaptation Journey

Tencent's Kuikly cross-platform framework open-sources HarmonyOS support and Compose DSL beta, achieving native-level performance via Kotlin Multiplatform and CAPI rendering, with detailed engineering trade-offs on ArkUI mapping, text layout reuse, and Kotlin Native optimization.

TDS Framework
TDS Framework
TDS Framework
Tencent Kuikly Open-Sources HarmonyOS Support: Inside the Native-Performance Adaptation Journey

Background

Kuikly is Tencent's widely used cross-platform development framework built on Kotlin Multiplatform (KMP), developed by Tencent's Oteam. It provides a unified tech stack for cross-platform development. Following Android and iOS open-source releases, Kuikly now open-sources HarmonyOS platform support and Compose DSL support, further improving multi-platform adaptation and HarmonyOS development efficiency. Kuikly HarmonyOS version has already been integrated into multiple Tencent apps including QQ Browser, Tencent News, Sogou Input, WeSing, and Stock Portfolio.

HarmonyOS Performance Adaptation

Kuikly targets high performance and dynamic capabilities. After HarmonyOS Next launched, Kuikly invested early in adaptation, leveraging its lightweight rendering architecture for a quick initial version. Continuous iteration achieved native-level performance.

Benchmark results on a complex Feed flow scenario (Huawei Mate 60):

Kuikly page opening speed is 6x faster than React Native on HarmonyOS.

Kuikly HarmonyOS version matches Android version's high performance, with page opening speed essentially identical to native.

Overall Adaptation Approach

Kuikly Architecture Recap

Kuikly is a one-code-multi-platform framework pursuing ultimate performance, dynamic capabilities, and native experience. It uses KMP to solve common cross-platform issues: performance gaps, inconsistent native experience, and ecosystem fragmentation. Design maximizes logic in Kotlin cross-platform layer, keeping native-side logic minimal.

Kuikly consists of two parts:

KuiklyUI : Supports proprietary DSL and Compose DSL for cross-platform UI development, using lightweight native rendering, supporting page-level dynamic updates.

KuiklyBase : Provides foundational capabilities for full cross-platform UI and KMP logic, including rich cross-platform components, complete debugging, building, publishing, monitoring toolchains, and stability monitoring.

Framework advantages:

One code, five platforms: Android, iOS, HarmonyOS, Web, Mini Programs (Web/Mini Programs open-source in Q2).

Native-level performance: KMP compiles Kotlin to each platform's native artifacts.

Kotlin-driven, pure native toolchain: Reuses native IDEs (Android Studio/VS Code) and profiling tools.

Declarative + reactive DSL: Proprietary DSL improves UI dev efficiency; Compose DSL beta also open-sourced.

Page-level dynamic updates: On Android, dynamic mode uses platform artifacts with near-zero overhead, near-native even on low-end devices.

Lightweight, stable, maintainable: Minimal external dependencies.

Core Adaptation Work

HarmonyOS adaptation is complex and systematic, targeting high performance, native rendering, and dynamic updates. Core work includes: integrating HarmonyOS UI system, encapsulating atomic components, integrating event system, optimizing performance/stability; compiling Kotlin cross-platform logic to efficient HarmonyOS native artifacts, exploring Kotlin JS and Kotlin Native adaptation and optimization; bridging cross-platform and HarmonyOS native layers for mutual calls; building debugging plugins, crash monitoring, and other infrastructure.

Rendering Layer Adaptation

1. ArkUI Rendering Instruction Mapping

a) Original Problem: Mapping Rendering Instructions via Declarative Interface

On Android/iOS, systems provide imperative UI interfaces, matching Kuikly's rendering abstraction for direct native widget manipulation. HarmonyOS uses declarative ArkUI: UI components consist of data and UI description; updates only via modifying bound data. Driving declarative ArkUI from rendering layer became the first adaptation challenge.

b) Initial Solution: Unified Builder Entry, Full Property Binding

After exploration, a new HarmonyOS rendering layer was designed:

Component property updates : Maintain a render node data abstraction; bind render nodes to ArkUI components via decorators; property add/delete/modify triggers UI updates.

UI tree description and updates : Use ArkUI's ForEach (loop rendering) binding an array to create child components. Associate render node data abstractions into a tree, using node children as data, with recursive ArkUI builder calls to describe and mutate the entire UI tree.

c) New Problem: Declarative Mapping Performance Unsatisfactory

Functional implementation via ArkUI declarative UI was quick, but performance benchmarks fell short. Causes:

Component outer layers with set properties doubled actual component hierarchy, hurting performance.

Unable to bind properties on-demand; forced full property binding; modifying one object triggered full property updates.

Component reuse helped little; reuse preparation call overhead became bottleneck.

Kotlin JS to HarmonyOS bytecode mode inefficient.

d) Ultimate Solution: Imperative CAPI for Instruction Mapping

Revisiting Android/iOS implementations, imperative interfaces are most natural for rendering instructions. After collaborating with HarmonyOS system team, obtained early-access CAPI. Research showed clear performance advantages: C-style API suits Kuikly's scenario, higher efficiency, direct interop with Kotlin Native, no extra cross-VM/language call overhead. Despite early CAPI bugs, missing features, and higher development complexity, the team chose CAPI for ultimate performance.

Rendering hierarchy comparison (old vs new) shows CAPI eliminates wrapper layers.

2. C-Node and ArkTS Component Nesting

Real-world scenarios mix custom widgets and Kuikly built-in components — i.e., C-nodes and ArkTS components nested. ArkTS components are declarative; early no solution to dynamically add C children to ArkTS nodes, blocking mixed nesting.

Solution: Shadow Nodes for Seamless Compatibility, Content Slots as Fallback

CAPI imperative interface can add C children to C nodes, and mount ArkTS nodes as children of C nodes. Designed a method bypassing ArkTS node operations to solve nesting:

Add a C shadow node, same size as business custom component. Auto-apply base properties to shadow node and "copy" to business component.

When mounting children to business component, mount them on shadow node instead — visually correct.

Benefit: zero-modification compatibility with existing business and third-party components.

Drawback: parent-child relationship becomes sibling relationship; transform operations on custom node may cause UI anomalies.

After HarmonyOS API 12 introduced content slot support for custom nodes, added support: when business has special needs, add content slot per spec in custom component. In this mode, no shadow node generated; children mounted to slot, keeping UI tree consistent with expectations.

3. Text Rendering Performance Optimization

a) First Implementation: Separate Text Measurement and Rendering

Using CAPI, early exploration separated measurement and rendering: measurement phase uses only size info for layout; rendering phase uses HarmonyOS text widget directly.

Performance analysis in List scrolling showed text measurement consumed >50% of parent container (List) layout time — unacceptable. Needed to reuse layout results, avoid secondary layout at draw time.

b) Intermediate Optimization: Partial Layout Artifact Reuse

HarmonyOS API 12 added new text rendering capabilities allowing retention of layout intermediate artifacts after text layout, besides size info. Tried and verified — significant performance gain, but secondary layout issue persisted.

c) Final Solution: On-Demand Drawing via System Text Drawing Capability

Shifted to directly calling system text drawing interfaces, further reusing layout results. Analysis confirms this completely eliminates text re-layout. Comprehensive comparison of on-screen text layout time shows system API on-demand drawing meets performance targets. Also filled gaps: accessibility, partial background color, substring region click callbacks, aligning with system text widget capabilities.

4. Other Typical Performance and Stability Issues

a) High-Frequency Node Creation/Release Performance

In long lists or extreme scenarios, frequent node create/release calls add measurable overhead. Introduced node reuse mechanism for ultimate performance.

Reuse challenges: node attributes not resettable, reset crashes. Designed reuse strategy for high reuse rate and stability:

Node-level whitelist: high-frequency nodes added to reusable whitelist.

Attribute-level blacklist: non-resettable attributes excluded from reuse pool.

b) Stability Optimization

CAPI increased development difficulty and complexity; many stability issues encountered with high diagnosis/fix cost.

Early XComponent high-frequency rapid create/destroy caused high-probability crashes.

Some system interfaces prone to misuse crashes: system logging interface, node ID reading interface.

All resolved through iterations. Over a year of multi-business online verification, crash rate maintained at low level; stability fully assured.

KuiklyBase HarmonyOS Adaptation

To support Kuikly and business HarmonyOS adaptation, KuiklyBase added HarmonyOS support across Kotlin Native, cross-platform components, and infrastructure.

1. Kotlin Native HarmonyOS Adaptation

Early tried Kotlin JS mode; performance insufficient:

Official Kotlin benchmark: Native performance 950% of JS; large gap, cannot rely on system AOT to close.

HarmonyOS Kotlin JS limitations: no multi-threading (no true concurrency); JS logic runs in worker with memory isolation hurting performance; Kotlin-to-JS numeric ops inefficient. None exist in Kotlin Native.

Solution

Kotlin Native adaptation to HarmonyOS covers compile-time and runtime, illustrated via object creation:

Compile-Time Adaptation

Kotlin 1.9.x uses LLVM 11; Kotlin 2.1 upgrades to LLVM 16. HarmonyOS supports LLVM 12–15. Both Apple and HarmonyOS modify public LLVM with custom optimizations. Apple's target is in public LLVM, so HarmonyOS LLVM can support both iOS and HarmonyOS.

Conventional approach : Compile separately with HarmonyOS and Apple LLVM. Simple, no compatibility issues. Downside: Kotlin doesn't support multi-LLVM architecture, requiring separate Kotlin versions for HarmonyOS and iOS.

KuiklyBase approach : Use Apple LLVM 11 for Kotlin IR → LLVM IR; use HarmonyOS LLVM 12 for LLVM IR → executable. Satisfies requirements without Kotlin architecture changes.

Runtime Adaptation and Optimization

Added HarmonyOS interop files for Kotlin Native, integrated system APIs, adjusted runtime logic for architecture/platform checks to support HarmonyOS.

After initial adaptation, Kotlin official benchmark showed HarmonyOS duration 2.48x same-performance iOS device. Series of HarmonyOS-specific optimizations: inlining optimization, ThreadLocal optimization, coroutine performance optimization. Post-optimization, HarmonyOS Kotlin Native performance improved by multiples, meeting product requirements. Detailed adaptation/optimization to be covered in future article.

2. Debugging Efficiency Optimization: Plugin Enables Kotlin Debugging in HarmonyOS IDE

Using Kotlin Native in HarmonyOS IDE had major debugging pain point: official Kotlin LLDB plugin enables debugging but variable inspection extremely slow, basically unusable.

Optimized Kotlin debug plugin and companion runtime: added debug info retrieval reuse/caching, call merging, info preloading — achieved 40x speedup, making plugin usable for daily debugging.

After debugging became usable, next issue: high barrier to use debug capabilities. Required manual HarmonyOS IDE settings; breakpoints needed finding source files in filesystem and dragging into IDE, or command-line (higher barrier).

Developed HarmonyOS IDE plugin automating debug flow: auto-configures IDE, associates artifact code. User switches to Kuikly panel, sees project SO artifacts and associated files, double-clicks to open files without manual drag. Greatly improves daily debugging efficiency. After broader internal validation, will publish to HarmonyOS IDE plugin marketplace for community.

Compose DSL Beta Release

Based on Kuikly core architecture and universal rendering layer, extended support for standard Compose DSL; beta released. Kuikly Compose DSL support lowers client dev onboarding cost. Core features:

More platform support : Reusing Kuikly universal rendering layer, Kuikly Compose supports standard Compose DSL syntax while seamlessly covering mainstream platforms: Android, iOS, HarmonyOS, Web, and common domestic mini-program platforms, greatly improving app reachability.

Dynamic capabilities : Extending Compose DSL support on Kuikly cross-platform framework layer gives Kuikly Compose inherent dynamic capabilities: hot updates, dynamic delivery.

Native experience : Unlike official Compose's self-rendering, Kuikly Compose retains Kuikly's native rendering advantage, ensuring high-performance native UI experience across platforms.

Details at:

https://kuikly.tds.qq.com/ComposeDSL/overview.html

Difference from ovCompose

Two frameworks differ in rendering approach, dynamic support, performance, multi-platform adaptation. To meet differentiated business needs, Tencent Oteam explores both simultaneously.

Native rendering KuiklyUI : Focuses on static+dynamic dual runtime modes, lightweight native rendering for native UI experience and high consistency; supports Compose API via native component mapping; supports H5 and mini-programs (late June).

Self-rendering ovCompose : Focuses on full alignment with Compose Multiplatform standard API, self-rendering for HarmonyOS adaptation, ensuring three-platform high consistency. For iOS legacy businesses, proposes multi-modal rendering to solve UI mixing.

Technical Outlook

HarmonyOS system evolving rapidly; will maintain close tracking and good adaptation.

Current Kotlin Native GC algorithm has significant improvement space; will continue catching up to Java GC performance.

Currently primarily using HarmonyOS IDE for debugging; future consideration: extend Android Studio KMP plugin or add HarmonyOS-supporting plugin for Android Studio, aligning Android/iOS debugging experience on Android Studio.

Expecting community developers to join in building a one-code-multi-platform, extremely usable, dynamically flexible, full-platform high-performance development framework.

GitHub repo: https://github.com/Tencent-TDS/KuiklyUI Official docs:

https://kuikly.tds.qq.com/%E7%AE%80%E4%BB%8B/arch.html
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Cross-platformHarmonyOSArkUIKotlin MultiplatformCAPIKotlin NativeCompose DSLKuikly
TDS Framework
Written by

TDS Framework

Kuikly is a cross‑platform framework under TDS Client Services, built on Kotlin Multiplatform. A single codebase targets Android, iOS, HarmonyOS, H5, and mini programs, delivering high performance and dynamic updates for efficient full‑platform app development.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.