An Analysis of NativeScript Mobile Platform

Hosted byCharles Lowell, Taras Mankovski, Jeffrey Cherewaty

May 24th, 2019.

In this internal Frontside Podcast episode, Charles, Taras, and Jeffrey analyze the NativeScript Mobile Platform.


Please join us in these conversations! If you or someone you know would be a perfect guest, please get in touch with us at contact@frontside.io. Our goal is to get people thinking on the platform level which includes tooling, internalization, state management, routing, upgrade, and the data layer.

This show was produced by Mandy Moore, aka @therubyrep of DevReps, LLC.

Transcript:

CHARLES: Hello and welcome to The Frontside Podcast, a place where we talk about user interfaces and everything that you need to know to build them right. My name is Charles, a developer here at Frontside. With me today are Taras and Jeffrey.

TARAS: Hello everyone.

CHARLES: Today, we're going to be talking about NativeScript, in particular, and evaluating technologies and frameworks, kind of at the meta level. So, I'm kind of excited about it because we've been pretty heavily involved with NativeScript for the past three months or so. And so, we've gotten to look at it both from beginners' eyes being kind of totally fresh to the platform, but then actually having to start to pump up against some of the edge cases which is what always ends up happening when you actually use a framework for real. Let's get started.

TARAS: All right. I think there's a lot of things that we could talk about because when we would start looking at NativeScript, the length that we were looking at NativeScript through this is that this platform that our client is going to be using for doing development of large applications. So, what does NativeScript need to have to be able to support potentially hundreds of developers building apps? We started looking at it and one things that made us consider NativeScript early on was it kind of provides a platform that allows you to encode in JavaScript and run it on mobile. And we saw this kind of emergence of Angular and Vue.js running on top of NativeScript. So, those things together is kind of exciting.

CHARLES: There was also an implementation in progress of React and there were a couple of spikes of Ember also running on top of NativeScript. So, my first impression was initially very favorable. The onboarding experience is actually pretty nice because it was JavaScript and the application was interpreted, there's the ability to completely and totally dynamically change the application at runtime. So, they have essentially an application called the NativeScript Playground which lets you flash a QR code at it and then it will go in to the URL associated with that QR code and it will download all of the assets for a NativeScript application running at that URL. So, all the JavaScript, all the templates, all the whatever, it'll pull it down, it will actually start running like within that app. So, the Playground app then becomes your actual app that you want to use. There's no App Store, no TestFlight, no Google Play. There's no gatekeeping to delivering your application into a running app. And I thought that was really, really cool and really, really compelling.

TARAS: We should clarify that this is specifically for preview purposes because if you're going to be shipping the application to production, you still need to go through all those things before...

CHARLES: Yes.

TARAS: But the onboarding process, you could just install the preview app and then you can point a QR code and it will open that app, whether it's in Angular or in Vue, that app will open up in the preview app and you have a native app that you could play around with.

CHARLES: Right.

JEFFREY: And that's key both for the engineers who are playing around with this and building this and also really key for the non-engineers who are part of the team to be able to really easily spin up and see what the engineers on the team are working on.

CHARLES: That's exactly why we thought, "Hey, we want to be able to use this mechanism for preview apps." In the same way on the server side, you have preview apps associated with a pull request. When we saw this, what we immediately wanted to do was have a bot post a comment onto a pull request with a QR code, so that anybody could just, boom, test out this app on their phone.

TARAS: We ultimately ended up setting that up but not quite that way because the original idea of being able to have something like danger bot post the QR code to the comments, you can kind of point out with your phone and open the preview app, that didn't actually pan out. Charles tried to implement that. What happened there?

CHARLES: What it actually turned out was that the preview functionality was dependent on a central server, a central NativeScript server. So rather than kind of statically bundling the assets and just saying 'these assets are this URL and just pull them in and bootstrap your NativeScript application that way', it required a lot of extra stuff. So, it required you to be running a Webpack Dev Server that was building your assets and then basically registering and doing some port forwarding with that dev server to a central NativeScript service that was provided by the company that underpins NativeScript. And that connection needed to be hot and live the whole time for that to work.

So, while it was really cool that you could get the QR codes up and running, unfortunately that functionality could not be decoupled from the hot update and the central service. Those central services were kind of hard coded into the tools.

TARAS: Yeah. So we eventually ended up implementing the preview apps that we wanted but we ended up using Appetize.io to essentially -- the process there is you build the app, you upload the app to Appetize and then danger bot embeds a link to a URL where you can open that app and it will essentially stream like it's running somewhere in a simulator for iOS, an emulator for Android and it will stream a video of that and you can interact with it, kind of like a VNC setup.

CHARLES: Yeah.

TARAS: And that actually accomplished the goal. It's just we weren't able to do the way that we thought we were hoping to do it straight off with the preview app mechanism.

CHARLES: It accomplished the goal. And Appetize is an incredible service that lets you preview the apps on pretty much any type of Android device, any type of iOS device, right there inside of a pull request. But what it didn't allow us to do was pop up your actual device, your actual phone and scan a QR code off of the pull request and pull down the assets. That would have been amazing. But it doesn't always work out that way. And I don't know if that would work long term anyhow because you can't pull down native libraries over the wire and funk them in. That's a big, big no-no. So, the process does have limitations. But nevertheless, that part was really cool.

TARAS: Yeah. That was kind of the entry point, the onboarding. And then I think one of the things that was kind of, I remember at the time when we were talking about the NativeScript architecture because we were starting to understand more about how it works. The idea itself is really kind of amazing actually because you have this V8 where you can run your JavaScript code and then they're kind of wired together on iOS and Android. They're wired to the native implementation. So when you're interacting with it, I think the thing that's really great about NativeScript is that the runtime environment for JavaScript essentially gives you API access. In JavaScript, you could say, "I want to create a Java view," and there will be a Java view that's rendered in the actual native device. You're using the same -- the APIs that you find on the Android docs or iOS docs, all of those APIs are available to you as JavaScript. So, you [crosstalk] as JavaScript. And it's seamless, right?

CHARLES: Yeah, and it makes it very, very handy. The language is different but the APIs are exactly the same. There is an attempt to make cross-platform components and cross-platform classes that serve the needs on both platforms and then delegate to the platform on which you happen to be running. But those are not mandatory, and the low level APIs are always available to you. An example of this is in iOS, kind of the core foundational object is NSObject. All the controllers, the views, the things, all of them are descended from this object. I can go from object and I can go in from JavaScript and I can just say {let object = new NSObject} and boom! I've got a reference to the actual object and I can pass it around to any other iOS API.

That is really, really powerful that there's nothing off limits. There's nothing at an arm's distance. There's really not much you can't do because all of those things are available to you. There's nothing that's off limits. That means that they can build cross-platform components on top of those APIs. Whereas a sort of system like React Native which does have cross-platform components, that's kind of where the base layer is but you can't crack open the hatch and go down the next level and start mucking around, unless you want to actually start meddling with the React Native source code or recompiling Swift in Java code.

TARAS: For me, I think this architecture is probably my favorite part of NativeScript.

JEFFREY: Mine too.

CHARLES: Yeah, me too.

TARAS: I really like this part. I kind of hope that everything else is as clever as that was.

CHARLES: Because among other things, it allowed us to write a Bluetooth. We were able to implement Bluetooth using nothing but JavaScript. We didn't actually have to go down and do any Swift and do any asynchronous message passing between the iOS libraries and the JavaScript libraries. It's like, "No." We've just got a very simple cross-platform interface that instantiates an implementation for Android and an implementation for iOS, but both of them are like JavaScript. And so, it really is you're doing native development but it's JavaScript all the way down.

TARAS: Yeah. And when you're writing plugins, your plugin is actually JavaScript plugin that is assuming iOS APIs and Android APIs.

CHARLES: Yeah. And if you have to have a native plugin like a CocoaPod or an Android Package, you just install it and you can instantiate it from JavaScript. There's no fuss, no muss, no ceremony. It's just like, "Hey, I want to use the..." what was the one we like to use? The Material-UI floating button which is a CocoaPod. You download it, you link it into your application, and then you just instantiate it from JavaScript.

TARAS: That was really cool. The challenging part was that a lot of that kind of awesomeness, like everything around it wasn't quite as polished. And so, one of the big things is that like around tooling, because one of the things about having grown up in a way like in the Ember community, in a sense, we have a certain expectation of what the level of polish from tooling that we would expect. And it's kind of supported in the way like when you look at how React or React Native tooling is, even Angular tooling, it's very polished. You kind of expect to see what you need to see when you're looking at a CLI input and you don't see anything else. That level of polish. I think part of the changes that they're going through, maybe that's part of the reason but that same level of polish isn't available around the tooling.

CHARLES: There are these fantastic qualities about the platform and it is amazing. We were using Angular and a lot of people are using Vue and things like that and that actually is pretty incredible. And there is nice tooling, there is command line stuff, but we started to run into issues where, for example, it was very clear that we were pretty much, as far as I could tell, one of the very, very few people running a NativeScript project on CircleCI or in a CI environment at all. It had capability for testing, both for acceptance testing and for unit testing, but it required changes to the core framework and the core tools in order to get those tests to work in a CI environment.

JEFFREY: Before we kind of get into the testing story there, some of the issues were around determinism of reliably reproducing your whole NativeScript environment and stack every time because that's such a key feature of doing it. And on a CI server, it's like, "Hey, we need this to load in the same exact packages every time." And so, we ran into challenges there.

TARAS: I think we spent almost two days. There's example projects in different combinations. One thing that was off was that there's a pattern that is applied in a lot of the plugins in NativeScript ecosystem is installing things. So, you run npm install and npm install will generate some files. And so, when we're trying to move it over to a CI, there were files, like there's hooks, like TypeScript hooks that were excluded that you can ignore, but they were necessary to compile the TypeScript. And so, what was happening is when we're running these at CI, the application, we would build the app but the app would crash the moment that you start it. And the reason for that was that the JavaScript files that were transpiled from TypeScript to JavaScript, those JavaScript files were actually never included because they were never transpiled in CI because the hooks directory, like we weren't preserving it between our tasks and so...

CHARLES: Right. We weren't caching. This was an artifact of the install. And so, we were caching the install, so essentially the yarn.lock was not changing. But the directory was not getting generated unless the cache key changed.

TARAS: And we spent spent quite a lot of time...

CHARLES: Two or three days out.

TARAS: Yeah.

CHARLES: What that said is, "Oh, nobody's really running this in CI." Nobody's actually building an app from scratch every time.

TARAS: There are people in NativeScript team that actually does a great job of documenting. They did have example projects that exist but sometimes that example project doesn't fit like a perfect combination of what you're looking for. There was an example project that was showing how to run on CI but it didn't use TypeScript. And so, that's where we lost a lot of time.

CHARLES: Right.

JEFFREY: So, let's talk about testing since that's kind of the core, the most important part of why you even want continuous integration capabilities to begin with. What did we run into there? What did it look like?

TARAS: Well, I think it's safe to say that we were really on a bleeding edge of testing capabilities in NativeScript ecosystem with Angular, at least. But I think it was still an interesting project. We were using the latest builds. And I have to say I think this is one of those things that's going to be kind of consistent through this, is like the people in NativeScript team are amazing. They're so easy to work with. They're so accommodating. When we ask for stuff, they're on it. But it was a lot of things we're trying to figure out like how do we run unit tests, what can we do. Ideally, we wanted to run, first and foremost, we started with how do we run functional testing. So we spent quite a lot of time trying to get Appium set up. I spent a good two to three weeks on that and it was not productively spent time.

CHARLES: I think ultimately, we had to pull back from it. And there were a number of reasons. Part of that is there are multiple paradigms for how you can build your NativeScript application. So as we speak, there's a move towards using Webpack to build all of your JavaScript in your style sheet assets because it's very much like a React Native application. You've got style sheets, you've got JavaScript assets, that some of them might be in TypeScript, some of them you might be using Babel, and you need to actually transpile them down to include them in a way that your underlying JavaScript runtime is going to be able to understand. But that wasn't always so. They have their own build system and packaging system, they kind of used the TypeScript compiler ad-hoc, if you were using TypeScript, which we were. And so, this was kind of this orthogonal complexity, I guess, where you have your unit testing and it has to play nice with this one package or Webpack.

There were multiple ways to package your app. And so, we ran into problems where, like TypeScript kept coming up as a problem and the way in which we were bundling our assets. So, in order to get TypeScript to work, we kind of had to get Webpack running. But the problem is it felt like three quarters of the tooling wasn't Webpack compatible yet. And so, it meant that other pieces of the build were breaking because of this. And so, we had to be on the bleeding edge of several different aspects of the runtime. And the problem is when you're on the bleeding edge, that can break other stuff.

TARAS: But there's complexity in running on native platforms that I think a lot of this complexity is kind of leaking to development experience because one of the challenges is your tests need to run on the native device in the application. So, you have to build the app. You have to push the app into the actual device. So, there's like all the setup of installing the at the app on the device.

CHARLES: You have to launch the simulator.

TARAS: Yeah, right.

CHARLES: To make sure the device is connected.

TARAS: And you run your tests in there. So, that created kind of this situation where we say let's just kind of set Appium aside and just use unit testing which is a very small fraction of the kind of testing that we actually want to do. It will test very little. But let's just do that because getting functional testing to work was really kind of not going anywhere. So once we start doing unit testing, one of the challenges is that it takes like 30 seconds to start your tests. And then, if you for whatever reason, made a mistake, the moment you cancel the build, it leaves, like it doesn't clean up of itself well. So, it leaves processes running in the background. And so now, you spend another like 10 to 15 minutes Googling around for a cookie, "How do you find these processes and stop them?" So, we eventually settled on having a script that does that, but this is the kind of things you have to end up doing because there's a bunch of things that are wired together, but they're not wired together in a way that is seamless. And so, you end up kind of just debugging a lot of stuff where you just want to run some tests but you end up doing all these other stuff.

CHARLES: Right.

TARAS: And you spend a couple of minutes just doing something that you'd expect to happen in like 20 seconds.

CHARLES: Right. There is a feeling that every aspect of the system is coupled to every other aspect of the system in kind of varying ways of interconnectedness. And that's not what you want for a very, very complex system. You want it to be extremely modular.

So, I think we should keep the command line tool. There's probably a separate discussion, I think, about that. But you have to close the book on the Appium and the unit testing. I think the other problem was that you have to run these things on simulators. On macOS, that's not a problem because the simulators ship with X code. And so, you don't actually require an external service. Whereas in CI on Android, it's very unlikely that you're going to have Android emulators on hand because they require a separate virtual machine. Android emulation is actually quite heavy. If you're running through Android Studio or something locally, you essentially need VirtualBox or some equivalent to run your Android simulator because you actually need that simulated hardware. If I understand correctly, that was actually not something that had been really accounted for. It was that you might want to be running simulators not on the same machine as what you were developing on or what the actual that you were building on.

TARAS: Yeah, a lot of the tooling seems to be designed around this idea that you're going to be building and running everything on your machine. And so, you can spin up a virtual machine easily. But in CircleCI, for example, they don't support running a virtual machine inside of a Docker container because for that, you need a feature of a virtualization that is not supported in many CI platforms. You have to run a parallel server if you want to have like Appium running, for example. You need to have a separate server running like an Azure or a Google Cloud somewhere that is able to run virtualized servers that have a host machine that's being guest systems that are running the actual Android emulators of different versions. And so, when I started doing research in this, there are companies that are doing this really well but it's not unusual to be using hardware from Amazon that costs thousands and thousands of dollars per month.

I think for anyone who's getting into mobile development, I would say the hidden gem of Android world is Genymotion. Those that do a lot of Android development, they know about it. But Genymotion has both like a desktop environment and it has SaaS offering that they're in the process of releasing. And so, what it allows you to do is when you run it locally or on your local machine, it allows you to create a virtual machine that is running in VirtualBox and then it allows you to run kind of optimized environment for running Android. And when you do that, it's really fast. It's very smooth. It makes running Android devices locally as easy as it is to run iOS devices on macOS.

CHARLES: I remember starting out and trying to actually just get any Android emulator running on my Mac and I couldn't even do it.

JEFFREY: It was such a huge time saver.

CHARLES: Yeah.

TARAS: And to have this Saas offering is really great because you could basically create your virtual machines on demand and then you install into a virtual machine from your CI server and then you run your tests there. That's kind of the key that I found to be able to run tests and automate it against emulated devices for Android. Genymotion is really great.

CHARLES: Yeah. Again that's the kind of thing that you need when you're in CI. And so, one of the things, I think, one of our discoveries is that there just isn't -- when we started working on this and we haven't seen a culture of running these tools in the cloud and accounting for the fact that you might have not all of the tools running on the same machine.

From, I would say, the beginning, I remember the kind of the diagnostics command didn't work but we were running it on a CI server. So, there's a diagnostics command that you run to see do you have this, do you have that, do you have that. It would work and give meaningful results when I wanted to debug my CI server because when we were initially getting set up, something wasn't building right, there was some dependency missing. And I just wanted a diagnosis but it was trying to install all those tools for me. And I was like, "No, no, no. I don't want you to do anything. I don't want to install them. I'm going to be doing all of that as part of the setup of the CI environment. It's going to be installed, it's going to be cached. I don't want you to just try and like massage my system into a suitable state for NativeScript development. I just want you to diagnose what is wrong. Tell me, am I missing this compiler? Maybe I've got the wrong version of Android SDK. Tell me what's going on." And I couldn't get that to work. That was very frustrating. I think it was because the kind of bulk of the assumptions was that it was going to be individual developers working on their own laptops or their own desktop computers to build, to test, to distribute these applications. I think that's becoming less and less the case. I mean, at this point, that's not a way that we're willing to operate.

TARAS: And we eventually figured out how to do all this stuff, right?

CHARLES: Yeah, we have.

JEFFREY: We have.

TARAS: We have the entire process working but it took a lot longer than one would imagine. It took all the time that we had allocated to it which we thought was very generous amount of time but it took like almost a month to get everything set up. The great part of this is that we do have now everything working. And so, there's a repo where people could take a look if they want to get all stuff working on CI, but it took quite a bit of work in figuring out.

CHARLES: Yeah. Actually, I think worth probably a Screencast to show some of those capabilities because it is really exciting. I mean, when you actually think about the pipeline in its entirety. But we never were able to get functional testing working.

TARAS: And then the challenge here is that because we were essentially looking at NativeScript, going back to this question like, "What do we need to be able to have like hundreds of developers potentially running on this platform?" And so there's a lot of considerations and this tool is just one of them. I think the other one that is a big one is like what are the capabilities of the view layer because that's where most of developers were spending most of their time. We got stuck a little bit about that because I spent a lot of time working in the view layer. The thing that was really great and the thing that I really liked about it is the fact that you have a collection of components that you can use in Angular. You render it as component and then that component is going to look correctly on iOS and is going to look correctly on Android. From a single code base, it's building appropriate components for iOS and Android. What I think is really confusing in that case, though, is because the Android and iOS components don't have parity in a sense. They don't behave exactly the same. And there is also a kind of a reputation in the NativeScript documentation that Android tends to be slower, much slower than iOS. And so, when you start to run into performance problems and you start to run into those pretty fast because it is not really clear what is necessary to not optimize NativeScript, when you start to run into performance problems, it's not really clear like where is it coming from. Right now, the profiling that they have for the UI is very limited. They're kind of in the process of migrating over to chrome.debugger, but profiling in chrome.debugger is not implemented. You can do performance optimization using Android tooling but that's only going to tell you performance of the Java side, or the iOS side is not going to tell you the performance of the code that's running inside of JavaScript. It's not really clear what is causing the problem. If you don't know what's happening, you kind of write it off as like, "I think it's just Android being slow." In reality, when you actually start to dig deeper, you realize there's things about the Android implementation of the components that are different or the views that are different than iOS. And it's the differences that add up to weird performance problems. That's probably the thing that gave me the most hesitation because one of the things that made me think like if we want to be able to give this to a team of like 50 people, we need to have our own view layer because we cannot rely on components. An example of this would be, they have a list ticker on iOS, it doesn't omit change events when you scroll. If the list is moving, it change events and not omit it. But on Android, every time that a different item shows up on a screen, it changes the selection. And so now, you've got this view that's a meeting on Android as a meeting change events. I made an issue around this and the response was that while there's a workaround that you can have for this, but that's hard. Work around is not a solution.

CHARLES: Right. When you have a leaky abstraction like that.

TARAS: Part of the problem is because people use leak abstraction. And so, what's happened in Native -- we actually got on the call with NativeScript core team and they're excellent in really being very helpful, understanding what the problems are, and providing pass on making things better. But what's happened as a result of having this leaky abstraction is that people are relying on the leak. And so now, the leak is the API. And so, we can't change that.

JEFFREY: Right.

CHARLES: And the answer that you really need there is, "We can't change that without breaking stuff. Here's our migration path for deprecating this and introducing a new API." And that gets more into the process stuff and it seems like the process for making changes to the underlying API, I think, could use a little love in the sense that it's kind of opaque as to where the platform is going. There's not a concept of like an [RSC], there's no roadmap about what to expect. What is this API going to look like in the future? Is this stable? If I were writing a software and someone said, "Hey, there's this leaky abstraction," I think my reaction would be, "We've got to fix this." And we also have to acknowledge that there are users who may depend on this. And so, we have to be very deliberate about it.

TARAS: The challenge with this too is that NativeScript kind of outgrew its hands because I think originally, it wasn't meant to be hosting Angular and hosting Vue. Vue didn't exist. Angular didn't exist when NativeScript started. So I think what's happened is that these views that were available, I wouldn't call them components because they don't act like components, but they're exposed in Angular like components but the API feel like Vue objects. So these Vue objects that you consume, that you render in Angular, for example, or in Vue.js, they are the same APIs that NativeScript had before Angular and Vue.js.

CHARLES: Right. You know what? It feels like there's a MVC framework, like a Circa 2010, 2012 MVC framework that has now become the foundational layer for Vue frameworks that have had significant advances in the way we conceive of model in Vue and how data is generated and passed around and how views are rendered off of the data and how reactivity is changed. But there's still, the underlying platform has not evolved. And in fact, this was originally user-facing APIs and now these APIs have become foundational for other user-facing APIs but haven't had the iteration and evolution to make them robust.

TARAS: And flexible enough. As a result, you have the situation where not only is it really super easy to deoptimize the views simply because the requirements of keeping performance expectations are not obvious. One of the things that I found is that the list which is, lists are like 50% of most applications. Before I go into the problem with list, the nice thing about lists in NativeScript is that because they're interacting directly with native APIs, you have really fast list when they're optimized. They're really easy to work with. But they easily get deoptimized by the fact that the expectation to keep the list fast, you have to use this API in NativeScript called array observable and observable. And this is not to be confused with like...

CHARLES: [Inaudible] observables?

TARAS: Yeah.

CHARLES: It's not to be confused, but in fact, every conversation involves a lot of confusion. Because we were using observables, right?

TARAS: And we were actually using observables. So, we're using observable [inaudible] and we're using this array observables and object observables. And so, it's necessary for NativeScript to, essentially what it expects for list to be fast, is it expects that it's going to receive an array observable which is an object that wraps an array because it needs to know when an order or length of data rate changes. So what happens when you pass an array observable, a NativeScript array observable into a list? It will listen for change events on that object. But if you want to change the value of each of the items, like if you want to change a property on the object and have your view remain optimized, the array observable has to have an observable object which allows NativeScript ListView to listen for changes, property changes on the object. You pass this array observable which contains observables that ListView listens for changes on to make sure that it knows how to correctly apply this change to the list. If you don't have this magic, like if you haven't figured out this recipe for ListView performance success, you're going to have a really hard time because it's really not clear at what point and how this thing got deoptimized, why has it just gotten slower.

CHARLES: There's a lot of iteration that needs to happen there and it's not clear what the plan, what the priority, or even how you will even begin to go about this. Because I think that the internal working is that it seems basically to be controlled by one company. I don't recall seeing any contribution from anybody except for Progress which is Progress Incorporated is the company that's kind of the controlling interest, the original company that developed it.

TARAS: The way this showed itself very practically is that to make changes too -- so they have a ListView which comes with NativeScript public and there's RadListView which is the component that has a lot of stuff on it. Like if you want to pull to refresh or if you want to do like laser loading a data or if you want to do a filtering, you want to do -- so most people use RadListView. But RadListView, you can install, so there's no limitation when you build to install it, and your node modules has the source code for that. But the source code, the original TypeScript code, untranspiled code is not publicly available. They have a process for doing this and it's very nice that everybody's very kind and very accommodating. You send an email, they'll give you access to this repo and then you'll have the ability to contribute. NativeScript core team is very helpful and they're open to contributions. There are changes that need to be done to the Angular implementation to make it faster without having to put the requirements of the observable thing, and so they can give you a path to make that stuff happen but it's not open source in the sense that it's not a traditional open source that we would kind of expect. So, there's all kinds of hoops that you need to jump through and the source code is very difficult to read because it's transpiled from TypeScript to JavaScript.

CHARLES: And there was a certain level of opacity in terms of process. For example, I filed an issue which was actually a blocker. For us, it was actually causing our Android build not to work. I didn't hear anything about it. And then, all of a sudden like four days later, a fix came through referencing another repository on which this thing depended with. There was not a lot of context service. So it was obviously referencing a bunch of context that probably happened between two people in a face-to-face conversation. But I couldn't really tell what was going on, why it was an issue, because there was no comment. It was just a pull request that was referencing this issue. I never got a notification. I actually had to go and be like, "Hey, I really would like for this issue to be solved. I wonder if I..." I was actually going to post a, "Hey, is there any progress on this?" Or, "Is there any way that I can help? What can I do to get this looked at?" And I saw that there was another pull request that had referenced my issue. And it was merged and I looked down, but then there was no indication of when this would be available for public release, how I might be able to work around it. And so, the strange loop that didn't get connected was, "Hey, you've got a user who files an issue. You actually use this as the impetus to fix the issue and make a release." But then that whole process was completely invisible to me.

TARAS: You know what? It sounds like you wanted for it to work [inaudible] but you got a pulling mechanism.

CHARLES: Yeah, exactly. Well, I wanted someone to say like, "Hey, here's what's going on, and we're looking right into it." Or, "We're going to look into it in like two months," or, "We can't address this now. But here's a workaround for it." Or, "I don't have a workaround." That's just kind of the expectation that you have when you're playing with open source. In many ways, it does not feel like an open source project.

TARAS: Let's just do a quick note about Saas. Jeffrey, what did you find about the styling of NativeScript views?

JEFFREY: All the components that come kind of shipped as part of the NativeScript core set of components all have styles attached to them. They have CSS attached to them. And as part of the standard data script workflow, with your build toy, you have SaaS available which is very nice. But actually on a recent project, we're not using Saas at all. We're simply using post-CSS and we were able to kick out some CSS variables that turned out to be really nice for theming. So as kind of a future friendly experiment, we were trying to have a light theme and a dark theme since that is very recently now a core part of Android and very likely will be part of iOS this year, where there's kind of a light theme and a dark theme for everything. We were trying to do that. The simplest way to do that with standard web tools is with CSS variables. You can have the flexibility, you have the theming with those. It's so nice. You just, "Hey, my primary color is this color in one scenario and it's this color in another." And we just didn't really have the flexibility to do that with SaaS by itself. And so, that's kind of a limitation of the tooling right now that I hope in the future, we'll have some more sophisticated CSS tools. And really, NativeScript's move toward Webpack and having that as a primary part of the workflow really opens up that possibility that I hope somebody runs with in the near future.

TARAS: Yes, let's bring it all back together.

CHARLES: Can we pause for a moment? Because I actually do think it's important that we at least touch on the command line. I can give a little bit of a kind rant in here but I think that's actually something really important that we have to talk specifically about that.

The other thing that I wanted to touch on very briefly as we kind of draw to the close is the command line tooling, in particular in NativeScript. I think that this is probably one of the weakest points of the platform. And again, I don't want to disparage anybody working on NativeScript. It's an extraordinarily complex problem. This is a command line tool that needs to manage launching simulators, installing things into simulators, pushing code to those simulators. It needs to handle hot updates to things that it's running on, devices and simulators. So, it needs to be building JavaScript assets either with Babel or with TypeScript. It needs to be building those SaaS assets that you were just talking about, image assets. But it needs to be doing all of this for two platforms, so it needs to be managing everything that I just described. It needs to be managing on iOS. Everything that I've just described needs to be managed on Android, as well. It needs to work for a single developer's desktop. It also needs to work with all of those components that I just described distributed out in the Cloud. So, we're talking about an extraordinarily complex piece of software. And I think that unfortunately, the NativeScript CLI does not inspire confidence because it can do all of those tasks.

But Taras, you also mentioned often if you stop the process midway, it will leave a thousand things open and they're just spewing output to your console. The console output, unfortunately, means there's a big noise to signal ratio because it puts out all of the content for Webpack. Every little thing that it's doing with any of the devices, it's logging to the console. So, it doesn't give you a sense of control. So, what you really are looking for in terms of a command line is, "Hey, I've got this incredible sprawl of complexity and I want to feel like I'm on top of it." And unfortunately, by leaving these things open and having so much console output and having the console output not be formatted well, there's all kinds of colors. Every single tool that you're using whether it's Webpack or whether it's Karma or whether it's just console outputs that you are happing inside of your NativeScript application, the brand of those tools comes through. Webpack is a great example. Its console output feels very Webpack. So when you've got Webpack content randomly interleaved with your console content from your Mocha content, from Karma, all of these competing brands, it doesn't feel like a cohesive developer experience. And so, I really, really hope that -- so, to the point being where I felt like I could not live with that command line tool without rewriting it myself. If we want to use this platform long term, we'd have to either have an alternative command line tool or really, really, really help the NativeScript team completely and totally rewrite the command line experience.

TARAS: I would love to work on fixing a lot of these parts about NativeScript if there was a way to actually do it in terms of like, if they wanted to pay us to help them kind of bring some of these things to a state that would match. For example, what's available in Ember or available in React CLI, I would love to do that.

CHARLES: React Native, yeah.

TARAS: Yeah, let's do that work. But who knows what's in store? A lot of awesome platform like the idea around NativeScript architecture is fascinating and it's really, really powerful and really wonderful people doing some, trying to tackle really challenging problems, but it's all glued together in a way that doesn't instill confidence. And it just makes everything feel wobbly, just makes it feel like you never know, is it a problem? Where's the problem from? What is causing this?

CHARLES: Yeah. And if I fix this thing, is it going to break something else?

TARAS: Yeah, we've seen it happen actually with one of the solutions that was introduced to a bug that you were referring to earlier.

CHARLES: Yeah. So that was our three months experience working with NativeScript.

TARAS: We are considering other things now, very seriously looking at Flutter as an alternative for the same client, same scenario. Flutter is looking pretty exciting. There's a lot of things that are really good there. So in three months, we'll do another report and talk about Flutter and what we found. So, that's it.

CHARLES: And I will say I'm actually not like super excited about dart but I'm in dart spot.

JEFFREY: That's a whole other conversation for yet another episode.

CHARLES: I think that, to continue the conversation maybe next week, next time we have kind of an internal podcast, is I would like to really talk about platform evaluation because really you need three months, at least, to get a good idea of this. Is this going to work for the next five years? And most of the time, we give it a week or give it a two week. Or someone comes on who's really excited about this one particular technology and you go off on that tangent. I think there's an interesting meta discussion about how do you select technologies. And we don't have time for that now, obviously. But it's definitely something that I want to have in the future.

TARAS: Sounds good. I think that will be a good conversation for sure.

CHARLES: I guess that is kind of the executive summary on NativeScript from our perspective. With us being three months in, I think, like you said, there's a lot there.

Thank you for listening. If you or someone you know has something to say about building user interfaces that simply must be heard, please get in touch with us. We can be found on Twitter at @TheFrontside or over just plain old email at contact@frontside.io. Thanks and see you next time.

Listen to our podcast:

Listen on Apple Podcasts