---
title: Announcing the Beta Foundry Release
author: Jules Sam. Randolph
author_title: Developer of React Native Render HTML v6
author_url: https://github.com/jsamr/
author_image_url: https://avatars.githubusercontent.com/u/3646758?v=4
tags: [foundry, "release notes"]
description: A major rewrite of the hackable, full-featured Open Source HTML rendering solution for React Native.
image: img/foundry-announcement.png
hide_table_of_contents: false
---
import SocialLinks from '@site/src/components/SocialLinks';
import DiscoveryFrame from '@site/src/components/DiscoveryFrame';
import Reference from '@site/src/components/Reference';
import TNodeTransformDisplay from '@site/src/components/TNodeTransformDisplay';
import ListsShowcase from '@site/src/components/ListsShowcase';
import ExpoDiscoveryCard from '@site/src/components/ExpoDiscoveryCard';

After seven months of a long and exciting journey in alpha development and
testing with the community, I am proud to announce the first Foundry (v6) beta
release of React Native Render HTML.

This process has led the
new API to mature, and the introduction of beta stage marks the end of its
instability.
During the beta stage, I will bring fixes to any issue reported by the
community and expect the test coverage to rise above 90%. I also plan to refine
the **Discovery App** and website, including additional sections for best user
experience. Now, let's get to the heart of it!

<!--truncate-->

## The Discovery App

Along with the release comes this new website and the **Discovery App** which
features all the docs of the website with embedded RNRH-rendered snippets. For
this very reason, the Discovery App is recommended for newcomers, or for those
who want **a "live" feeling of the new engine capabilities**. The website is
more suited during development when searching for specific information.
In addition, the Discovery App has a collection of "Playgrounds" to play with
specific components and observe how they respond to style and props changes.

<DiscoveryFrame scale={0.95} />

<ExpoDiscoveryCard />

## Overview of New Features

### The Transient Render Engine

The Transient Render engine (TRE) transforms DOM nodes into a ready-to-render
data structure called the Transient Render Tree (TRT), which is made of <Reference type="api-def" name="TNodes" url="/react-native-render-html/api/tnode" />. It allows features such as **whitespace collapsing**, **hoisting**,
**CSS inheritance** and more.

A legitimate concerns is whether it adds any overhead. The short answer is
*no*, if we compare it to the legacy engine which had its own transient render
structure. Moreover, this TRT construction process is benchmarked to safeguard
its speed. In addition to the enumerated features, the new transient data
structure offers obvious advantages for library consumers:

- It is totally transparent and predictable; you can create snapshots of a
&ZeroWidthSpace;<Reference type="api-def" name="TNode" url="/react-native-render-html/api/tnode" /> thanks to the <Reference type="api-def" name="TNodeShape" member="snaphot()"
url="/react-native-render-html/api/tnodeshape#snapshot" /> method for an
intuitive understanding of the engine internals. This feature is extremely
handy for debugging and testing!
- It's hackable by allowing to define custom **content models** for tags. Say
hi to inline images!
- It is shipped with a CSS processor which enforces strict translation rules
from CSS to React Native styles. Say goodbye to native crashes caused by
unsupported CSS properties! See the [**dedicated
article**](/react-native-render-html/docs/flow/css-processing) for 
reference.
- It paves the way to server side (or build-time) pre-rendering in the future,
and, why not, a react fiber and MDX builder.

Below is an example of HTML transformation into a Transient Render Tree:

<TNodeTransformDisplay title="Translation of HTML markup into a Transient Render Tree" caption="This figure shows how HTML markup translates to a transient render tree structure. The markup for the TRT is JSX and has been produced by the snapshot() method. Notice that whitespace have collapsed!" html="%3Ca%20href%3D%22https%3A%2F%2Fdomain.com%22%3E%0AThis%20is%0A%3Cspan%3Ephrasing%20content%3C%2Fspan%3E%0A%3Cimg%20src%3D%22https%3A%2F%2Fdomain.com%2Flogo.jpg%22%20%2F%3E%0A%20%20%20%20and%20this%20is%20%3Cstrong%3Etoo%3C%2Fstrong%3E.%0A%3C%2Fa%3E" snapshot="%3CTDocument%20tagName%3D%22html%22%3E%0A%20%20%3CTBlock%20tagName%3D%22body%22%3E%0A%20%20%20%20%3CTBlock%20tagName%3D%22a%22%20href%3D%22https%3A%2F%2Fdomain.com%22%3E%0A%20%20%20%20%20%20%3CTPhrasing%20anonymous%3E%0A%20%20%20%20%20%20%20%20%3CTText%20anonymous%20data%3D%22This%20is%20%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CTText%20tagName%3D%22span%22%20data%3D%22phrasing%20content%22%20%2F%3E%0A%20%20%20%20%20%20%3C%2FTPhrasing%3E%0A%20%20%20%20%20%20%3CTBlock%20tagName%3D%22img%22%20src%3D%22https%3A%2F%2Fdomain.com%2Flogo.jpg%22%20%2F%3E%0A%20%20%20%20%20%20%3CTPhrasing%20anonymous%3E%0A%20%20%20%20%20%20%20%20%3CTText%20anonymous%20data%3D%22and%20this%20is%20%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CTText%20tagName%3D%22strong%22%20data%3D%22too%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CTText%20anonymous%20data%3D%22.%22%20%2F%3E%0A%20%20%20%20%20%20%3C%2FTPhrasing%3E%0A%20%20%20%20%3C%2FTBlock%3E%0A%20%20%3C%2FTBlock%3E%0A%3C%2FTDocument%3E" />

:::tip Learn More
A detailed review of the Transient Render Engine has its [**dedicated article**](/react-native-render-html/docs/flow/transient-render-engine).
You can also learn more about the new data flow in the [**Architecture article**](/react-native-render-html/docs/architecture).
:::

### Custom Renderers

The new rendering API is an order of magnitude more powerful than the legacy.
Custom renderers are now plain React Component instead of functions, and you
have now access to the underlying renderer for rich customization:

```jsx title="Foundry Custom Renderer"
import React from 'react';
import { Alert } from 'react-native';

function H1Renderer({
  TDefaultRenderer,
  ...props
}) {
  const onPress = () => Alert.alert('pressed!');
  return (
    <TDefaultRenderer
      {...props}
      onPress={onPress}
    />
  );
}
```
Default renderers support `onPress` and many more interesting props! See 
&ZeroWidthSpace;<Reference type="api-def" name="TDefaultRendererProps" url="/react-native-render-html/api/tdefaultrendererprops" />.
Moreover, you can customize the rendering of children thanks to the <Reference
type="api-def" name="TChildrenRenderer" url="/react-native-render-html/api/tchildrenrenderer" /> component!

```jsx title="Foundry Custom Renderer with Children Tampering"
import React from 'react';
import { TChildrenRenderer } from 'react-native-render-html';
import AdComponent from './AdComponent';

function ArticleWithAds({
  TDefaultRenderer,
  tnode,
  ...defaultRendererProps
}) {
  const firstChildrenChunk = tnode.children.slice(0, 2);
  const secondChildrenChunk = tnode.children.slice(2, 4);
  const thirdChildrenChunk = tnode.children.slice(4);
  return (
    <TDefaultRenderer tnode={tnode} {...defaultRendererProps}>
      <TChildrenRenderer tchildren={firstChildrenChunk} />
      {firstChildrenChunk.length === 2 ? <AdComponent /> : null}
      <TChildrenRenderer tchildren={secondChildrenChunk} />
      {secondChildrenChunk.length === 2 ? <AdComponent /> : null}
      <TChildrenRenderer tchildren={thirdChildrenChunk} />
    </TDefaultRenderer>
  );
}
```
This custom renderer will insert an `AdComponent` element after the second and
fourth children of this <Reference type="api-def" name="TNode" url="/react-native-render-html/api/tnode" />.

Last but not least, custom renderers can reuse internal renderers (those
special renderers displaying lists, images and anchors). For this purpose,
you can use the <Reference type="api-def" name="InternalRenderer" url="/react-native-render-html/api/customrendererprops#internalrenderer" /> prop or <Reference type="api-def" name="useInternalRenderer" url="/react-native-render-html/api/useinternalrenderer" /> hook.

:::tip Learn More
[**Check-out the Custom Rendering guide**](/react-native-render-html/docs/guides/custom-renderers).
:::

### Font Selection

CSS `font-family` property allows a comma-separated list of fonts, while react
Native `fontFamily` does not. Moreover, setting a font that is not available in
the system will often lead to native crashes. To reconcile this inconsistency, the CSS
Processor will try to match each font in a `font-family` property with a list
of supported fonts available in the system by the library consumer. The prop to
declare such fonts is <Reference type="api-def" name="systemFonts"
url="/react-native-render-html/api/renderhtmlprops#systemfonts"/>.

:::tip Learn More
[**Check-out the Font Selection section from the Textual guide**](/react-native-render-html/docs/content/textual#font-selection).
:::

### A Revamped List Renderer

The versatile new list component [gives access to 47 markers
presets](https://github.com/jsamr/react-native-li/tree/master/packages/counter-style#readme)
for custom [CSS Counter
Styles](https://drafts.csswg.org/css-counter-styles-3/); supports 
`list-style-type` CSS property and `start` attribute. There is also an experimental RTL feature!

<ListsShowcase />

Note that the **thai** and **arabic indic** counters have been rendered via
[@jsamr/counter-style](https://github.com/jsamr/react-native-li/tree/master/packages/counter-style#readme)
presets, and the **russian** counter has been rendered with a custom, 2
lines-of-code counter renderer. Learn more about this fancy feature and examples [**in the dedicated
article**](/react-native-render-html/docs/content/lists).

### Extensible Internal Image Renderer

The new internal image renderer is shipped with `object-fit` CSS property support.
Moreover, **its building blocks are completely reusable for custom
rendering**:

<dl>

<dt>

&ZeroWidthSpace;<Reference library="react-native-render-html" name="IMGElementContainer" url="/react-native-render-html/api/imgelementcontainer" member={undefined} full={false} type="api-def" plural={undefined} />

</dt><dd>

To render the container of the &ZeroWidthSpace;<Reference full={false} name="&lt;img&gt;" url="https://mdn.io/img" type="html-el" /> element.

</dd><dt>

&ZeroWidthSpace;<Reference library="react-native-render-html" name="IMGElementContentError" url="/react-native-render-html/api/imgelementcontenterror" member={undefined} full={false} type="api-def" plural={undefined} />

</dt><dd>

To render the fallback view on error state.

</dd><dt>

&ZeroWidthSpace;<Reference library="react-native-render-html" name="IMGElementContentLoading" url="/react-native-render-html/api/imgelementcontentloading" member={undefined} full={false} type="api-def" plural={undefined} />

</dt><dd>

To render the fallback view on loading state.

</dd><dt>

&ZeroWidthSpace;<Reference library="react-native-render-html" name="IMGElementContentSuccess" url="/react-native-render-html/api/imgelementcontentsuccess" member={undefined} full={false} type="api-def" plural={undefined} />

</dt><dd>

To render the image on success state..

</dd><dt>

&ZeroWidthSpace;<Reference library="react-native-render-html" name="useIMGElementState" url="/react-native-render-html/api/useimgelementstate" member={undefined} full={false} type="api-def" plural={undefined} />

</dt><dd>

To get the state of the image resource fetching.

</dd>

</dl>


:::tip Learn More
[**Check-out the Images article**](/react-native-render-html/docs/content/images).
:::

### Composite Rendering Architecture

The three-layer rendering architecture shows its potential when rendering many HTML
snippets at a time. It basically means that you can put configuration in a
context to avoid the cost of instantiating the TRE too many times:

```jsx 
<RenderHTML source={{ html }} />
```

is equivalent to this (**explicit 3 layers**):

```jsx 
<TRenderEngineProvider>
  <RenderHTMLConfigProvider>
    <RenderHTMLSource source={{ html }} />
  </RenderHTMLConfigProvider>
</TRenderEngineProvider>
```

:::tip Learn More
[**Check-out the rendering article**](/react-native-render-html/docs/flow/rendering).
:::

It also offers the ability to select the root of the document to render, and to
inspect the DOM object asynchronously before rendering.

:::tip Learn More
[**Check-out the DOM Tampering guide**](/react-native-render-html/docs/guides/dom-tampering)
:::

## Massive dumps of squashed bugs

After merging the Foundry PR to master, **73% of open issues have been
closed**. Most fixes stem from the efficiency and rigor of the new test-driven
CSS processor and Transient Render Engine. Most notable areas of fixes:

- **Unrecognized styles** crashing the app. The new CSS processor is strict and
deterministic in what is translatable to React Native styles and what is not.
- **Missing inheritable styles**. Styles inheritance and specificity are
implemented and battle-tested in the TRE.
- **List prefixes styles** not inheriting from parent styles (color...). The
new list internal renderer takes them all.
- **Missing HTML tags support**. The TRE now has explicit support for all the
tags specified in the [HTML5 WHATWG living
standard](https://html.spec.whatwg.org/). However, not all tags will be
rendered. Tags with a **content model** set to `none` will not be rendered (you
can override this model though). Check-out the list of all tags and their
models in the <Reference type="api-doc" name="defaultHTMLElementModels" url="/react-native-render-html/api/defaulthtmlelementmodels/" /> definition.

:::tip Learn More
[Check-out the release notes for more details](https://github.com/meliorence/react-native-render-html/releases/tag/v6.0.0-beta.0).
:::

## Ready for Production?

### Quality and Stability Assessments

With all the bug fixes, high test coverage and API stability, entering the
beta stage means **the Foundry release is now ready for production**. Test coverage for
the CSS processor and TRE is **100%** (see
[native-html/core](https://github.com/native-html/core)) repository. The
`react-native-render-html` package has a test coverage above **64%**, and will
rise to above **90%** by the end of the beta stage.

### Migrating from v4 and v5

[**Check-out our dedicated
guide**](/react-native-render-html/docs/migration-guide), and please don't
hesitate to ask for help in [**our discord channel**](https://discord.gg/dbEMMJM).

## Final Notes

:::note Consulting
I am available for consulting, to help you incorporate this
library in your project or migrate from legacy versions. Contact me via
[email](https://github.com/jsamr) or
[LinkedIn](https://www.linkedin.com/in/js-randolph/).
:::

I want to thank [Maxime Bertonnier](https://github.com/Exilz), the original
first contributor of `react-native-render-html` for letting me join the team
and take over this awesome project. I want to also thank all those amazing
alpha-testers from the community who have helped me refine the API over the
last 7 months. And finally, kudos to [Expensify](https://use.expensify.com/),
Inc. for hiring me to build the first iteration of the engine, which was
originally motivated by the lack of whitespace collapsing support.

<SocialLinks twitterUrl="https://twitter.com/jsamrn/status/1402322299395756032" redditUrl="https://www.reddit.com/r/reactjs/comments/nva0dk/announcing_the_beta_foundry_release_of_react/" />