React Renderers: an Overview
Tags: react
Published: 2020-09-28 14:47:50

# React Renderers: an Overview

One of the most advanced features of React is the ability to write renderers for different environments. You can be surprised, but it’s possible to create CLI or Hardware apps using React! In this article, I will look over the most interesting React renderers.

# Ink

[Ink](https://github.com/vadimdemedes/ink) is a React for CLIs. It allows you to build and test your CLI output using components:

![https://dev-to-uploads.s3.amazonaws.com/i/j93bjb1dhhskapybmm0r.gif](https://dev-to-uploads.s3.amazonaws.com/i/j93bjb1dhhskapybmm0r.gif)

The code of the demo:

```jsx
const Counter = () => {
  const [i, setI] = useState(0);

  useEffect(() => {
    setInterval(() => {
      setI(prev => prev + 1);
    }, 100);
  }, []);

  return <Color>
    {i} tests passed
  </Color>;
}
```

Ink used by popular libraries such a [Gatsby](https://www.gatsbyjs.com/), [Parcel](https://parceljs.org/), [Yarn 2](https://yarnpkg.com/getting-started/install/), etc. Also, there are similar libraries such a [react-blessed](https://github.com/Yomguithereal/react-blessed).

# React Hardware

[React Hardware](https://github.com/iamdustan/react-hardware) allows to operate some hardware devices (such as Arduino) through React components:

![https://media.giphy.com/media/BeoH46ppAdTPYfpIss/giphy.gif](https://media.giphy.com/media/BeoH46ppAdTPYfpIss/giphy.gif)

The code of the demo:

```jsx
const App = () => {
  const [ledState, setLedState] = useState(false);

  useEffect(() => {
    setInterval(() => {
      setLedState(prev => !prev);
    }, 1000);
  }, []);

  return <Led pin={13} value={ledState ? 255 : 0} />
}
const PORT = 'dev/tty.usbmodem1411';
ReactHardware.render(<App />, PORT);
```

# React Figma

[React Figma](https://github.com/react-figma/react-figma) is a React renderer into [Figma](https://www.figma.com/). It allows you to use React components as a source for your designs.

[![https://user-images.githubusercontent.com/1270648/89524327-09365c80-d7ed-11ea-9cb1-08f6fd56a350.gif](https://user-images.githubusercontent.com/1270648/89524327-09365c80-d7ed-11ea-9cb1-08f6fd56a350.gif)](https://github.com/react-figma/react-figma)

[React Figma](https://github.com/react-figma/react-figma) can be useful for describing design systems, creating automations or integrations between some APIs and Figma. E.g. [OpenAI](https://openai.com/) and [react-jsx-parser](https://github.com/TroyAlford/react-jsx-parser) allows to create amazing concepts like [this](https://twitter.com/sonnylazuardi/status/1282626069095280642). There is sample code written on react-figma:

```jsx
import * as React from 'react';
import { Page, View, Text } from 'react-figma';

export const App = () => {
    return (
        <Page name="New page" isCurrent>
            <View>
                <View style={{ width: 200, height: 100, backgroundColor: '#dd55aa' }} />
                <Text style={{ color: '#ffffff' }}>text</Text>
            </View>
        </Page>
    );
};
```

Figma is the most popular design tool for now, but other editors have similar renderers: [react-sketchapp](https://github.com/airbnb/react-sketchapp) for Sketch, [react-xd](https://github.com/macintoshhelper/react-xd) for Adobe XD.

# react-three-fiber

[react-three-fiber](https://github.com/pmndrs/react-three-fiber) is a React renderer for [threejs](https://threejs.org/) on the web and react-native.

[![https://media.giphy.com/media/MwQM6s5nh5L3qbq2Ak/giphy.gif](https://media.giphy.com/media/MwQM6s5nh5L3qbq2Ak/giphy.gif)](https://codesandbox.io/s/rrppl0y8l4?file=/src/App.js)

There is a sample code:

```jsx
import ReactDOM from 'react-dom'
import React, { useRef, useState } from 'react'
import { Canvas, useFrame } from 'react-three-fiber'

function Box(props) {
  // This reference will give us direct access to the mesh
  const mesh = useRef()

  // Set up state for the hovered and active state
  const [hovered, setHover] = useState(false)
  const [active, setActive] = useState(false)

  // Rotate mesh every frame, this is outside of React without overhead
  useFrame(() => (mesh.current.rotation.x = mesh.current.rotation.y += 0.01))

  return (
    <mesh
      {...props}
      ref={mesh}
      scale={active ? [1.5, 1.5, 1.5] : [1, 1, 1]}
      onClick={(e) => setActive(!active)}
      onPointerOver={(e) => setHover(true)}
      onPointerOut={(e) => setHover(false)}>
      <boxBufferGeometry args={[1, 1, 1]} />
      <meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
    </mesh>
  )
}

ReactDOM.render(
  <Canvas>
    <ambientLight />
    <pointLight position={[10, 10, 10]} />
    <Box position={[-1.2, 0, 0]} />
    <Box position={[1.2, 0, 0]} />
  </Canvas>,
  document.getElementById('root')
)
```

Building dynamic scene graphs declaratively with re-usable components makes dealing with threejs easier and brings order and sanity to your codebase. These components react to state changes, are interactive out of the box, and can tap into React’s infinite ecosystem.

The library has an amazing ecosystem with packages such as [react-three-flex](https://github.com/pmndrs/react-three-flex) - it’s a flexbox implementation, [react-xr](https://github.com/pmndrs/react-xr), [react-postprocessing](https://github.com/pmndrs/react-postprocessing) and many others.

# react-nil

[react-nil](https://github.com/pmndrs/react-nil) is a custom react renderer that renders nothing.

```jsx
import React, { useState, useEffect } from "react"
import { render } from "react-nil"

function Foo() {
  const [active, set] = useState(false)
  useEffect(() => void setInterval(() => set((a) => !a), 1000), [])
  console.log(active)

  // This is a logical component without a view, it renders nothing,
  // but it has a real lifecycle and is managed by React regardless.
  return null
}

render(<Foo />)
```
This package allows you to bring Reacts high-level component abstraction to Node, or wherever you need it. Why not manage your REST endpoints like routes on the client, users as components with mount/unmount lifecycles, self-contained separation of concern, and clean side-effects. Suspense for requests, etc.

# react-docx

[react-docx](https://github.com/Jeday/react-docx) is a brand new React reconciler for DOCX.js. A sample code:

```jsx
renderAsyncDocument(
  <section>
    <paragraph heading={Docx.HeadingLevel.HEADING_1}>
      You can pass props as if you are passing them to constructor
    </paragraph>
    <p>There are some helpful shortcuts for often used tags, like this</p>
    <p>
      <t>this one is for TextRun</t>
    </p>
    <p>
      <img
        src="base64 string or buffer object works"
        width={200}
        height={200}
      />
      <href
        src="http://localhost:8080"
        label={"For images and links shortcuts object are provided"}
      />
      This allows for removal of boilerplate for often used objects. In future
      more such object will be implemented.
    </p>
    <Component text="You can use componets of course, just like in react!">
      <t>A child</t>
    </Component>
  </section>
).then((document) => console.log("This is rendered docx document", document));
```

Also, [react-pdf](https://github.com/diegomura/react-pdf) and [redocx](https://github.com/nitin42/redocx) can be used for equal needs.

# Conclusion

Hope you get inspired for creating your own React renderer, it’s possible due to [React Reconciler package](https://github.com/facebook/react/tree/master/packages/react-reconciler). I didn’t mention the most popular renderers such as [react-dom](https://github.com/facebook/react/tree/master/packages/react-dom) or [react-native](https://reactnative.dev/), but I tried to collect the most unusual of them. Are you have any additions? Propose them on the comments! 🙌

# Thanks

- Yaroslav Losev [@losyear](https://github.com/LosYear) - fact checking, editing

# Links

- [Awesome React Renderer list](https://github.com/chentsulin/awesome-react-renderer)

### Rendrers:

- [Ink](https://github.com/vadimdemedes/ink)
- [React Hardware](https://github.com/iamdustan/react-hardware)
- [React Figma](https://github.com/react-figma/react-figma)
- [react-three-fiber](https://github.com/pmndrs/react-three-fiber)
- [react-nil](https://github.com/pmndrs/react-nil)
- [react-docx](https://github.com/Jeday/react-docx)

### Renderers writing:

- [React Reconciler package](https://github.com/facebook/react/tree/master/packages/react-reconciler)
- [Atul R – Beginners guide to Custom React Renderers](https://blog.atulr.com/react-custom-renderer-1/)
- [Manas Jayanth – Learn how React Reconciler package works by building your own lightweight React DOM](https://hackernoon.com/learn-you-some-custom-react-renderers-aed7164a4199)
- [Sophie Alpert – Building a Custom React Renderer](https://www.youtube.com/watch?v=CGpMlWVcHok)
- [Aziz Khambati – Building an Async React Renderer with Diffing in Web Worker](https://medium.com/@azizhk/building-an-async-react-renderer-with-diffing-in-web-worker-f3be07f16d90)