Announcing the Beta Foundry Release
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!
#
The Discovery AppAlong 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.
#
Overview of New Features#
The Transient Render EngineThe Transient Render engine (TRE) transforms DOM nodes into a ready-to-render
data structure called the Transient Render Tree (TRT), which is made of TNodes
. 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
โ
TNode
thanks to thesnaphot()
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 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:
Learn More
A detailed review of the Transient Render Engine has its dedicated article. You can also learn more about the new data flow in the Architecture article.
#
Custom RenderersThe 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:
Default renderers support onPress
and many more interesting props! See
โTDefaultRendererProps
.
Moreover, you can customize the rendering of children thanks to the TChildrenRenderer
component!
This custom renderer will insert an AdComponent
element after the second and
fourth children of this 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 InternalRenderer
prop or useInternalRenderer
hook.
Learn More
#
Font SelectionCSS 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 systemFonts
.
#
A Revamped List RendererThe versatile new list component gives access to 47 markers
presets
for custom CSS Counter
Styles; supports
list-style-type
CSS property and start
attribute. There is also an experimental RTL feature!
Note that the thai and arabic indic counters have been rendered via @jsamr/counter-style 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.
#
Extensible Internal Image RendererThe new internal image renderer is shipped with object-fit
CSS property support.
Moreover, its building blocks are completely reusable for custom
rendering:
To render the container of the โ
<img>
element.To render the fallback view on error state.
To render the fallback view on loading state.
To render the image on success state..
To get the state of the image resource fetching.
Learn More
#
Composite Rendering ArchitectureThe 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:
is equivalent to this (explicit 3 layers):
Learn More
It also offers the ability to select the root of the document to render, and to inspect the DOM object asynchronously before rendering.
Learn More
#
Massive dumps of squashed bugsAfter 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. 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 thedefaultHTMLElementModels
definition.
Learn More
#
Ready for Production?#
Quality and Stability AssessmentsWith 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) 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 v5Check-out our dedicated guide, and please don't hesitate to ask for help in our discord channel.
#
Final NotesConsulting
I want to thank Maxime Bertonnier, 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,
Inc. for hiring me to build the first iteration of the engine, which was
originally motivated by the lack of whitespace collapsing support.