What if React Native could be used to build high-fidelity apps AND add more than 11 platforms to its reach?

When I first heard of React Native (RN) back in Fall 2016, the You.i TV Engineering team was beginning the work of providing a Javascript (JS) binding for our You.i Engine SDK by using code generation to create binding code for multiple JS engines.

Having only heard the elevator pitch, I assumed that it was just a UI framework that we could use to sit on top of our JS APIs, but I quickly learned that RN was an entire framework and workflow, rather than just a JS library. It achieves cross-platform support by mapping JS methods to native methods, which I like to call a pass-through approach.

I have a soft spot for JS bindings for C++ APIs. Shipping more than 500 million copies of an SVG player on mobile devices and using multiple scripting engines to bind the SVG DOM API to JS was where it all started for me back in 2003. Naturally, React Native sparked my curiosity and I took some time to dig into the approach.

So here were my initial thoughts about RN.

RN has many benefits, but for me the top three are:

  1. it enables JS for application development without needing a web view,
  2. it removes the performance bottleneck of a web browser by going native, and
  3. it opens the doorway to sharing a percentage of web code written in React.

It was a compelling start and enough to keep me interested. However, there were three limitations that were also striking;

  1. Lowest common denominator apps
    This is a typical challenge for ‘pass-through’ cross-platform approaches. The more platforms that are supported, the more complex it becomes to maintain and find common ground. Since these approaches need to map their abstractions to the native controls, they need to keep up to date as the OSs change and progress. Because of this abstraction, it typically leads to ‘lowest-common-denominator’ apps, or ones that don’t quite leverage all the uniqueness of the native controls but only the common functionality found in each. In my opinion this leads to apps which are generic at best.
  2. Platforms
    Based on the first two challenges it’s likely no surprise that platform reach is somewhat limited. Roku, PS4, Xbox One and Samsung Tizen to name some of the more common ones, are not part of the current supported field. True cross-platform support gets rather tricky given how this abstraction is handled.
  3. UX workflow
    However, one of the biggest and most obvious challenges from my perspective stems from the gap between UX design and software development — especially if the UX design has a lot of nuanced animations. Coming from a world where the UX workflow has designers and developers as equal partners in the app creation process, this was a step backwards from my point of view.

The Test
From the above challenges, it has been made clear to us by our customers and prospects that larger platform reach and compelling, rich apps top the list. Let’s see what adding You.i Engine One as a supported platform on React Native can do on both these fronts.

To start, I looked at the RN code base as well as the UWP port. My excitement grew as a learned more about the codebase and eventually came up with a preliminary architecture.

To me, the key component was the cxxreact library which implements the API bindings from a JS engine to C++. I started with our basic “Empty Sample”, which essentially is an empty C++ app that links in and builds our You.i Engine One, specifically using the OSX build in this case.

I then linked the cxxreact library and began to integrate it with our sample application, which also required adding the dependant libraries like JavaScriptCore and Folly. Next, I needed a RN app and a JS bundle to send to the cxxreact library. I created a new React Native project, and I piggybacked on the Android index.js file and used that to run the packager and provide a way for me to download the JS bundle. Within my sample C++ application, I downloaded the JS bundle and started to hook up key elements of cxxreact to our C++ engine.

Integrating the cxxreact library in this way proved to be very effective. I started to see events and methods being sent to our C++ layer, specifically UI creation methods with constants and settings. As I began to hook these into our engine, I realized we would have to deal with layout. React Native makes use of the flex layout system, based on the easy to understand and open specification from the W3C. Our framework also has a layout system which has some overlap with the flex feature set but also some features which we find allow more control to the designer.

As an example, a critical part of any layout system is not just defining how the components layout relative to one another, but also how they animate. And when I talk about animation, it’s not just self contained animations within the boundaries on a given component, but how they animate and move in relation to each other. A key element of our animation and layout system is the ability for the UX designer to describe what is essentially a deterministic animation but applied to non-deterministic starting and ending — in other words relative rather than absolute attributes such as position. Take the example of animating a card in a list to move a given way when it scrolls into view. This can be defined in our UX workflow, but at runtime it is applied to the UI layer dynamically based on what the layout system has calculated while keeping all the complexities like bezier curves for easing. Knowing that we have solved these problems with our engine — and had things working nicely with layout, I was confident that we would be able to bring this type of workflow to a RN-based framework.

However, for this prototype, I simply disabled our existing layout rules for a container, and used the open source Flex layout library which Facebook provides to generate positioning information. Once complete, I began to see UI components positioned in the correct locations. Next was rounding out other UI components like images and lists by adding to the sample. This lead to hooking up keyboard and mouse events and sending them into the cxxreact engine.

Eventually, I had an app on OSX looking like this screenshot

To me, this was incredible and a clear demonstration of RN supporting You.i Engine as a platform.

Takeaway
What does this mean exactly? It means that our You.i Engine One framework can bring RN to 11+ more platforms, with the performance of a gaming engine. It also means that we could bring our patented design workflow into RN and use it to develop engaging, high-fidelity apps — by eventually giving the ability to augment animations and other visuals in AE.

Up to this point, the proof of concept was only on macOS As far as platforms go, it is easy to develop for and had a pre-compiled binary of the JavaScriptCore library. With our cross-platform approach, at least 90% of the application code is the same regardless of the platform we are on. In this case, we will simply need to compile some of the dependant open source libraries on the platforms we support. But any code implementing React Native on top of our You.i Engine One would be fully cross-platform unlike the React Native implementations for iOS and Android which are almost completely different code bases. After this simple POC, there are many more exciting things to think about. We need to figure out 10-foot focus, native modules, UX preview/workflow support, debugging, and video players. We need to hook up our current JS binding to JSC and allow developers to create modules simply using JS?

Summary
RN is highly accessible and has made great progress when it comes to cross-platform app development. The exploratory work we did demonstrated how we could fill a couple of areas that React Native struggles with — platform reach and a UX workflow — based on our You.i Engine One technology.

The next step? Take the learnings from the POC work and to really dig into a sustainable architecture. Specifically, how would we design an easy to use mechanism for binding our C++ APIs to React Native. Sounds like a topic for our next blog post.


Thanks for reading! If you like what you saw here, make sure to follow You.i TV. We’re building the future of TV and learning a lot along the way.