What is the iOS Runtime and how does it operate?

The runtimes are the native bridges that connect the "native" and the "JavaScript" world. There is one for Android and one for iOS, and these two runtimes are the core of the framework enabling many of the unique features in NativeScript. Since the runtimes are responsible for evaluating the JavaScript that we write in our apps - naturally they need an embedded engine to handle this responsibility. For all kinds of legacy reasons those two runtimes are using different JavaScript engines - V8 for the Android runtime and JavaScriptCore for the iOS runtime. More about how all of this operates can be found in the documentation.

Why do we need to change it?

Maintaining two runtimes with two different JavaScript engines brings several challenges:

It requires a massive effort to keep up with maintenance. Especially if the JavaScript engine is not designed embedded-friendly like JavaScriptCore - there might be heavy customizations involved which makes the upgrades a non-trivial job.

Having feature parity is also not something that comes out of the box - in some cases it's even impossible. This is the case with the snapshots that NativeScript supports for Android and can boost your start up time. This feature comes from V8 and doesn't have an equivalent in JavaScriptCore.

Which approach did we choose?

We chose to go with V8 for both platforms for several reasons:

The version of JavaScriptCore we are using has significantly diverged from the main repository in order to be able to support everything that the framework needs. This makes every upgrade not only challenging as the changes are very often not trivial, but also time-consuming - it can take up to 3 person-months to complete it.

V8 is embedding friendly and now it supports JIT-less mode which makes it possible to be used on iOS.

This allows us to provide Bitcode support down the road, which is a blocker for other exciting features like writing Apple Watch applications in NativeScript.

Several months ago, Darin Dimitrov from the runtimes team started a POC to verify how feasible this would be, and step by step he came to the point where this option became very realistic. As the main driver of this effort, Darin went through extensive collaboration with Google's V8 team who were extremely helpful in this process. Now is the time to say big thanks to Jakob Gruber for all the help along the way.



At this point a big part of our tests are passing with the new runtime and we managed to get some internal applications working with it as well. The performance is similar to the official version, even without providing support for snapshots. With that said, we are extremely excited to share those bits with you as well.

Give it a try!

Testing the new iOS Runtime is really easy. You need a working NativeScript application - you can try it on a brand new blank project or on some of your existing apps (be sure to have a backup!). The only command you need to run is:

tns platform add ios @ alpha - v8

After that, just run the application the usual way:

tns run ios

And you are all set!

Known Limitations

The following features are not implemented, yet and will not work correctly:

Vector types

Safari Inspector and Chrome DevTools are not supported

No armv7 architecture

No logging

Lack of error handling

HMR will work only with real devices

interop.Reference API might not work for more complicated types

Next Steps

First, if you gave it a try - be sure to let us know what do you think! If you find any issues, please report them in the V8 iOS repository and don't forget to mention that you are using the V8 alpha. Since logging is still not enabled, you will need to attach a sample repro of the problem so that we can debug it.

We are looking to release a BETA and more stable version by the end of the year. Your feedback will be essential for addressing the most important issues on time and scope the release accordingly.