Implementing React-Based High-Performance HarmonyOS Apps with Taro: Runtime Principles and ArkUI Integration
This article examines how the Taro framework adapts React code to run on Huawei's HarmonyOS by implementing a custom renderer that converts React components into Taro virtual nodes, then maps them to ArkUI structures through a three‑step process involving Taro Elements, RenderNodes, and native ArkUI nodes.
Background
With the rapid development of HarmonyOS, developers aim to migrate existing cross‑platform applications to the platform. Taro, a popular cross‑platform framework, has attracted attention for its potential to support HarmonyOS.
However, HarmonyOS uses the new ArkUI framework for native UI, which differs significantly from the platforms Taro originally supports. Bridging Taro’s React development model with ArkUI’s declarative UI paradigm presents a technical challenge.
This article explores how Taro achieves this by converting React code to run on ArkUI, analyzing the runtime principles, the transformation of React components into ArkUI‑recognizable structures, and the associated challenges and solutions.
Taro Runtime Principle Introduction
To understand the core mechanism of Taro’s adaptation to ArkUI, we first examine Taro’s runtime. Taro cleverly transforms React code into executable forms for various platforms, including HarmonyOS. The following sections detail how React code is converted into ArkUI‑executable form and the node conversion process.
1. From React to Taro
React Cross‑Platform Secret
In Taro’s runtime, the developer‑written React business code is executed first. This code defines the application’s structure, logic, and state management. Understanding React’s core architecture is essential because the renderer maps React’s virtual nodes to the target platform.
After grasping React’s architecture, we see that the Renderer is responsible for mapping virtual node operations to the platform, e.g., react-dom for browsers and react-native for iOS/Android. This design enables React to adapt to different environments.
Based on this idea, the Taro team designed the Taro Renderer , which acts as a bridge between React and Taro’s virtual node tree, allowing React operations to be transformed into Taro’s intermediate representation.
HostConfig Interface Implementation
// Partial HostConfig interface implementation
const hostConfig: HostConfig = {
// create Taro virtual node
createInstance (type, props, _rootContainerInstance, _hostContext, internalInstanceHandle) {
const element: TaroElement = TaroNativeModule.createTaroNode(type);
precacheFiberNode(internalInstanceHandle, element);
updateFiberProps(element, props);
return element;
},
// update props
commitUpdate (dom, updatePayload, _, oldProps, newProps) {
updatePropsByPayload(dom, oldProps, updatePayload);
updateFiberProps(dom, newProps);
},
// insert node
insertBefore (parent: TaroElement, child: TaroElement, refChild: TaroElement) {
parent.insertBefore(child, refChild);
},
// remove node
removeChild (parent: TaroElement, child: TaroElement) {
parent.removeChild(child);
},
// ...
};2. From Taro to ArkUI
The conversion from Taro’s virtual node tree to ArkUI involves several key steps.
First, a component library that maps Taro components to corresponding ArkUI components must be implemented. For example, Taro’s View , Text , and Image components need matching ArkUI counterparts.
During mapping, differences such as composite component structures, hierarchical position adjustments, and platform‑specific components must be handled.
Therefore, a more complex conversion process is required, maintaining a Render Tree as an intermediate bridge.
1. Create Taro Element Based on Component Type
// Create Taro Element based on component type
std::shared_ptr
TaroDocument::CreateElement(napi_value &node) {
// Get component type
TAG_NAME tag_name_ = TaroDOM::TaroElement::GetTagName(node);
std::shared_ptr
item;
switch (tag_name_) {
case TAG_NAME::SCROLL_VIEW: {
item = std::make_shared
(node);
break;
}
case TAG_NAME::IMAGE:
item = std::make_shared
(node);
break;
case TAG_NAME::SPAN:
case TAG_NAME::TEXT: {
item = std::make_shared
(node);
break;
}
case TAG_NAME::SWIPER: {
item = std::make_shared
(node);
break;
}
// ...
}
return item;
}2. Create Taro RenderNode from Taro Element
void TaroSwiper::Build() {
if (!is_init_) {
// create render node
TaroElementRef element = std::static_pointer_cast
(shared_from_this());
auto render_swiper = std::make_shared
(element);
render_swiper->Build();
}
}3. Create ArkUI Node from Taro RenderNode
void TaroSwiperNode::Build() {
NativeNodeApi *nativeNodeApi = NativeNodeApi::getInstance();
// Create a Swiper ArkUI node
SetArkUINodeHandle(nativeNodeApi->createNode(ARKUI_NODE_SWIPER));
}Through these three steps, the C++ layer successfully maps React component structures to native ArkUI components, enabling Taro applications to render accurately on HarmonyOS and providing strong support for cross‑platform development.
Conclusion
The article discussed how Taro bridges React to HarmonyOS ArkUI by implementing a custom renderer and a three‑stage conversion pipeline (Taro Element → Taro RenderNode → ArkUI Node). This architecture allows React‑based applications to run natively on HarmonyOS with high performance.
JD Tech Talk
Official JD Tech public account delivering best practices and technology innovation.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.