---
title: Implementation
---

# How it works

Ray is a runtime built on top of Remax. It is essentially a `react-reconciler` based miniapp-side renderer. For more information about `react-reconciler` and React renderer, [check out this video](https://www.youtube.com/watch?v=CGpMlWVcHok).

MiniApp shields the Document Object Model (DOM), so the code is run in a worker thread and is not allowed to directly manipulate the DOM in the view layer. Ray imports `VNode` to make React update `VNode` first in the reconciliation process instead of directly changing the DOM.

The basic structure of `VNode` is as follows:

```js
interface VNode {
  id: number;
  container: Container;
  children: VNode[];
  mounted: boolean;
  type: string | symbol;
  props?: any;
  parent: VNode | null;
  text?: string;
  appendChild(node: VNode): void;
  removeChild(node: VNode): void;
  insertBefore(newNode: VNode, referenceNode: VNode): void;
  toJSON(): RawNode;
}
```

- `id`: The node ID that is auto-incremented to be unique for each node.
- `container`: It is similar to `ReactDOM.render(<App />, document.getElementById('root'))`. Ray renders components to a container that is used to save the reference to `VNode`.
- `children`: The child node.
- `mounted`: Indicates whether a node has been displayed in the view layer.
- `type`: The node type, that is the basic component of a miniapp, such as `view` and `text`.
- `props`: The node property.
- `parent`: The parent node.
- `text`: The text of the text node.

`VNode` adopts a tree structure. In `VNode`, we implement node operation methods similar to those in `DOM`. After React updates `VNode`, the `toJSON` method is invoked to convert `VNode` into a JSON object.

Take the following page component as an example.

```js
import React from 'react';
import { View, Text } from '@ray-js/ray';
const IndexPage = () => {
  return (
    <View className="greeting">
      <Text>Hello Ray</Text>
    </View>
  );
};
export default IndexPage;
```

Ray renders this component into the following `VNode` structure.

```json
{
  "id": 0,
  "type": "root",
  "children": [
    {
      "id": 1,
      "type": "view",
      "props": {
        "className": "greeting"
      },
      "children": [
        {
          "id": 2,
          "type": "text",
          "props": {},
          "children": [
            {
              "type": "plain-text",
              "text": "Hello Ray"
            }
          ]
        }
      ]
    }
  ]
}
```

The `root` node is created internally by Ray. The rendered `VNode` becomes the `data` of the `Page` in a miniapp.

## Display interfaces in the view layer

In the previous section, the React component is rendered into a `VNode` in JSON object that becomes the `data` of the `Page` in a miniapp. In this section, we will show you how to display this `data` in the miniapp template.

When we build a Ray application, a page template is generated to display `VNode`, as shown below.

```xml
<block a:for="{{root.children}}" a:key="{{item.id}}">
  <template is="{{'REMAX_TPL_' + item.type}}" data="{{item: item}}" />
</block>

<template name="REMAX_TPL_view">
  <view class="{{item.props['className']}}">
    <block a:for="{{item.children}}" key="{{item.id}}">
      <template is="{{'REMAX_TPL_' + item.type}}" data="{{item: item}}" />
    </block>
  </view>
</template>

<template name="REMAX_TPL_text">
  <text>
    <block a:for="{{item.children}}" key="{{item.id}}">
      <template is="{{'REMAX_TPL_' + item.type}}" data="{{item: item}}" />
    </block>
  </text>
</template>

<template name="REMAX_TPL_plain-text">
  <block>{{item.text}}</block>
</template>
```

The above code traverses the child element of the root node and selects the corresponding template by the type of the child element to render this child element. Then, it traverses the child element of the current element in each template to traverse the entire node tree recursively.

This is how Ray is implemented. You can optimize the code as needed.
